summaryrefslogtreecommitdiff
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-01-24 13:52:32 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-01-24 13:52:32 +0000
commit618445576faa94fcd6d3957ea3fb59f6372b64ba (patch)
tree36cc450623d3e216e643a3f9acc183537e3e05a2 /vm_insnhelper.c
parent2979842520060311909874e300ef943cca2d215c (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.c42
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:{