コード例 #1
0
ファイル: proc.c プロジェクト: srirammca53/update_status
VALUE
rb_proc_call(VALUE self, VALUE args)
{
    rb_proc_t *proc;
    GetProcPtr(self, proc);
    return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			     RARRAY_LEN(args), RARRAY_PTR(args), 0);
}
コード例 #2
0
ファイル: vm_insnhelper.c プロジェクト: qnighy/ruby-1.9.2p0
static inline VALUE
vm_call_bmethod(rb_thread_t *th, VALUE recv, int argc, const VALUE *argv,
		const rb_block_t *blockptr, const rb_method_entry_t *me)
{
    rb_proc_t *proc;
    VALUE val;

    /* control block frame */
    th->passed_me = me;

    GetProcPtr(me->def->body.proc, proc);
    val = rb_vm_invoke_proc(th, proc, recv, argc, argv, blockptr);
    return val;
}
コード例 #3
0
static inline VALUE
vm_call_bmethod(rb_thread_t *th, ID id, VALUE procval, VALUE recv,
		VALUE klass, int argc, VALUE *argv, rb_block_t *blockptr)
{
    rb_control_frame_t *cfp = th->cfp;
    rb_proc_t *proc;
    VALUE val;

    /* control block frame */
    (cfp-2)->method_id = id;
    (cfp-2)->method_class = klass;

    GetProcPtr(procval, proc);
    val = rb_vm_invoke_proc(th, proc, recv, argc, argv, blockptr);
    return val;
}
コード例 #4
0
ファイル: proc.c プロジェクト: srirammca53/update_status
VALUE
rb_proc_call_with_block(VALUE self, int argc, VALUE *argv, VALUE pass_procval)
{
    rb_proc_t *proc;
    rb_block_t *block = 0;
    GetProcPtr(self, proc);

    if (!NIL_P(pass_procval)) {
	rb_proc_t *pass_proc;
	GetProcPtr(pass_procval, pass_proc);
	block = &pass_proc->block;
    }

    return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			     argc, argv, block);
}
コード例 #5
0
static inline VALUE
vm_call_bmethod(rb_thread_t *th, VALUE recv, int argc, const VALUE *argv,
		const rb_block_t *blockptr, const rb_method_entry_t *me)
{
    rb_proc_t *proc;
    VALUE val;

    EXEC_EVENT_HOOK(th, RUBY_EVENT_CALL, recv, me->called_id, me->klass);

    /* control block frame */
    th->passed_me = me;
    GetProcPtr(me->def->body.proc, proc);
    val = rb_vm_invoke_proc(th, proc, recv, argc, argv, blockptr);

    EXEC_EVENT_HOOK(th, RUBY_EVENT_RETURN, recv, me->called_id, me->klass);

    return val;
}
コード例 #6
0
ファイル: cont.c プロジェクト: srirammca53/update_status
void
rb_fiber_start(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_fiber_t *fib;
    rb_context_t *cont;
    rb_proc_t *proc;
    int state;

    GetFiberPtr(th->fiber, fib);
    cont = &fib->cont;

    TH_PUSH_TAG(th);
    if ((state = EXEC_TAG()) == 0) {
	int argc;
	VALUE *argv, args;
	GetProcPtr(cont->saved_thread.first_proc, proc);
	args = cont->value;
	argv = (argc = cont->argc) > 1 ? RARRAY_PTR(args) : &args;
	cont->value = Qnil;
	th->errinfo = Qnil;
	th->local_lfp = proc->block.lfp;
	th->local_svar = Qnil;

	fib->status = RUNNING;
	cont->value = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, 0);
    }
    TH_POP_TAG();

    if (state) {
	if (TAG_RAISE) {
	    th->thrown_errinfo = th->errinfo;
	}
	else {
	    th->thrown_errinfo =
	      rb_vm_make_jump_tag_but_local_jump(state, th->errinfo);
	}
	RUBY_VM_SET_INTERRUPT(th);
    }

    rb_fiber_terminate(fib);
    rb_bug("rb_fiber_start: unreachable");
}
コード例 #7
0
ファイル: proc.c プロジェクト: srirammca53/update_status
static VALUE
proc_call(int argc, VALUE *argv, VALUE procval)
{
    rb_proc_t *proc;
    rb_block_t *blockptr = 0;
    rb_iseq_t *iseq;
    GetProcPtr(procval, proc);

    iseq = proc->block.iseq;
    if (BUILTIN_TYPE(iseq) == T_NODE || iseq->arg_block != -1) {
	if (rb_block_given_p()) {
	    rb_proc_t *proc;
	    VALUE procval;
	    procval = rb_block_proc();
	    GetProcPtr(procval, proc);
	    blockptr = &proc->block;
	}
    }

    return rb_vm_invoke_proc(GET_THREAD(), proc, proc->block.self,
			     argc, argv, blockptr);
}
コード例 #8
0
static inline VALUE
vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp,
	       int num, const rb_block_t *blockptr, VALUE flag,
	       ID id, const rb_method_entry_t *me, VALUE recv)
{
    VALUE val;

  start_method_dispatch:

    if (me != 0) {
	if ((me->flag == 0)) {
	  normal_method_dispatch:
	    switch (me->def->type) {
	      case VM_METHOD_TYPE_ISEQ:{
		vm_setup_method(th, cfp, recv, num, blockptr, flag, me);
		return Qundef;
	      }
	      case VM_METHOD_TYPE_NOTIMPLEMENTED:
	      case VM_METHOD_TYPE_CFUNC:{
		val = vm_call_cfunc(th, cfp, num, recv, blockptr, me);
		break;
	      }
	      case VM_METHOD_TYPE_ATTRSET:{
		if (num != 1) {
		    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num);
		}
		val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1));
		cfp->sp -= 2;
		break;
	      }
	      case VM_METHOD_TYPE_IVAR:{
		if (num != 0) {
		    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num);
		}
		val = rb_attr_get(recv, me->def->body.attr.id);
		cfp->sp -= 1;
		break;
	      }
	      case VM_METHOD_TYPE_MISSING:{
		VALUE *argv = ALLOCA_N(VALUE, num+1);
		argv[0] = ID2SYM(me->def->original_id);
		MEMCPY(argv+1, cfp->sp - num, VALUE, num);
		cfp->sp += - num - 1;
		th->passed_block = blockptr;
		val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv);
		break;
	      }
	      case VM_METHOD_TYPE_BMETHOD:{
		VALUE *argv = ALLOCA_N(VALUE, num);
		MEMCPY(argv, cfp->sp - num, VALUE, num);
		cfp->sp += - num - 1;
		val = vm_call_bmethod(th, recv, num, argv, blockptr, me);
		break;
	      }
	      case VM_METHOD_TYPE_ZSUPER:{
		VALUE klass = RCLASS_SUPER(me->klass);
		me = rb_method_entry(klass, id);

		if (me != 0) {
		    goto normal_method_dispatch;
		}
		else {
		    goto start_method_dispatch;
		}
	      }
	      case VM_METHOD_TYPE_OPTIMIZED:{
		switch (me->def->body.optimize_type) {
		  case OPTIMIZED_METHOD_TYPE_SEND: {
		    rb_control_frame_t *reg_cfp = cfp;
		    rb_num_t i = num - 1;
		    VALUE sym;

		    if (num == 0) {
			rb_raise(rb_eArgError, "no method name given");
		    }

		    sym = TOPN(i);
		    id = SYMBOL_P(sym) ? SYM2ID(sym) : rb_to_id(sym);
		    /* shift arguments */
		    if (i > 0) {
			MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i);
		    }
		    me = rb_method_entry(CLASS_OF(recv), id);
		    num -= 1;
		    DEC_SP(1);
		    flag |= VM_CALL_FCALL_BIT | VM_CALL_OPT_SEND_BIT;

		    goto start_method_dispatch;
		  }
		  case OPTIMIZED_METHOD_TYPE_CALL: {
		    rb_proc_t *proc;
		    int argc = num;
		    VALUE *argv = ALLOCA_N(VALUE, num);
		    GetProcPtr(recv, proc);
		    MEMCPY(argv, cfp->sp - num, VALUE, num);
		    cfp->sp -= num + 1;

		    val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr);
		    break;
		  }
		  default:
		    rb_bug("eval_invoke_method: unsupported optimized method type (%d)",
			   me->def->body.optimize_type);
		}
		break;
	      }
	      default:{
		rb_bug("eval_invoke_method: unsupported method type (%d)", me->def->type);
		break;
	      }
	    }
	}
	else {
	    int noex_safe;

	    if (!(flag & VM_CALL_FCALL_BIT) &&
		(me->flag & NOEX_MASK) & NOEX_PRIVATE) {
		int stat = NOEX_PRIVATE;

		if (flag & VM_CALL_VCALL_BIT) {
		    stat |= NOEX_VCALL;
		}
		val = vm_method_missing(th, id, recv, num, blockptr, stat);
	    }
	    else if (!(flag & VM_CALL_OPT_SEND_BIT) && (me->flag & NOEX_MASK) & NOEX_PROTECTED) {
		VALUE defined_class = me->klass;

		if (RB_TYPE_P(defined_class, T_ICLASS)) {
		    defined_class = RBASIC(defined_class)->klass;
		}

		if (!rb_obj_is_kind_of(cfp->self, defined_class)) {
		    val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED);
		}
		else {
		    goto normal_method_dispatch;
		}
	    }
	    else if ((noex_safe = NOEX_SAFE(me->flag)) > th->safe_level &&
		     (noex_safe > 2)) {
		rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id));
	    }
	    else {
		goto normal_method_dispatch;
	    }
	}
    }
    else {
	/* method missing */
	int stat = 0;
	if (flag & VM_CALL_VCALL_BIT) {
	    stat |= NOEX_VCALL;
	}
	if (flag & VM_CALL_SUPER_BIT) {
	    stat |= NOEX_SUPER;
	}
	if (id == idMethodMissing) {
	    VALUE *argv = ALLOCA_N(VALUE, num);
	    vm_method_missing_args(th, argv, num - 1, 0, stat);
	    rb_raise_method_missing(th, num, argv, recv, stat);
	}
	else {
	    val = vm_method_missing(th, id, recv, num, blockptr, stat);
	}
    }

    RUBY_VM_CHECK_INTS();
    return val;
}