fix-ifunc-block.patch

Kazuki Tsujimoto, 06/16/2013 03:33 AM

Download (2.8 KB)

View differences:

include/ruby/ruby.h
1480 1480
#define rb_funcall2 rb_funcallv
1481 1481
#define rb_funcall3 rb_funcallv_public
1482 1482
VALUE rb_funcall_passing_block(VALUE, ID, int, const VALUE*);
1483
VALUE rb_funcall_with_block(VALUE, ID, int, const VALUE*, VALUE);
1483 1484
int rb_scan_args(int, const VALUE*, const char*, ...);
1484 1485
VALUE rb_call_super(int, const VALUE*);
1485 1486

  
string.c
8213 8213
}
8214 8214

  
8215 8215
static VALUE
8216
sym_call(VALUE args, VALUE sym, int argc, VALUE *argv)
8216
sym_call(VALUE args, VALUE sym, int argc, VALUE *argv, VALUE pass_procval)
8217 8217
{
8218 8218
    VALUE obj;
8219 8219

  
......
8221 8221
	rb_raise(rb_eArgError, "no receiver given");
8222 8222
    }
8223 8223
    obj = argv[0];
8224
    return rb_funcall_passing_block(obj, (ID)sym, argc - 1, argv + 1);
8224
    return rb_funcall_with_block(obj, (ID)sym, argc - 1, argv + 1, pass_procval);
8225 8225
}
8226 8226

  
8227 8227
/*
vm_eval.c
830 830
    return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
831 831
}
832 832

  
833
VALUE
834
rb_funcall_with_block(VALUE recv, ID mid, int argc, const VALUE *argv, VALUE pass_procval)
835
{
836
    if (!NIL_P(pass_procval)) {
837
	rb_thread_t *th = GET_THREAD();
838
	rb_block_t *block = 0;
839

  
840
	rb_proc_t *pass_proc;
841
	GetProcPtr(pass_procval, pass_proc);
842
	block = &pass_proc->block;
843

  
844
	th->passed_block = block;
845
    }
846

  
847
    return rb_call(recv, mid, argc, argv, CALL_PUBLIC);
848
}
849

  
833 850
static VALUE
834 851
send_internal(int argc, const VALUE *argv, VALUE recv, call_type scope)
835 852
{
vm_insnhelper.c
2076 2076
    NODE *ifunc = (NODE *) block->iseq;
2077 2077
    VALUE val, arg, blockarg;
2078 2078
    int lambda = block_proc_is_lambda(block->proc);
2079
    rb_control_frame_t *cfp;
2080 2079

  
2081 2080
    if (lambda) {
2082 2081
	arg = rb_ary_new4(argc, argv);
......
2100 2099
	blockarg = Qnil;
2101 2100
    }
2102 2101

  
2103
    cfp = vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
2104
			0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
2105
			th->cfp->sp, 1, 0);
2102
    vm_push_frame(th, (rb_iseq_t *)ifunc, VM_FRAME_MAGIC_IFUNC, self,
2103
		  0, VM_ENVVAL_PREV_EP_PTR(block->ep), 0,
2104
		  th->cfp->sp, 1, 0);
2106 2105

  
2107
    if (blockargptr) {
2108
	VM_CF_LEP(cfp)[0] = VM_ENVVAL_BLOCK_PTR(blockargptr);
2109
    }
2110 2106
    val = (*ifunc->nd_cfnc) (arg, ifunc->nd_tval, argc, argv, blockarg);
2111 2107

  
2112 2108
    th->cfp++;