summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-09 01:02:13 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-09 01:02:13 +0000
commit3cb6952f12335ce0a84d612cdbebbc358c430e81 (patch)
tree301363c26604d05eb4ced3fdc1bb461831ed6fef /vm_insnhelper.c
parente3cfb1f3ca9ab0ef4980e4e3cf983323da9a1846 (diff)
fix passing wrong `passed_bmethod_me`.
* vm_core.h: remove `rb_execution_context_t::passed_bmethod_me` and fix functions to pass the `me` directly. `passed_bmethod_me` was used to make bmethod (methods defined by `defined_method`). `rb_vm_invoke_bmethod` invoke `Proc` with `me` information as method frame (`lambda` frame, actually). If the proc call is not bmethod call, `passed_bmethod_me` should be NULL. However, there is a bug which passes wrong `me` for normal block call. http://ci.rvm.jp/results/trunk-asserts@silicon-docker/1449470 This is because wrong `me` was remained in `passed_bmethod_me` (and used incorrectly it after collected by GC). We need to clear `passed_bmethod_me` just after bmethod call, but clearing is not enough. To solve this issue, I removed `passed_bmethod_me` and pass `me` information as a function parameter of `rb_vm_invoke_bmethod`, `invoke_block_from_c_proc` and `invoke_iseq_block_from_c` in vm.c. * vm.c (invoke_iseq_block_from_c): the number of parameters is too long so that I try to specify `ALWAYS_INLINE`. * vm.c (invoke_block_from_c_proc): ditto. * vm_insnhelper.c (vm_yield_with_cfunc): now there are no pathes to use bmethod here. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65636 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r--vm_insnhelper.c7
1 files changed, 2 insertions, 5 deletions
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);