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 /eval.c | |
parent | 2979842520060311909874e300ef943cca2d215c (diff) | |
download | ruby-618445576faa94fcd6d3957ea3fb59f6372b64ba.tar.gz |
* 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 'eval.c')
-rw-r--r-- | eval.c | 25 |
1 files changed, 19 insertions, 6 deletions
@@ -352,11 +352,10 @@ rb_frozen_class_p(VALUE klass) NORETURN(static void rb_longjmp(int, volatile VALUE)); static void -rb_longjmp(int tag, volatile VALUE mesg) +setup_exception(rb_thread_t *th, int tag, volatile VALUE mesg) { VALUE at; VALUE e; - rb_thread_t *th = GET_THREAD(); const char *file; volatile int line = 0; @@ -425,10 +424,15 @@ rb_longjmp(int tag, volatile VALUE mesg) rb_trap_restore_mask(); if (tag != TAG_FATAL) { - EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, - 0 /* TODO: id */, 0 /* TODO: klass */); + EXEC_EVENT_HOOK(th, RUBY_EVENT_RAISE, th->cfp->self, 0, 0); } +} +static void +rb_longjmp(int tag, volatile VALUE mesg) +{ + rb_thread_t *th = GET_THREAD(); + setup_exception(th, tag, mesg); rb_thread_raised_clear(th); JUMP_TAG(tag); } @@ -559,9 +563,18 @@ void rb_raise_jump(VALUE mesg) { rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = th->cfp; + VALUE klass = cfp->me->klass; + VALUE self = cfp->self; + ID mid = cfp->me->called_id; + th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); - /* TODO: fix me */ - rb_longjmp(TAG_RAISE, mesg); + + setup_exception(th, TAG_RAISE, mesg); + + EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, self, mid, klass); + rb_thread_raised_clear(th); + JUMP_TAG(TAG_RAISE); } void |