ruby-changes:48471
From: yui-knk <ko1@a...>
Date: Tue, 31 Oct 2017 09:46:37 +0900 (JST)
Subject: [ruby-changes:48471] yui-knk:r60585 (trunk): Use NODE_CASE2 if case expressions don't exist
yui-knk 2017-10-31 09:46:30 +0900 (Tue, 31 Oct 2017) New Revision: 60585 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60585 Log: 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. Modified files: trunk/compile.c trunk/ext/objspace/objspace.c trunk/node.c trunk/node.h trunk/parse.y Index: parse.y =================================================================== --- parse.y (revision 60584) +++ parse.y (revision 60585) @@ -2866,7 +2866,7 @@ primary : literal https://github.com/ruby/ruby/blob/trunk/parse.y#L2866 | k_case opt_terms case_body k_end { /*%%%*/ - $$ = NEW_CASE(0, $3); + $$ = NEW_CASE2(0, $3); nd_set_line($3, $<num>1); nd_set_lineno($$, @1.first_line); nd_set_column($$, @1.first_column); Index: ext/objspace/objspace.c =================================================================== --- ext/objspace/objspace.c (revision 60584) +++ ext/objspace/objspace.c (revision 60585) @@ -376,6 +376,7 @@ count_nodes(int argc, VALUE *argv, VALUE https://github.com/ruby/ruby/blob/trunk/ext/objspace/objspace.c#L376 COUNT_NODE(NODE_IF); COUNT_NODE(NODE_UNLESS); COUNT_NODE(NODE_CASE); + COUNT_NODE(NODE_CASE2); COUNT_NODE(NODE_WHEN); COUNT_NODE(NODE_WHILE); COUNT_NODE(NODE_UNTIL); Index: node.c =================================================================== --- node.c (revision 60584) +++ node.c (revision 60585) @@ -219,6 +219,14 @@ dump_node(VALUE buf, VALUE indent, int c https://github.com/ruby/ruby/blob/trunk/node.c#L219 LAST_NODE; F_NODE(nd_body, "when clauses"); return; + case NODE_CASE2: + ANN("case statement"); + ANN("format: case; [nd_body]; end"); + ANN("example: case; when 1; foo; when 2; bar; else baz; end"); + F_NODE(nd_head, "case expr"); + LAST_NODE; + F_NODE(nd_body, "when clauses"); + return; case NODE_WHEN: ANN("if statement"); @@ -1125,6 +1133,7 @@ rb_gc_mark_node(NODE *obj) https://github.com/ruby/ruby/blob/trunk/node.c#L1133 case NODE_AND: case NODE_OR: case NODE_CASE: + case NODE_CASE2: case NODE_SCLASS: case NODE_DOT2: case NODE_DOT3: Index: compile.c =================================================================== --- compile.c (revision 60584) +++ compile.c (revision 60585) @@ -4406,10 +4406,6 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4406 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_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4502 } 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_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L4554 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 https://github.com/ruby/ruby/blob/trunk/compile.c#L5166 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: Index: node.h =================================================================== --- node.h (revision 60584) +++ node.h (revision 60585) @@ -30,6 +30,8 @@ enum node_type { https://github.com/ruby/ruby/blob/trunk/node.h#L30 #define NODE_UNLESS NODE_UNLESS NODE_CASE, #define NODE_CASE NODE_CASE + NODE_CASE2, +#define NODE_CASE2 NODE_CASE2 NODE_WHEN, #define NODE_WHEN NODE_WHEN NODE_WHILE, @@ -355,6 +357,7 @@ typedef struct RNode { https://github.com/ruby/ruby/blob/trunk/node.h#L357 #define NEW_IF(c,t,e) NEW_NODE(NODE_IF,c,t,e) #define NEW_UNLESS(c,t,e) NEW_NODE(NODE_UNLESS,c,t,e) #define NEW_CASE(h,b) NEW_NODE(NODE_CASE,h,b,0) +#define NEW_CASE2(h,b) NEW_NODE(NODE_CASE2,h,b,0) #define NEW_WHEN(c,t,e) NEW_NODE(NODE_WHEN,c,t,e) #define NEW_WHILE(c,b,n) NEW_NODE(NODE_WHILE,c,b,n) #define NEW_UNTIL(c,b,n) NEW_NODE(NODE_UNTIL,c,b,n) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/