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

ruby-changes:10795

From: ko1 <ko1@a...>
Date: Tue, 17 Feb 2009 05:55:13 +0900 (JST)
Subject: [ruby-changes:10795] Ruby:r22363 (trunk): * compile.c: fix to add "ensure" codes across "while" clause

ko1	2009-02-17 05:54:58 +0900 (Tue, 17 Feb 2009)

  New Revision: 22363

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

  Log:
    * compile.c: fix to add "ensure" codes across "while" clause
      before "return" expression.  [ruby-dev:37967]
    * bootstraptest/test_flow.rb: add a test.

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/test_flow.rb
    trunk/compile.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 22362)
+++ ChangeLog	(revision 22363)
@@ -1,3 +1,10 @@
+Tue Feb 17 05:41:08 2009  Koichi Sasada  <ko1@a...>
+
+	* compile.c: fix to add "ensure" codes across "while" clause
+	  before "return" expression.  [ruby-dev:37967]
+
+	* bootstraptest/test_flow.rb: add a test.
+
 Tue Feb 17 01:53:35 2009  Tanaka Akira  <akr@f...>
 
 	* ext/socket/mkconstants.rb: generate rb_define_const directly for
Index: bootstraptest/test_flow.rb
===================================================================
--- bootstraptest/test_flow.rb	(revision 22362)
+++ bootstraptest/test_flow.rb	(revision 22363)
@@ -200,7 +200,9 @@
   end; $a << 8
 ; $a << 9
 ; rescue Exception; $a << 99; end; $a}
-assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1
+assert_equal %q{[1, 2, 3, 5, 99]}, %q{
+$a = [];
+begin; ; $a << 1
   while true; $a << 2
     begin; $a << 3
       break; $a << 4
@@ -488,4 +490,15 @@
     a << :last
   end
   a
-   }
+}
+assert_equal %Q{ENSURE\n}, %q{
+  def test
+    while true
+      return
+    end
+  ensure
+    puts("ENSURE")
+  end
+  test
+}, '[ruby-dev:37967]'
+
Index: compile.c
===================================================================
--- compile.c	(revision 22362)
+++ compile.c	(revision 22363)
@@ -2750,6 +2750,17 @@
 }
 
 static void
+push_ensure_entry(rb_iseq_t *iseq,
+		  struct iseq_compile_data_ensure_node_stack *enl,
+		  struct ensure_range *er, NODE *node)
+{
+    enl->ensure_node = node;
+    enl->prev = iseq->compile_data->ensure_node_stack;	/* prev */
+    enl->erange = er;
+    iseq->compile_data->ensure_node_stack = enl;
+}
+
+static void
 add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange,
 		 LABEL *lstart, LABEL *lend)
 {
@@ -2768,7 +2779,7 @@
 }
 
 static void
