ruby-changes:20447
From: ko1 <ko1@a...>
Date: Sun, 10 Jul 2011 18:04:57 +0900 (JST)
Subject: [ruby-changes:20447] ko1:r32495 (trunk): * vm_insnhelper.c (vm_throw): check a class frame.
ko1 2011-07-10 18:04:44 +0900 (Sun, 10 Jul 2011) New Revision: 32495 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=32495 Log: * vm_insnhelper.c (vm_throw): check a class frame. Fixes Bug #4648. The patch is contributed by Kazuki Tsujimoto. * bootstraptest/test_proc.rb: add tests for above. Modified files: trunk/ChangeLog trunk/bootstraptest/test_proc.rb trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 32494) +++ ChangeLog (revision 32495) @@ -1,3 +1,11 @@ +Sun Jul 10 16:57:08 2011 Koichi Sasada <ko1@a...> + + * vm_insnhelper.c (vm_throw): check a class frame. + Fixes Bug #4648. + The patch is contributed by Kazuki Tsujimoto. + + * bootstraptest/test_proc.rb: add tests for above. + Sun Jul 10 17:28:01 2011 KOSAKI Motohiro <kosaki.motohiro@g...> * thread_pthread.c (mutex_debug): use exit(EXIT_FAILURE) instad of Index: bootstraptest/test_proc.rb =================================================================== --- bootstraptest/test_proc.rb (revision 32494) +++ bootstraptest/test_proc.rb (revision 32495) @@ -429,3 +429,30 @@ raise "ok" } +assert_equal 'ok', %q{ + lambda do + class A + class B + proc{return :ng}.call + end + end + end.call + :ok +} + +assert_equal 'ok', %q{ + $proc = proc{return} + begin + lambda do + class A + class B + $proc.call + end + end + end.call + :ng + rescue LocalJumpError + :ok + end +} + Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 32494) +++ vm_insnhelper.c (revision 32495) @@ -1541,6 +1541,7 @@ rb_control_frame_t *cfp = GET_CFP(); VALUE *dfp = GET_DFP(); VALUE *lfp = GET_LFP(); + int in_class_frame = 0; /* check orphan and get dfp */ while ((VALUE *) cfp < th->stack + th->stack_size) { @@ -1548,6 +1549,7 @@ lfp = cfp->lfp; } if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) { + in_class_frame = 1; lfp = 0; } @@ -1555,6 +1557,12 @@ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) { VALUE *tdfp = dfp; + if (in_class_frame) { + /* lambda {class A; ... return ...; end} */ + dfp = cfp->dfp; + goto valid_return; + } + while (lfp != tdfp) { if (cfp->dfp == tdfp) { /* in lambda */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/