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

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/

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