-add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq)
+add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return)
 {
     struct iseq_compile_data_ensure_node_stack *enlp =
 	iseq->compile_data->ensure_node_stack;
@@ -2777,19 +2788,25 @@
 
     INIT_ANCHOR(ensure);
     while (enlp) {
-	DECL_ANCHOR(ensure_part);
-	LABEL *lstart = NEW_LABEL(0);
-	LABEL *lend = NEW_LABEL(0);
+	if (enlp->erange != 0) {
+	    DECL_ANCHOR(ensure_part);
+	    LABEL *lstart = NEW_LABEL(0);
+	    LABEL *lend = NEW_LABEL(0);
+	    INIT_ANCHOR(ensure_part);
 
-	INIT_ANCHOR(ensure_part);
-	add_ensure_range(iseq, enlp->erange, lstart, lend);
+	    add_ensure_range(iseq, enlp->erange, lstart, lend);
 
-	iseq->compile_data->ensure_node_stack = enlp->prev;
-	ADD_LABEL(ensure_part, lstart);
-	COMPILE_POPED(ensure_part, "ensure part", enlp->ensure_node);
-	ADD_LABEL(ensure_part, lend);
-
-	ADD_SEQ(ensure, ensure_part);
+	    iseq->compile_data->ensure_node_stack = enlp->prev;
+	    ADD_LABEL(ensure_part, lstart);
+	    COMPILE_POPED(ensure_part, "ensure part", enlp->ensure_node);
+	    ADD_LABEL(ensure_part, lend);
+	    ADD_SEQ(ensure, ensure_part);
+	}
+	else {
+	    if (!is_return) {
+		break;
+	    }
+	}
 	enlp = enlp->prev;
     }
     iseq->compile_data->ensure_node_stack = prev_enlp;
@@ -3123,8 +3140,7 @@
 	LABEL *prev_redo_label = iseq->compile_data->redo_label;
 	VALUE prev_loopval_popped = iseq->compile_data->loopval_popped;
 
-	struct iseq_compile_data_ensure_node_stack *enlp =
-	    iseq->compile_data->ensure_node_stack;
+	struct iseq_compile_data_ensure_node_stack enl;
 
 	LABEL *next_label = iseq->compile_data->start_label = NEW_LABEL(nd_line(node));	/* next  */
 	LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(nd_line(node));	/* redo  */
@@ -3135,7 +3151,7 @@
 	LABEL *tmp_label = NULL;
 
 	iseq->compile_data->loopval_popped = 0;
-	iseq->compile_data->ensure_node_stack = 0;
+	push_ensure_entry(iseq, &enl, 0, 0);
 
 	if (type == NODE_OPT_N || node->nd_state == 1) {
 	    ADD_INSNL(ret, nd_line(node), jump, next_label);
@@ -3197,7 +3213,7 @@
 	iseq->compile_data->end_label = prev_end_label;
 	iseq->compile_data->redo_label = prev_redo_label;
 	iseq->compile_data->loopval_popped = prev_loopval_popped;
-	iseq->compile_data->ensure_node_stack = enlp;
+	iseq->compile_data->ensure_node_stack = iseq->compile_data->ensure_node_stack->prev;
 	break;
       }
       case NODE_ITER:
@@ -3246,7 +3262,7 @@
 	    ADD_LABEL(ret, splabel);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
 	    COMPILE_(ret, "break val (while/until)", node->nd_stts, iseq->compile_data->loopval_popped);
-	    add_ensure_iseq(ret, iseq);
+	    add_ensure_iseq(ret, iseq, 0);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
 	    ADD_ADJUST_RESTORE(ret, splabel);
 
@@ -3306,7 +3322,7 @@
 	    debugs("next in while loop\n");
 	    ADD_LABEL(ret, splabel);
 	    COMPILE(ret, "next val/valid syntax?", node->nd_stts);
-	    add_ensure_iseq(ret, iseq);
+	    add_ensure_iseq(ret, iseq, 0);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
 	    ADD_ADJUST_RESTORE(ret, splabel);
@@ -3317,7 +3333,7 @@
 	    ADD_LABEL(ret, splabel);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
 	    COMPILE(ret, "next val", node->nd_stts);
-	    add_ensure_iseq(ret, iseq);
+	    add_ensure_iseq(ret, iseq, 0);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
 	    ADD_ADJUST_RESTORE(ret, splabel);
 
@@ -3372,7 +3388,7 @@
 	    debugs("redo in while");
 	    ADD_LABEL(ret, splabel);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
-	    add_ensure_iseq(ret, iseq);
+	    add_ensure_iseq(ret, iseq, 0);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->redo_label);
 	    ADD_ADJUST_RESTORE(ret, splabel);
 	}
@@ -3385,7 +3401,7 @@
 
 	    debugs("redo in block");
 	    ADD_LABEL(ret, splabel);
-	    add_ensure_iseq(ret, iseq);
+	    add_ensure_iseq(ret, iseq, 0);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
 	    ADD_ADJUST_RESTORE(ret, splabel);
@@ -3542,20 +3558,18 @@
 	LABEL *lstart = NEW_LABEL(nd_line(node));
 	LABEL *lend = NEW_LABEL(nd_line(node));
 	LABEL *lcont = NEW_LABEL(nd_line(node));
-	struct ensure_range er = { 0 };
+	struct ensure_range er;
 	struct iseq_compile_data_ensure_node_stack enl;
 	struct ensure_range *erange;
 
 	INIT_ANCHOR(ensr);
+	COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr);
+
 	er.begin = lstart;
 	er.end = lend;
-	enl.ensure_node = node->nd_ensr;
-	enl.prev = iseq->compile_data->ensure_node_stack;	/* prev */
-	enl.erange = &er;
-	COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr);
+	er.next = 0;
+	push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
 
-	iseq->compile_data->ensure_node_stack = &enl;
-
 	ADD_LABEL(ret, lstart);
 	COMPILE_(ret, "ensure head", node->nd_head, poped);
 	ADD_LABEL(ret, lend);
@@ -3573,6 +3587,7 @@
 			    ensure, lcont);
 	    erange = erange->next;
 	}
+
 	iseq->compile_data->ensure_node_stack = enl.prev;
 	break;
       }
@@ -4171,7 +4186,7 @@
 		COMPILE(ret, "return nd_stts (return val)", node->nd_stts);
 
 		if (is->type == ISEQ_TYPE_METHOD) {
-		    add_ensure_iseq(ret, iseq);
+		    add_ensure_iseq(ret, iseq, 1);
 		    ADD_INSN(ret, nd_line(node), leave);
 		    ADD_ADJUST_RESTORE(ret, splabel);
 

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

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