diff options
author | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-22 12:49:46 +0000 |
---|---|---|
committer | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-22 12:49:46 +0000 |
commit | 4a3765a2cbd7863301e4e2ac2783ee5c54d13f68 (patch) | |
tree | 93bd7259f8c3c8c6b5f114b2a5209acf1495ccb2 | |
parent | 8335857ede39cfbdf2bb5a0bff69130ee90dd19b (diff) |
merges r22363 from trunk into ruby_1_9_1.
* compile.c: fix to add "ensure" codes across "while" clause
before "return" expression. [ruby-dev:37967]
* bootstraptest/test_flow.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@22536 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | bootstraptest/test_flow.rb | 17 | ||||
-rw-r--r-- | compile.c | 73 |
3 files changed, 66 insertions, 31 deletions
@@ -1,3 +1,10 @@ +Tue Feb 17 05:41:08 2009 Koichi Sasada <ko1@atdot.net> + + * compile.c: fix to add "ensure" codes across "while" clause + before "return" expression. [ruby-dev:37967] + + * bootstraptest/test_flow.rb: add a test. + Sun Feb 15 11:45:29 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> * variable.c (rb_define_hooked_variable): suppress false assertion diff --git a/bootstraptest/test_flow.rb b/bootstraptest/test_flow.rb index 9964dfb2ed..46ca1a0c6a 100644 --- a/bootstraptest/test_flow.rb +++ b/bootstraptest/test_flow.rb @@ -200,7 +200,9 @@ assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1 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 @@ assert_equal %q{[:ok, :ok2, :last]}, %q{ a << :last end a - } +} +assert_equal %Q{ENSURE\n}, %q{ + def test + while true + return + end + ensure + puts("ENSURE") + end + test +}, '[ruby-dev:37967]' + @@ -2748,6 +2748,17 @@ make_name_for_block(rb_iseq_t *iseq) } 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) { @@ -2766,7 +2777,7 @@ add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange, } 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; @@ -2775,19 +2786,25 @@ add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq) 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; @@ -3121,8 +3138,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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 */ @@ -3133,7 +3149,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); @@ -3195,7 +3211,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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: @@ -3244,7 +3260,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); @@ -3304,7 +3320,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); @@ -3315,7 +3331,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); @@ -3370,7 +3386,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); } @@ -3383,7 +3399,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); @@ -3540,19 +3556,17 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); - 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); - iseq->compile_data->ensure_node_stack = &enl; + er.begin = lstart; + er.end = lend; + er.next = 0; + push_ensure_entry(iseq, &enl, &er, node->nd_ensr); ADD_LABEL(ret, lstart); COMPILE_(ret, "ensure head", node->nd_head, poped); @@ -3571,6 +3585,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) ensure, lcont); erange = erange->next; } + iseq->compile_data->ensure_node_stack = enl.prev; break; } @@ -4169,7 +4184,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) 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); |