[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]