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

ruby-changes:25373

From: nobu <ko1@a...>
Date: Sat, 3 Nov 2012 04:14:46 +0900 (JST)
Subject: [ruby-changes:25373] nobu:r37430 (trunk): vm.c: rewrite all catch points

nobu	2012-11-03 04:14:24 +0900 (Sat, 03 Nov 2012)

  New Revision: 37430

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37430

  Log:
    vm.c: rewrite all catch points
    
    * vm.c (rb_vm_rewrite_ep_in_errinfo): rewrite all catch points in
      errinfo, not only the topmost frame.  based on the patch by
      ktsj (Kazuki Tsujimoto) in [ruby-dev:45656]. [Bug #6460]

  Modified files:
    trunk/ChangeLog
    trunk/KNOWNBUGS.rb
    trunk/bootstraptest/test_flow.rb
    trunk/vm.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 37429)
+++ ChangeLog	(revision 37430)
@@ -1,3 +1,9 @@
+Sat Nov  3 04:14:19 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* vm.c (rb_vm_rewrite_ep_in_errinfo): rewrite all catch points in
+	  errinfo, not only the topmost frame.  based on the patch by
+	  ktsj (Kazuki Tsujimoto) in [ruby-dev:45656]. [Bug #6460]
+
 Fri Nov  2 20:11:17 2012  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/mkmf.rb (MakeMakefile#timestamp_file): remove @ which looks like
Index: bootstraptest/test_flow.rb
===================================================================
--- bootstraptest/test_flow.rb	(revision 37429)
+++ bootstraptest/test_flow.rb	(revision 37430)
@@ -543,9 +543,49 @@
     end
   end
   e = Bug5234.new
+}],
+ ['[ruby-dev:45656]', %q{
+  class Bug6460
+    include Enumerable
+    def each
+      begin
+        yield :foo
+      ensure
+        1.times { Proc.new }
+      end
+    end
+  end
+  e = Bug6460.new
 }]].each do |bug, src|
   assert_equal "foo", src + %q{e.detect {true}}, bug
   assert_equal "true", src + %q{e.any? {true}}, bug
   assert_equal "false", src + %q{e.all? {false}}, bug
   assert_equal "true", src + %q{e.include?(:foo)}, bug
 end
+
+assert_equal "foo", %q{
+  class Bug6460
+    def m1
+      m2 {|e|
+        return e
+      }
+    end
+
+    def m2
+      begin
+        yield :foo
+      ensure
+        begin
+          begin
+            yield :foo
+          ensure
+            Proc.new
+            raise ''
+          end
+        rescue
+        end
+      end
+    end
+  end
+  Bug6460.new.m1
+}, '[ruby-dev:46372]'
Index: KNOWNBUGS.rb
===================================================================
--- KNOWNBUGS.rb	(revision 37429)
+++ KNOWNBUGS.rb	(revision 37430)
@@ -3,21 +3,3 @@
 # So all tests will cause failure.
 #
 
-[['[ruby-dev:45656]', %q{
-  class Bug6460
-    include Enumerable
-    def each
-      begin
-        yield :foo
-      ensure
-        1.times { Proc.new }
-      end
-    end
-  end
-  e = Bug6460.new
-}]].each do |bug, src|
-  assert_equal "foo", src + %q{e.detect {true}}, bug
-  assert_equal "true", src + %q{e.any? {true}}, bug
-  assert_equal "false", src + %q{e.all? {false}}, bug
-  assert_equal "true", src + %q{e.include?(:foo)}, bug
-end
Index: vm.c
===================================================================
--- vm.c	(revision 37429)
+++ vm.c	(revision 37430)
@@ -434,7 +434,8 @@
     if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
 	/* TODO */
 	env->block.iseq = 0;
-    } else {
+    }
+    else {
 	rb_vm_rewrite_ep_in_errinfo(th, cfp);
     }
     return envval;
@@ -493,9 +494,20 @@
     return envval;
 }
 
+static void vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
+
 void
 rb_vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
 {
+    while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
+	vm_rewrite_ep_in_errinfo(th, cfp);
+	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+    }
+}
+
+static void
+vm_rewrite_ep_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
+{
     /* rewrite ep in errinfo to point to heap */
     if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
 	(cfp->iseq->type == ISEQ_TYPE_RESCUE ||
@@ -505,7 +517,7 @@
 	    VALUE *escape_ep = GET_THROWOBJ_CATCH_POINT(errinfo);
 	    if (! ENV_IN_HEAP_P(th, escape_ep)) {
 		VALUE epval = *escape_ep;
-		if (CLASS_OF(epval) == rb_cEnv) {
+		if (!SPECIAL_CONST_P(epval) && RBASIC(epval)->klass == rb_cEnv) {
 		    rb_env_t *epenv;
 		    GetEnvPtr(epval, epenv);
 		    SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(epenv->env + epenv->local_size));

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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