From a2f5275e0b0a79ad804eae3f6c817f8bf9979661 Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 27 Aug 2017 16:18:17 +0000 Subject: [PATCH] compile.c: compile_ensure * compile.c (compile_ensure): extract from iseq_compile_each. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59670 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- compile.c | 107 +++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/compile.c b/compile.c index 868ae2a4a0..29141d61ac 100644 --- a/compile.c +++ b/compile.c @@ -4711,6 +4711,61 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped) return COMPILE_OK; } +static int +compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped) +{ + const int line = nd_line(node); + DECL_ANCHOR(ensr); + const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr, + rb_str_concat(rb_str_new2 ("ensure in "), iseq->body->location.label), + ISEQ_TYPE_ENSURE, line); + LABEL *lstart = NEW_LABEL(line); + LABEL *lend = NEW_LABEL(line); + LABEL *lcont = NEW_LABEL(line); + LINK_ELEMENT *last; + int last_leave = 0; + struct ensure_range er; + struct iseq_compile_data_ensure_node_stack enl; + struct ensure_range *erange; + + INIT_ANCHOR(ensr); + CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr)); + last = ensr->last; + last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave); + + er.begin = lstart; + er.end = lend; + er.next = 0; + push_ensure_entry(iseq, &enl, &er, node->nd_ensr); + + ADD_LABEL(ret, lstart); + CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave))); + ADD_LABEL(ret, lend); + if (ensr->anchor.next == NULL) { + ADD_INSN(ret, line, nop); + } + else { + ADD_SEQ(ret, ensr); + if (!popped && last_leave) { + ADD_INSN(ret, line, putnil); + } + } + ADD_LABEL(ret, lcont); + if (last_leave) ADD_INSN(ret, line, pop); + + erange = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->erange; + if (lstart->link.next != &lend->link) { + while (erange) { + ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end, + ensure, lcont); + erange = erange->next; + } + } + + ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enl.prev; + return COMPILE_OK; +} + static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popped); /** compile each node @@ -4898,57 +4953,9 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, NODE *node, int popp case NODE_RESBODY: CHECK(compile_resbody(iseq, ret, node, popped)); break; - case NODE_ENSURE:{ - DECL_ANCHOR(ensr); - const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr, - rb_str_concat(rb_str_new2 ("ensure in "), iseq->body->location.label), - ISEQ_TYPE_ENSURE, line); - LABEL *lstart = NEW_LABEL(line); - LABEL *lend = NEW_LABEL(line); - LABEL *lcont = NEW_LABEL(line); - LINK_ELEMENT *last; - int last_leave = 0; - struct ensure_range er; - struct iseq_compile_data_ensure_node_stack enl; - struct ensure_range *erange; - - INIT_ANCHOR(ensr); - CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr)); - last = ensr->last; - last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave); - - er.begin = lstart; - er.end = lend; - er.next = 0; - push_ensure_entry(iseq, &enl, &er, node->nd_ensr); - - ADD_LABEL(ret, lstart); - CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave))); - ADD_LABEL(ret, lend); - if (ensr->anchor.next == NULL) { - ADD_INSN(ret, line, nop); - } - else { - ADD_SEQ(ret, ensr); - if (!popped && last_leave) { - ADD_INSN(ret, line, putnil); - } - } - ADD_LABEL(ret, lcont); - if (last_leave) ADD_INSN(ret, line, pop); - - erange = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->erange; - if (lstart->link.next != &lend->link) { - while (erange) { - ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end, - ensure, lcont); - erange = erange->next; - } - } - - ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enl.prev; + case NODE_ENSURE: + CHECK(compile_ensure(iseq, ret, node, popped)); break; - } case NODE_AND: case NODE_OR:{