ruby-changes:5883
From: ko1 <ko1@a...>
Date: Wed, 18 Jun 2008 04:27:41 +0900 (JST)
Subject: [ruby-changes:5883] Ruby:r17390 (trunk): * vm.c, vm_insnhelper.c: fix escape process with "braek" and "return"
ko1 2008-06-18 04:27:24 +0900 (Wed, 18 Jun 2008) New Revision: 17390 Modified files: trunk/ChangeLog trunk/KNOWNBUGS.rb trunk/bootstraptest/test_proc.rb trunk/vm.c trunk/vm_insnhelper.c Log: * vm.c, vm_insnhelper.c: fix escape process with "braek" and "return" syntax in "lambda". [ ruby-Bugs-19304 ], [ruby-core:17164] * KNOWNBUGS.rb, bootstraptest/test_proc.rb: add/move solved test. http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=17390&r2=17389&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_proc.rb?r1=17390&r2=17389&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/KNOWNBUGS.rb?r1=17390&r2=17389&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.c?r1=17390&r2=17389&diff_format=u http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_insnhelper.c?r1=17390&r2=17389&diff_format=u Index: ChangeLog =================================================================== --- ChangeLog (revision 17389) +++ ChangeLog (revision 17390) @@ -1,3 +1,10 @@ +Wed Jun 18 04:24:20 2008 Koichi Sasada <ko1@a...> + + * vm.c, vm_insnhelper.c: fix escape process with "braek" and "return" + syntax in "lambda". [ ruby-Bugs-19304 ], [ruby-core:17164] + + * KNOWNBUGS.rb, bootstraptest/test_proc.rb: add/move solved test. + Wed Jun 18 01:51:10 2008 Hidetoshi NAGAI <nagai@a...> * ext/tk/lib/multi-tk.rb: cannot access class variable from Index: bootstraptest/test_proc.rb =================================================================== --- bootstraptest/test_proc.rb (revision 17389) +++ bootstraptest/test_proc.rb (revision 17390) @@ -276,3 +276,91 @@ :ng }.call }, '[ruby-dev:34646]' + +assert_equal %q{[:bar, :foo]}, %q{ + def foo + klass = Class.new do + define_method(:bar) do + return :bar + end + end + [klass.new.bar, :foo] + end + foo +}, "[ ruby-Bugs-19304 ]" + +assert_equal 'ok', %q{ + $x = :ok + def def7(x, y) + x[y] + $x = :ng + end + def test_def7 + def7(lambda {|x| x.call}, Proc.new {return}) + $x = :ng + end + test_def7 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + lambda { a = lambda { return }; $x = :ng; a[]; $x = :ok }.call + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + lambda { a = lambda { break }; $x = :ng; a[]; $x = :ok }.call + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def8 + $x = :ng + lambda { a = Proc.new { return }; a[]}.call + $x = :ok + end + def8 + $x +}, '[ruby-core:17164]' + + +assert_equal 'ok', %q{ + def def9 + lambda {|a| $x = :ok; a[]; $x = :ng }.call(Proc.new { return }) + $x = :ng + end + def9 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def10 + $x = :ng + lambda { 1.times { return } }.call + $x = :ok + end + $x = :ok + def10 + $x +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def11 + yield + end + begin + lambda { def11 { return } }.call + rescue LocalJumpError + :ng + else + :ok + end +}, '[ruby-core:17164]' + +assert_equal 'ok', %q{ + def def12 + b = Proc.new { $x = :ng; lambda { return }.call; $x = :ok }.call + end + def12 + $x +}, '[ruby-core:17164]' Index: KNOWNBUGS.rb =================================================================== --- KNOWNBUGS.rb (revision 17389) +++ KNOWNBUGS.rb (revision 17390) @@ -3,15 +3,18 @@ # So all tests will cause failure. # -assert_equal %q{[:bar, :foo]}, %q{ - def foo - klass = Class.new do - define_method(:bar) do - return :bar - end +assert_equal 'A', %q{ + class A + @@a = 'A' + def a=(x) + @@a = x end - [klass.new.bar, :foo] + def a + @@a + end end - foo -}, "[ ruby-Bugs-19304 ]" + B = A.dup + B.new.a = 'B' + A.new.a +} Index: vm.c =================================================================== --- vm.c (revision 17389) +++ vm.c (revision 17390) @@ -525,9 +525,9 @@ if (state == TAG_RETURN && proc->is_lambda) { VALUE err = th->errinfo; VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(err); - VALUE *cdfp = proc->block.dfp; - if (escape_dfp == cdfp) { + if (escape_dfp == cfp->dfp) { + printf("ok\n"); state = 0; th->errinfo = Qnil; th->cfp = cfp; Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 17389) +++ vm_insnhelper.c (revision 17390) @@ -1044,7 +1044,8 @@ { VALUE klass; - while (cref && cref->nd_next && (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) { + while (cref && cref->nd_next && + (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) { cref = cref->nd_next; if (!cref->nd_next) { @@ -1221,7 +1222,7 @@ if (cfp->dfp == dfp) { goto search_parent; } - cfp++; + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } rb_bug("VM (throw): can't find break base."); } @@ -1229,7 +1230,7 @@ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) { /* lambda{... break ...} */ is_orphan = 0; - pt = GET_LFP(); + pt = cfp->dfp; state = TAG_RETURN; } else { @@ -1261,7 +1262,7 @@ is_orphan = 0; break; } - cfp++; + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } } @@ -1284,26 +1285,29 @@ * check orphan: */ while ((VALUE *) cfp < th->stack + th->stack_size) { - if (GET_DFP() == dfp) { + if (dfp == cfp->dfp) { if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) { /* in lambda */ is_orphan = 0; break; } + + if (GET_LFP() == dfp && cfp->iseq->type == ISEQ_TYPE_METHOD) { + is_orphan = 0; + break; + } + + dfp = GC_GUARDED_PTR_REF(dfp[0]); } - if (GET_LFP() == cfp->lfp && - cfp->iseq->type == ISEQ_TYPE_METHOD) { - is_orphan = 0; - break; - } - cfp++; + + cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); } if (is_orphan) { vm_localjump_error("unexpected return", throwobj, TAG_RETURN); } - pt = GET_LFP(); + pt = dfp; } else { rb_bug("isns(throw): unsupport throw type"); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/