summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vm.c35
-rw-r--r--vm_core.h1
-rw-r--r--vm_insnhelper.c7
3 files changed, 26 insertions, 17 deletions
diff --git a/vm.c b/vm.c
index 2844441997..24cf5ed97b 100644
--- a/vm.c
+++ b/vm.c
@@ -299,7 +299,9 @@ static void vm_collect_usage_register(int reg, int isset);
#endif
static VALUE vm_make_env_object(const rb_execution_context_t *ec, rb_control_frame_t *cfp);
-extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, VALUE block_handler);
+extern VALUE rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
+ int argc, const VALUE *argv, VALUE block_handler,
+ const rb_callable_method_entry_t *me);
static VALUE vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self, int argc, const VALUE *argv, VALUE block_handler);
static VALUE rb_block_param_proxy;
@@ -1031,18 +1033,22 @@ invoke_bmethod(rb_execution_context_t *ec, const rb_iseq_t *iseq, VALUE self, co
return ret;
}
+ALWAYS_INLINE(static inline VALUE
+ invoke_iseq_block_from_c(rb_execution_context_t *ec, const struct rb_captured_block *captured,
+ VALUE self, int argc, const VALUE *argv, VALUE passed_block_handler,
+ const rb_cref_t *cref, int is_lambda, const rb_callable_method_entry_t *me));
+
static inline VALUE
invoke_iseq_block_from_c(rb_execution_context_t *ec, const struct rb_captured_block *captured,
VALUE self, int argc, const VALUE *argv, VALUE passed_block_handler,
- const rb_cref_t *cref, int is_lambda)
+ const rb_cref_t *cref, int is_lambda, const rb_callable_method_entry_t *me)
{
const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);
int i, opt_pc;
VALUE type = VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0);
rb_control_frame_t *cfp = ec->cfp;
VALUE *sp = cfp->sp;
- const rb_callable_method_entry_t *me = ec->passed_bmethod_me;
- ec->passed_bmethod_me = NULL;
+
stack_check(ec);
CHECK_VM_STACK_OVERFLOW(cfp, argc);
@@ -1076,7 +1082,7 @@ invoke_block_from_c_bh(rb_execution_context_t *ec, VALUE block_handler,
const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(block_handler);
return invoke_iseq_block_from_c(ec, captured, captured->self,
argc, argv, passed_block_handler,
- cref, is_lambda);
+ cref, is_lambda, NULL);
}
case block_handler_type_ifunc:
return vm_yield_with_cfunc(ec, VM_BH_TO_IFUNC_BLOCK(block_handler),
@@ -1139,17 +1145,24 @@ vm_yield_force_blockarg(rb_execution_context_t *ec, VALUE args)
VM_BLOCK_HANDLER_NONE, NULL, FALSE, TRUE);
}
+ALWAYS_INLINE(static inline VALUE
+ invoke_block_from_c_proc(rb_execution_context_t *ec, const rb_proc_t *proc,
+ VALUE self, int argc, const VALUE *argv,
+ VALUE passed_block_handler, int is_lambda,
+ const rb_callable_method_entry_t *me));
+
static inline VALUE
invoke_block_from_c_proc(rb_execution_context_t *ec, const rb_proc_t *proc,
VALUE self, int argc, const VALUE *argv,
- VALUE passed_block_handler, int is_lambda)
+ VALUE passed_block_handler, int is_lambda,
+ const rb_callable_method_entry_t *me)
{
const struct rb_block *block = &proc->block;
again:
switch (vm_block_type(block)) {
case block_type_iseq:
- return invoke_iseq_block_from_c(ec, &block->as.captured, self, argc, argv, passed_block_handler, NULL, is_lambda);
+ 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);
case block_type_symbol:
@@ -1167,14 +1180,14 @@ static VALUE
vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
int argc, const VALUE *argv, VALUE passed_block_handler)
{
- return invoke_block_from_c_proc(ec, proc, self, argc, argv, passed_block_handler, proc->is_lambda);
+ return invoke_block_from_c_proc(ec, proc, self, argc, argv, passed_block_handler, proc->is_lambda, NULL);
}
MJIT_FUNC_EXPORTED VALUE
rb_vm_invoke_bmethod(rb_execution_context_t *ec, rb_proc_t *proc, VALUE self,
- int argc, const VALUE *argv, VALUE block_handler)
+ int argc, const VALUE *argv, VALUE block_handler, const rb_callable_method_entry_t *me)
{
- return invoke_block_from_c_proc(ec, proc, self, argc, argv, block_handler, TRUE);
+ return invoke_block_from_c_proc(ec, proc, self, argc, argv, block_handler, TRUE, me);
}
MJIT_FUNC_EXPORTED VALUE
@@ -1185,7 +1198,7 @@ rb_vm_invoke_proc(rb_execution_context_t *ec, rb_proc_t *proc,
vm_block_handler_verify(passed_block_handler);
if (proc->is_from_method) {
- return rb_vm_invoke_bmethod(ec, proc, self, argc, argv, passed_block_handler);
+ return rb_vm_invoke_bmethod(ec, proc, self, argc, argv, passed_block_handler, NULL);
}
else {
return vm_invoke_proc(ec, proc, self, argc, argv, passed_block_handler);
diff --git a/vm_core.h b/vm_core.h
index af9ec2b8ef..6b094dcbfb 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -858,7 +858,6 @@ typedef struct rb_execution_context_struct {
/* temporary places */
VALUE errinfo;
VALUE passed_block_handler; /* for rb_iterate */
- const rb_callable_method_entry_t *passed_bmethod_me; /* for bmethod */
uint8_t raised_flag; /* only 3 bits needed */
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 9136a4aee4..01f5b9283f 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -1943,9 +1943,8 @@ vm_call_bmethod_body(rb_execution_context_t *ec, struct rb_calling_info *calling
VALUE val;
/* control block frame */
- ec->passed_bmethod_me = cc->me;
GetProcPtr(cc->me->def->body.proc, proc);
- val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->block_handler);
+ val = rb_vm_invoke_bmethod(ec, proc, calling->recv, calling->argc, argv, calling->block_handler, cc->me);
return val;
}
@@ -2517,8 +2516,6 @@ vm_yield_with_cfunc(rb_execution_context_t *ec,
int is_lambda = FALSE; /* TODO */
VALUE val, arg, blockarg;
const struct vm_ifunc *ifunc = captured->code.ifunc;
- const rb_callable_method_entry_t *me = ec->passed_bmethod_me;
- ec->passed_bmethod_me = NULL;
if (is_lambda) {
arg = rb_ary_new4(argc, argv);
@@ -2536,7 +2533,7 @@ vm_yield_with_cfunc(rb_execution_context_t *ec,
VM_FRAME_MAGIC_IFUNC | VM_FRAME_FLAG_CFRAME,
self,
VM_GUARDED_PREV_EP(captured->ep),
- (VALUE)me,
+ Qfalse,
0, ec->cfp->sp, 0, 0);
val = (*ifunc->func)(arg, ifunc->data, argc, argv, blockarg);
rb_vm_pop_frame(ec);