зеркало из https://github.com/github/ruby.git
There is a path to use bmethod with ifunc.
* vm_insnhelper.c (vm_yield_with_cfunc): use passed me as bmethod. We also need to set `VM_FRAME_FLAG_BMETHOD` if needed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65639 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
7c8b5e8f11
Коммит
191108a6d0
4
vm.c
4
vm.c
|
@ -1087,7 +1087,7 @@ invoke_block_from_c_bh(rb_execution_context_t *ec, VALUE block_handler,
|
|||
case block_handler_type_ifunc:
|
||||
return vm_yield_with_cfunc(ec, VM_BH_TO_IFUNC_BLOCK(block_handler),
|
||||
VM_BH_TO_IFUNC_BLOCK(block_handler)->self,
|
||||
argc, argv, passed_block_handler);
|
||||
argc, argv, passed_block_handler, NULL);
|
||||
case block_handler_type_symbol:
|
||||
return vm_yield_with_symbol(ec, VM_BH_TO_SYMBOL(block_handler),
|
||||
argc, argv, passed_block_handler);
|
||||
|
@ -1164,7 +1164,7 @@ invoke_block_from_c_proc(rb_execution_context_t *ec, const rb_proc_t *proc,
|
|||
case block_type_iseq:
|
||||
return invoke_iseq_block_from_c(ec, &block->as.captured, self, argc, argv, passed_block_handler, NULL, is_lambda, me);
|
||||
case block_type_ifunc:
|
||||
return vm_yield_with_cfunc(ec, &block->as.captured, self, argc, argv, passed_block_handler);
|
||||
return vm_yield_with_cfunc(ec, &block->as.captured, self, argc, argv, passed_block_handler, me);
|
||||
case block_type_symbol:
|
||||
return vm_yield_with_symbol(ec, block->as.symbol, argc, argv, passed_block_handler);
|
||||
case block_type_proc:
|
||||
|
|
|
@ -2511,7 +2511,8 @@ block_proc_is_lambda(const VALUE procval)
|
|||
static VALUE
|
||||
vm_yield_with_cfunc(rb_execution_context_t *ec,
|
||||
const struct rb_captured_block *captured,
|
||||
VALUE self, int argc, const VALUE *argv, VALUE block_handler)
|
||||
VALUE self, int argc, const VALUE *argv, VALUE block_handler,
|
||||
const rb_callable_method_entry_t *me)
|
||||
{
|
||||
int is_lambda = FALSE; /* TODO */
|
||||
VALUE val, arg, blockarg;
|
||||
|
@ -2530,10 +2531,11 @@ vm_yield_with_cfunc(rb_execution_context_t *ec,
|
|||
blockarg = rb_vm_bh_to_procval(ec, block_handler);
|
||||
|
||||
vm_push_frame(ec, (const rb_iseq_t *)captured->code.ifunc,
|
||||
VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME,
|
||||
VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME |
|
||||
(me ? VM_FRAME_FLAG_BMETHOD : 0),
|
||||
self,
|
||||
VM_GUARDED_PREV_EP(captured->ep),
|
||||
Qfalse,
|
||||
(VALUE)me,
|
||||
0, ec->cfp->sp, 0, 0);
|
||||
val = (*ifunc->func)(arg, ifunc->data, argc, argv, blockarg);
|
||||
rb_vm_pop_frame(ec);
|
||||
|
@ -2680,7 +2682,7 @@ vm_invoke_ifunc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
|
|||
int argc;
|
||||
CALLER_SETUP_ARG(ec->cfp, calling, ci);
|
||||
argc = calling->argc;
|
||||
val = vm_yield_with_cfunc(ec, captured, captured->self, argc, STACK_ADDR_FROM_TOP(argc), calling->block_handler);
|
||||
val = vm_yield_with_cfunc(ec, captured, captured->self, argc, STACK_ADDR_FROM_TOP(argc), calling->block_handler, NULL);
|
||||
POPN(argc); /* TODO: should put before C/yield? */
|
||||
return val;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче