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 /compile.c | |
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
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 73 |
1 files changed, 44 insertions, 29 deletions
@@ -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); |