示例#1
0
static inline void
vm_method_missing_args(rb_thread_t *th, VALUE *argv,
		       int num, const rb_block_t *blockptr, int opt)
{
    rb_control_frame_t * const reg_cfp = th->cfp;
    MEMCPY(argv, STACK_ADDR_FROM_TOP(num + 1), VALUE, num + 1);
    th->method_missing_reason = opt;
    th->passed_block = blockptr;
    POPN(num + 1);
}
示例#2
0
static inline VALUE
vm_method_missing(rb_thread_t *th, ID id, VALUE recv,
		  int num, rb_block_t *blockptr, int opt)
{
    VALUE val;
    rb_control_frame_t * const reg_cfp = th->cfp;
    VALUE *argv = ALLOCA_N(VALUE, num + 1);
    MEMCPY(argv, STACK_ADDR_FROM_TOP(num + 1), VALUE, num + 1);
    argv[0] = ID2SYM(id);
    th->method_missing_reason = opt;
    th->passed_block = blockptr;
    POPN(num + 1);
    val = rb_funcall2(recv, idMethodMissing, num + 1, argv);
    return val;
}
示例#3
0
static VALUE
vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_num_t flag)
{
    const rb_block_t *block = GET_BLOCK_PTR();
    rb_iseq_t *iseq;
    int argc = (int)num;
    VALUE type = GET_ISEQ()->local_iseq->type;

    if ((type != ISEQ_TYPE_METHOD && type != ISEQ_TYPE_CLASS) || block == 0) {
	rb_vm_localjump_error("no block given (yield)", Qnil, 0);
    }
    iseq = block->iseq;

    argc = caller_setup_args(th, GET_CFP(), flag, argc, 0, 0);

    if (BUILTIN_TYPE(iseq) != T_NODE) {
	int opt_pc;
	const int arg_size = iseq->arg_size;
	VALUE * const rsp = GET_SP() - argc;
	SET_SP(rsp);

	CHECK_STACK_OVERFLOW(GET_CFP(), iseq->stack_max);
	opt_pc = vm_yield_setup_args(th, iseq, argc, rsp, 0,
				     block_proc_is_lambda(block->proc));

	vm_push_frame(th, iseq,
		      VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
		      iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp,
		      iseq->local_size - arg_size);

	return Qundef;
    }
    else {
	VALUE val = vm_yield_with_cfunc(th, block, block->self, argc, STACK_ADDR_FROM_TOP(argc), 0);
	POPN(argc); /* TODO: should put before C/yield? */
	return val;
    }
}