summaryrefslogtreecommitdiff
path: root/vm_eval.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_eval.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_eval.c')
-rw-r--r--vm_eval.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/vm_eval.c b/vm_eval.c
index 2d16ba6653..762453e5fe 100644
--- a/vm_eval.c
+++ b/vm_eval.c
@@ -814,6 +814,9 @@ rb_f_loop(VALUE self)
return Qnil; /* dummy */
}
+static const char *
+vm_frametype_name(const rb_control_frame_t *cfp);
+
VALUE
rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
VALUE (* bl_proc) (ANYARGS), VALUE data2)
@@ -852,7 +855,17 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1,
state = 0;
th->state = 0;
th->errinfo = Qnil;
- th->cfp = cfp;
+
+ /* check skipped frame */
+ while (th->cfp != cfp) {
+ /* printf("skipped frame: %s\n", vm_frametype_name(th->cfp)); */
+ if (UNLIKELY(VM_FRAME_TYPE(th->cfp) == VM_FRAME_MAGIC_CFUNC)) {
+ const rb_method_entry_t *me = th->cfp->me;
+ EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, th->cfp->self, me->called_id, me->klass);
+ }
+
+ th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp);
+ }
}
else{
/* SDR(); printf("%p, %p\n", cdfp, escape_dfp); */