summaryrefslogtreecommitdiff
path: root/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 /eval.c
parent2979842520060311909874e300ef943cca2d215c (diff)
downloadruby-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.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/eval.c b/eval.c
index c5a72dc609..f60a7e4a5a 100644
--- a/eval.c
+++ b/eval.c
@@ -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