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/