Skip to content

Commit af2e98a

Browse files
committed
Optimization for case when with splat operator
[Fix rubyGH-1928] [Feature ruby#14984] From: chopraanmol1 <[email protected]> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64318 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent 4fe8308 commit af2e98a

File tree

1 file changed

+42
-4
lines changed

1 file changed

+42
-4
lines changed

compile.c

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4077,6 +4077,47 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
40774077
return only_special_literals;
40784078
}
40794079

4080+
static int
4081+
when_splat_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals,
4082+
LABEL *l1, int only_special_literals, VALUE literals)
4083+
{
4084+
const int line = nd_line(vals);
4085+
4086+
switch (nd_type(vals)) {
4087+
case NODE_ARRAY:
4088+
if (when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals) < 0)
4089+
return COMPILE_NG;
4090+
break;
4091+
case NODE_SPLAT:
4092+
ADD_INSN (cond_seq, line, dup);
4093+
CHECK(COMPILE(cond_seq, "when splat", vals->nd_head));
4094+
ADD_INSN1(cond_seq, line, splatarray, Qfalse);
4095+
ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
4096+
ADD_INSNL(cond_seq, line, branchif, l1);
4097+
break;
4098+
case NODE_ARGSCAT:
4099+
CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
4100+
CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals));
4101+
break;
4102+
case NODE_ARGSPUSH:
4103+
CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
4104+
ADD_INSN (cond_seq, line, dup);
4105+
CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body));
4106+
ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE));
4107+
ADD_INSNL(cond_seq, line, branchif, l1);
4108+
break;
4109+
default:
4110+
ADD_INSN (cond_seq, line, dup);
4111+
CHECK(COMPILE(cond_seq, "when val", vals));
4112+
ADD_INSN1(cond_seq, line, splatarray, Qfalse);
4113+
ADD_INSN1(cond_seq, line, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
4114+
ADD_INSNL(cond_seq, line, branchif, l1);
4115+
break;
4116+
}
4117+
return COMPILE_OK;
4118+
}
4119+
4120+
40804121
static int
40814122
compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node)
40824123
{
@@ -4996,10 +5037,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod
49965037
case NODE_ARGSCAT:
49975038
case NODE_ARGSPUSH:
49985039
only_special_literals = 0;
4999-
ADD_INSN (cond_seq, nd_line(vals), dup);
5000-
CHECK(COMPILE(cond_seq, "when/cond splat", vals));
5001-
ADD_INSN1(cond_seq, nd_line(vals), checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY));
5002-
ADD_INSNL(cond_seq, nd_line(vals), branchif, l1);
5040+
CHECK(when_splat_vals(iseq, cond_seq, vals, l1, only_special_literals, literals));
50035041
break;
50045042
default:
50055043
UNKNOWN_NODE("NODE_CASE", vals, COMPILE_NG);

0 commit comments

Comments
 (0)