diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-01-24 13:52:32 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-01-24 13:52:32 +0000 |
commit | 618445576faa94fcd6d3957ea3fb59f6372b64ba (patch) | |
tree | 36cc450623d3e216e643a3f9acc183537e3e05a2 /vm_insnhelper.c | |
parent | 2979842520060311909874e300ef943cca2d215c (diff) |
* eval.c, vm.c, vm_eval.c, vm_insnhelper.c: fix issues about
return and c-return trace. This issue skips (c-)return event
with global jump such as break or return. This fix make vm invoke
hooks at stack rewind timing. fix [ruby-core:27606] [Bug #2610].
* test/ruby/test_settracefunc.rb: add a test for above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26395 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 42 |
1 files changed, 14 insertions, 28 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 8f992d2a8f..54d54ff195 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -360,44 +360,30 @@ call_cfunc(VALUE (*func)(), VALUE recv, static inline VALUE vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, - int num, VALUE recv, const rb_block_t *blockptr, VALUE flag, + int num, VALUE recv, const rb_block_t *blockptr, const rb_method_entry_t *me) { VALUE val = 0; int state = 0; const rb_method_definition_t *def = me->def; - VALUE klass = me->klass; - ID id = me->called_id; + rb_control_frame_t *cfp; - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass); + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass); - TH_PUSH_TAG(th); - /* TODO: fix me. separate event */ - if (th->event_flags & (RUBY_EVENT_C_RETURN | RUBY_EVENT_VM)) { - state = TH_EXEC_TAG(); - } - else { - _th->tag = _tag.prev; - } - if (state == 0) { - rb_control_frame_t *cfp = - vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, - recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1); + cfp = vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC, + recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1); + cfp->me = me; + reg_cfp->sp -= num + 1; - cfp->me = me; - reg_cfp->sp -= num + 1; + val = call_cfunc(def->body.cfunc.func, recv, (int)def->body.cfunc.argc, num, reg_cfp->sp + 1); - val = call_cfunc(def->body.cfunc.func, recv, (int)def->body.cfunc.argc, num, reg_cfp->sp + 1); + if (reg_cfp != th->cfp + 1) { + rb_bug("cfp consistency error - send"); + } - if (reg_cfp != th->cfp + 1) { - rb_bug("cfp consistency error - send"); - } + vm_pop_frame(th); - vm_pop_frame(th); - } - TH_POP_TAG(); - EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass); - if (state) TH_JUMP_TAG(th, state); + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, me->called_id, me->klass); return val; } @@ -512,7 +498,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, } case VM_METHOD_TYPE_NOTIMPLEMENTED: case VM_METHOD_TYPE_CFUNC:{ - val = vm_call_cfunc(th, cfp, num, recv, blockptr, flag, me); + val = vm_call_cfunc(th, cfp, num, recv, blockptr, me); break; } case VM_METHOD_TYPE_ATTRSET:{ |