summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authoryui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-31 00:46:30 +0000
committeryui-knk <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-31 00:46:30 +0000
commita09e1750682ee19b21c5785f34f3db39e15a2f2e (patch)
treee4a888d5da822653a45addc4a319684c9d46e543 /compile.c
parentbb88b1aab8ce5aad01e11f1dbd574ab46ac44648 (diff)
Use NODE_CASE2 if case expressions don't exist
When NODE_WHEN is compiled by iseq_compile_each0, the node passed to compile_when is NODE_WHEN (not NODE_CASE). So we can not handle the location of NODE_CASE of case statements which don't have case expressions. e.g. : ``` case; when 1; foo; when 2; bar; else baz; end ``` This commit adds NODE_CASE2, and compiles it by iseq_compile_each0. * compile.c (compile_case): Does not call COMPILE_ when NODE_CASE does not have case expressions. * compile.c (compile_case2): Compile NODE_CASE2 by compile_case2. * compile.c (compile_when): Delete an obsoleted function. * compile.c (iseq_compile_each0): Compile NODE_CASE2. * ext/objspace/objspace.c (count_nodes): Add NODE_CASE2 case. * node.c (dump_node, rb_gc_mark_node): Add NODE_CASE2 case. * node.h (node_type): Add NODE_CASE2. * node.h (NEW_CASE2): Add a macro which generates NODE_CASE2. * parse.y: Generate NODE_CASE2 if case expressions don't exist. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60585 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/compile.c b/compile.c
index b0a67e49ce..c5d079c904 100644
--- a/compile.c
+++ b/compile.c
@@ -4406,10 +4406,6 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
rb_hash_tbl_raw(literals)->type = &cdhash_type;
- if (node->nd_head == 0) {
- CHECK(COMPILE_(ret, "when", node->nd_body, popped));
- return COMPILE_OK;
- }
CHECK(COMPILE(head, "case base", node->nd_head));
DECL_BRANCH_BASE(branches, nd_lineno(node), nd_column(node), "case");
@@ -4506,26 +4502,27 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
}
static int
-compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
+compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_node, int popped)
{
const NODE *vals;
const NODE *val;
- const NODE *node = orig_node;
+ const NODE *node = orig_node->nd_body;
LABEL *endlabel;
DECL_ANCHOR(body_seq);
VALUE branches = 0;
- DECL_BRANCH_BASE(branches, nd_line(node), nd_column(node), "case");
+ DECL_BRANCH_BASE(branches, nd_lineno(orig_node), nd_column(orig_node), "case");
INIT_ANCHOR(body_seq);
endlabel = NEW_LABEL(nd_line(node));
while (node && nd_type(node) == NODE_WHEN) {
const int line = nd_line(node);
+ const int lineno = nd_lineno(node);
const int column = nd_column(node);
LABEL *l1 = NEW_LABEL(line);
ADD_LABEL(body_seq, l1);
- ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_line(node->nd_body) : line, node->nd_body ? nd_column(node->nd_body) : column, "when", branches);
+ ADD_TRACE_BRANCH_COVERAGE(body_seq, node->nd_body ? nd_lineno(node->nd_body) : lineno, node->nd_body ? nd_column(node->nd_body) : column, "when", branches);
CHECK(COMPILE_(body_seq, "when", node->nd_body, popped));
ADD_INSNL(body_seq, line, jump, endlabel);
@@ -4557,7 +4554,7 @@ compile_when(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
node = node->nd_next;
}
/* else */
- ADD_TRACE_BRANCH_COVERAGE(ret, node ? nd_line(node) : nd_line(orig_node), node ? nd_column(node) : nd_column(orig_node), "else", branches);
+ ADD_TRACE_BRANCH_COVERAGE(ret, node ? nd_lineno(node) : nd_lineno(orig_node), node ? nd_column(node) : nd_column(orig_node), "else", branches);
CHECK(COMPILE_(ret, "else", node, popped));
ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
@@ -5169,8 +5166,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, in
case NODE_CASE:
CHECK(compile_case(iseq, ret, node, popped));
break;
- case NODE_WHEN:
- CHECK(compile_when(iseq, ret, node, popped));
+ case NODE_CASE2:
+ CHECK(compile_case2(iseq, ret, node, popped));
break;
case NODE_WHILE:
case NODE_UNTIL: