ruby-changes:52110
From: nobu <ko1@a...>
Date: Sun, 12 Aug 2018 17:11:00 +0900 (JST)
Subject: [ruby-changes:52110] nobu:r64318 (trunk): Optimization for case when with splat operator
nobu 2018-08-12 17:10:53 +0900 (Sun, 12 Aug 2018) New Revision: 64318 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64318 Log: Optimization for case when with splat operator [Fix GH-1928] [Feature #14984] From: chopraanmol1 <chopraanmol1@g...> Modified files: trunk/compile.c Index: compile.c =================================================================== --- compile.c (revision 64317) +++ compile.c (revision 64318) @@ -4078,6 +4078,47 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR * https://github.com/ruby/ruby/blob/trunk/compile.c#L4078 } static int +when_splat_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, + LABEL *l1, int only_special_literals, VALUE literals) +{ + const int line = nd_line(vals); + + switch (nd_type(vals)) { + case NODE_ARRAY: + if (when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals) < 0) + return COMPILE_NG; + break; + case NODE_SPLAT: + ADD_INSN (cond_seq, line, dup); + CHECK(COMPILE(cond_seq, "when splat", vals->nd_head)); + ADD_INSN1(cond_seq, line, splatarray, Qfalse); + ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); + ADD_INSNL(cond_seq, line, branchif, l1); + break; + case NODE_ARGSCAT: + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals)); + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals)); + break; + case NODE_ARGSPUSH: + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals)); + ADD_INSN (cond_seq, line, dup); + CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body)); + ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE)); + ADD_INSNL(cond_seq, line, branchif, l1); + break; + default: + ADD_INSN (cond_seq, line, dup); + CHECK(COMPILE(cond_seq, "when val", vals)); + ADD_INSN1(cond_seq, line, splatarray, Qfalse); + ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); + ADD_INSNL(cond_seq, line, branchif, l1); + break; + } + return COMPILE_OK; +} + + +static int compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) { switch (nd_type(node)) { @@ -4996,10 +5037,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHO https://github.com/ruby/ruby/blob/trunk/compile.c#L5037 case NODE_ARGSCAT: case NODE_ARGSPUSH: only_special_literals = 0; - ADD_INSN (cond_seq, nd_line(vals), dup); - CHECK(COMPILE(cond_seq, "when/cond splat", vals)); - ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); - ADD_INSNL(cond_seq, nd_line(vals), branchif, l1); + CHECK(when_splat_vals(iseq, cond_seq, vals, l1, only_special_literals, literals)); break; default: UNKNOWN_NODE("NODE_CASE", vals, COMPILE_NG); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/