Exemplo n.º 1
0
static void
rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
{
    rb_thread_t *th = trace_arg->th;

    if (trace_arg->event & RUBY_INTERNAL_EVENT_MASK) {
        if (th->trace_arg && (th->trace_arg->event & RUBY_INTERNAL_EVENT_MASK)) {
            /* skip hooks because this thread doing INTERNAL_EVENT */
        }
        else {
            rb_trace_arg_t *prev_trace_arg = th->trace_arg;
            th->trace_arg = trace_arg;
            exec_hooks_unprotected(th, &th->event_hooks, trace_arg);
            exec_hooks_unprotected(th, &th->vm->event_hooks, trace_arg);
            th->trace_arg = prev_trace_arg;
        }
    }
    else {
        if (th->trace_arg == 0 && /* check reentrant */
                trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
            const VALUE errinfo = th->errinfo;
            const int outer_state = th->state;
            int state = 0;
            th->state = 0;
            th->errinfo = Qnil;

            th->vm->trace_running++;
            th->trace_arg = trace_arg;
            {
                /* thread local traces */
                state = exec_hooks_protected(th, &th->event_hooks, trace_arg);
                if (state) goto terminate;

                /* vm global traces */
                state = exec_hooks_protected(th, &th->vm->event_hooks, trace_arg);
                if (state) goto terminate;

                th->errinfo = errinfo;
            }
terminate:
            th->trace_arg = 0;
            th->vm->trace_running--;

            if (state) {
                if (pop_p) {
                    if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
                        th->tag = th->tag->prev;
                    }
                    th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
                }
                TH_JUMP_TAG(th, state);
            }
            th->state = outer_state;
        }
    }
}
Exemplo n.º 2
0
static void
vm_iter_break(rb_thread_t *th)
{
    rb_control_frame_t *cfp = th->cfp;
    VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);

    th->state = TAG_BREAK;
    th->errinfo = (VALUE)NEW_THROW_OBJECT(Qnil, (VALUE)dfp, TAG_BREAK);
    TH_JUMP_TAG(th, TAG_BREAK);
}
Exemplo n.º 3
0
static void
rb_threadptr_exec_event_hooks_orig(rb_trace_arg_t *trace_arg, int pop_p)
{
    rb_thread_t *th = trace_arg->th;
    if (th->trace_arg == 0 &&
	trace_arg->self != rb_mRubyVMFrozenCore /* skip special methods. TODO: remove it. */) {
	const int vm_tracing = th->vm->trace_running;
	const VALUE errinfo = th->errinfo;
	const int outer_state = th->state;
	int state = 0;
	th->state = 0;

	th->vm->trace_running++;
	th->trace_arg = trace_arg;
	{
	    rb_hook_list_t *list;

	    /* thread local traces */
	    list = &th->event_hooks;
	    if (list->events & trace_arg->event) {
		state = exec_hooks(th, list, trace_arg, TRUE);
		if (state) goto terminate;
	    }

	    /* vm global traces */
	    list = &th->vm->event_hooks;
	    if (list->events & trace_arg->event) {
		state = exec_hooks(th, list, trace_arg, !vm_tracing);
		if (state) goto terminate;
	    }
	    th->errinfo = errinfo;
	}
      terminate:
	th->trace_arg = 0;
	th->vm->trace_running--;

	if (state) {
	    if (pop_p) {
		if (VM_FRAME_TYPE_FINISH_P(th->cfp)) {
		    th->tag = th->tag->prev;
		}
		th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
	    }
	    TH_JUMP_TAG(th, state);
	}
	th->state = outer_state;
    }
}
Exemplo n.º 4
0
static inline VALUE
vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp,
	      int num, ID id, ID oid, VALUE recv, VALUE klass,
	      VALUE flag, const NODE *mn, const rb_block_t *blockptr)
{
    VALUE val = 0;
    int state = 0;

    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
    TH_PUSH_TAG(th);
    if (th->event_flags & RUBY_EVENT_C_RETURN) {
	state = TH_EXEC_TAG();
    }
    else {
	_th->tag = _tag.prev;
    }
    if (state == 0) {
	rb_control_frame_t *cfp =
	    vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
			  recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1);

	cfp->method_id = oid;
	cfp->method_class = klass;

	reg_cfp->sp -= num + 1;

	val = call_cfunc(mn->nd_cfnc, recv, mn->nd_argc, num, reg_cfp->sp + 1);

	if (reg_cfp != th->cfp + 1) {
	    rb_bug("cfp consistency error - send");
	}

	vm_pop_frame(th);
    }
    TH_POP_TAG();
    EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
    if (state) TH_JUMP_TAG(th, state);

    return val;
}
Exemplo n.º 5
0
VALUE
rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
	   VALUE (* bl_proc) (ANYARGS), VALUE data2)
{
    int state;
    volatile VALUE retval = Qnil;
    NODE *node = NEW_IFUNC(bl_proc, data2);
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;

    TH_PUSH_TAG(th);
    state = TH_EXEC_TAG();
    if (state == 0) {
      iter_retry:
	{
	    rb_block_t *blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(th->cfp);
	    blockptr->iseq = (void *)node;
	    blockptr->proc = 0;
	    th->passed_block = blockptr;
	}
	retval = (*it_proc) (data1);
    }
    else {
	VALUE err = th->errinfo;
	if (state == TAG_BREAK) {
	    VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
	    VALUE *cdfp = cfp->dfp;

	    if (cdfp == escape_dfp) {
		state = 0;
		th->state = 0;
		th->errinfo = Qnil;
		th->cfp = cfp;
	    }
	    else{
		/* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */
	    }
	}
	else if (state == TAG_RETRY) {
	    VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
	    VALUE *cdfp = cfp->dfp;

	    if (cdfp == escape_dfp) {
		state = 0;
		th->state = 0;
		th->errinfo = Qnil;
		th->cfp = cfp;
		goto iter_retry;
	    }
	}
    }
    TH_POP_TAG();

    switch (state) {
      case 0:
	break;
      default:
	TH_JUMP_TAG(th, state);
    }
    return retval;
}