summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c73
1 files changed, 44 insertions, 29 deletions
diff --git a/compile.c b/compile.c
index 24a63e1d68..2bf4167719 100644
--- a/compile.c
+++ b/compile.c
@@ -2750,6 +2750,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)
{
@@ -2768,7 +2779,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;
@@ -2777,19 +2788,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;
@@ -3123,8 +3140,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 */
@@ -3135,7 +3151,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);
@@ -3197,7 +3213,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:
@@ -3246,7 +3262,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);
@@ -3306,7 +3322,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);
@@ -3317,7 +3333,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);
@@ -3372,7 +3388,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);
}
@@ -3385,7 +3401,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);
@@ -3542,19 +3558,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);
@@ -3573,6 +3587,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;
}
@@ -4171,7 +4186,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);