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

ruby-changes:21047

From: ktsj <ko1@a...>
Date: Sat, 27 Aug 2011 18:59:59 +0900 (JST)
Subject: [ruby-changes:21047] ktsj:r33096 (trunk): * proc.c (proc_new): force to rewrite errinfo when calling Proc.new in ensure.

ktsj	2011-08-27 18:59:48 +0900 (Sat, 27 Aug 2011)

  New Revision: 33096

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

  Log:
    * proc.c (proc_new): force to rewrite errinfo when calling Proc.new in ensure.
      [Bug #5234] [ruby-core:39125]
      This code will be removed after changing throw mechanism (see r33064).
    
    * vm.c (rb_vm_rewrite_dfp_in_errinfo): new function.
    
    * vm.c (vm_make_env_each): changed accordingly.
    
    * vm_core.h: ditto.
    
    * bootstraptest/test_flow.rb: add tests for above.

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/test_flow.rb
    trunk/proc.c
    trunk/vm.c
    trunk/vm_core.h

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 33095)
+++ ChangeLog	(revision 33096)
@@ -1,3 +1,17 @@
+Sat Aug 27 18:53:51 2011  Kazuki Tsujimoto  <kazuki@c...>
+
+	* proc.c (proc_new): force to rewrite errinfo when calling Proc.new in ensure.
+	  [Bug #5234] [ruby-core:39125]
+	  This code will be removed after changing throw mechanism (see r33064).
+
+	* vm.c (rb_vm_rewrite_dfp_in_errinfo): new function.
+
+	* vm.c (vm_make_env_each): changed accordingly.
+
+	* vm_core.h: ditto.
+
+	* bootstraptest/test_flow.rb: add tests for above.
+
 Sat Aug 27 18:44:06 2011  NARUSE, Yui  <naruse@r...>
 
 	* internal.h (rb_strftime_timespec): move to time.c because it depends
Index: bootstraptest/test_flow.rb
===================================================================
--- bootstraptest/test_flow.rb	(revision 33095)
+++ bootstraptest/test_flow.rb	(revision 33096)
@@ -530,6 +530,19 @@
     end
   end
   e = Bug2729.new
+}],
+ ['[ruby-core:39125]', %q{
+  class Bug5234
+    include Enumerable
+    def each
+      begin
+        yield :foo
+      ensure
+        proc
+      end
+    end
+  end
+  e = Bug5234.new
 }]].each do |bug, src|
   assert_equal "foo", src + %q{e.detect {true}}, bug
   assert_equal "true", src + %q{e.any? {true}}, bug
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 33095)
+++ vm_core.h	(revision 33096)
@@ -649,6 +649,7 @@
 			int argc, const VALUE *argv, const rb_block_t *blockptr);
 VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
 VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
+VALUE rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
 void rb_vm_inc_const_missing_count(void);
 void rb_vm_gvl_destroy(rb_vm_t *vm);
 VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc,
Index: proc.c
===================================================================
--- proc.c	(revision 33095)
+++ proc.c	(revision 33096)
@@ -418,6 +418,7 @@
     }
 
     procval = rb_vm_make_proc(th, block, klass);
+    rb_vm_rewrite_dfp_in_errinfo(th, cfp);
 
     if (is_lambda) {
 	rb_proc_t *proc;
Index: vm.c
===================================================================
--- vm.c	(revision 33095)
+++ vm.c	(revision 33096)
@@ -410,22 +410,7 @@
 	/* TODO */
 	env->block.iseq = 0;
     } else {
-	/* rewrite dfp in errinfo to point to heap */
-	if (cfp->iseq->type == ISEQ_TYPE_RESCUE ||
-	    cfp->iseq->type == ISEQ_TYPE_ENSURE) {
-	    VALUE errinfo = env->env[0]; /* #$! */
-	    if (RB_TYPE_P(errinfo, T_NODE)) {
-		VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
-		if (! ENV_IN_HEAP_P(th, escape_dfp)) {
-		    VALUE dfpval = *escape_dfp;
-		    if (CLASS_OF(dfpval) == rb_cEnv) {
-			rb_env_t *dfpenv;
-			GetEnvPtr(dfpval, dfpenv);
-			SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
-		    }
-		}
-	    }
-	}
+	rb_vm_rewrite_dfp_in_errinfo(th, cfp);
     }
     return envval;
 }
@@ -488,6 +473,28 @@
     return envval;
 }
 
+VALUE
+rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+    /* rewrite dfp in errinfo to point to heap */
+    if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
+	(cfp->iseq->type == ISEQ_TYPE_RESCUE ||
+	 cfp->iseq->type == ISEQ_TYPE_ENSURE)) {
+	VALUE errinfo = cfp->dfp[-2]; /* #$! */
+	if (RB_TYPE_P(errinfo, T_NODE)) {
+	    VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
+	    if (! ENV_IN_HEAP_P(th, escape_dfp)) {
+		VALUE dfpval = *escape_dfp;
+		if (CLASS_OF(dfpval) == rb_cEnv) {
+		    rb_env_t *dfpenv;
+		    GetEnvPtr(dfpval, dfpenv);
+		    SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
+		}
+	    }
+	}
+    }
+}
+
 void
 rb_vm_stack_to_heap(rb_thread_t *th)
 {

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

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