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

ruby-changes:5913

From: ko1 <ko1@a...>
Date: Thu, 19 Jun 2008 11:46:29 +0900 (JST)
Subject: [ruby-changes:5913] Ruby:r17421 (trunk): * vm_insnhelper.c (vm_throw): fix "return" process from "lambda".

ko1	2008-06-19 11:46:02 +0900 (Thu, 19 Jun 2008)

  New Revision: 17421

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/pending.rb
    trunk/bootstraptest/test_proc.rb
    trunk/vm_insnhelper.c

  Log:
    * vm_insnhelper.c (vm_throw): fix "return" process from "lambda".
    * bootstraptest/test_proc.rb: add a test.
    * bootstraptest/pending.rb: add a pending bug.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=17421&r2=17420&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_proc.rb?r1=17421&r2=17420&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_insnhelper.c?r1=17421&r2=17420&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/pending.rb?r1=17421&r2=17420&diff_format=u

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 17420)
+++ ChangeLog	(revision 17421)
@@ -1,3 +1,11 @@
+Thu Jun 19 11:40:55 2008  Koichi Sasada  <ko1@a...>
+
+	* vm_insnhelper.c (vm_throw): fix "return" process from "lambda".
+
+	* bootstraptest/test_proc.rb: add a test.
+
+	* bootstraptest/pending.rb: add a pending bug.
+
 Thu Jun 19 00:33:40 2008  Yusuke Endoh  <mame@t...>
 
 	* test/etc/test_etc.rb: avoid infinite loop.  [ruby-dev:35158]
Index: bootstraptest/pending.rb
===================================================================
--- bootstraptest/pending.rb	(revision 17420)
+++ bootstraptest/pending.rb	(revision 17421)
@@ -13,3 +13,20 @@
   B.new.a = 'B'
   A.new.a
 }, '[ruby-core:17019]'
+
+assert_equal 'ok', %q{
+  def m
+    lambda{
+      proc{
+        return :ng1
+      }
+    }.call.call
+    :ng2
+  end
+
+  begin
+    m()
+  rescue LocalJumpError
+    :ok
+  end
+}
Index: bootstraptest/test_proc.rb
===================================================================
--- bootstraptest/test_proc.rb	(revision 17420)
+++ bootstraptest/test_proc.rb	(revision 17421)
@@ -364,3 +364,17 @@
    def12
    $x
 }, '[ruby-core:17164]'
+
+assert_equal 'ok', %q{
+  def m
+    pr = proc{
+      proc{
+        return :ok
+      }
+    }.call
+    pr.call
+    :ng
+  end
+  m()
+}
+
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 17420)
+++ vm_insnhelper.c	(revision 17421)
@@ -1279,34 +1279,36 @@
 	    else if (state == TAG_RETURN) {
 		rb_control_frame_t *cfp = GET_CFP();
 		VALUE *dfp = GET_DFP();
-		int is_orphan = 1;
+		VALUE * const lfp = GET_LFP();
 
-		/**
-		 * check orphan:
-		 */
+		/* check orphan and get dfp */
 		while ((VALUE *) cfp < th->stack + th->stack_size) {
-		    if (dfp == cfp->dfp) {
+		    if (cfp->lfp == lfp) {
 			if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
-			    /* in lambda */
-			    is_orphan = 0;
-			    break;
-			}
+			    VALUE *tdfp = dfp;
 
-			if (GET_LFP() == dfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
-			    is_orphan = 0;
-			    break;
+			    while (lfp != tdfp) {
+				if (cfp->dfp == tdfp) {
+				    /* in lambda */
+				    dfp = cfp->dfp;
+				    goto valid_return;
+				}
+				tdfp = GC_GUARDED_PTR_REF((VALUE *)*dfp);
+			    }
 			}
+		    }
 
-			dfp = GC_GUARDED_PTR_REF(dfp[0]);
+		    if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_METHOD) {
+			dfp = lfp;
+			goto valid_return;
 		    }
 
 		    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
 		}
 
-		if (is_orphan) {
-		    vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
-		}
+		vm_localjump_error("unexpected return", throwobj, TAG_RETURN);
 
+	      valid_return:
 		pt = dfp;
 	    }
 	    else {

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

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