aboutsummaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-01-10 11:57:51 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2016-01-10 11:57:51 +0000
commite6f6c77d1dc368e240dcb6b827e9e868efb6c06f (patch)
tree5d2f68fa1a4f53f5b09803b1dfe7cb063ec232f2 /compile.c
parenta5beed9ff467be394afc4957f0c9b12765c81743 (diff)
downloadruby-e6f6c77d1dc368e240dcb6b827e9e868efb6c06f.tar.gz
compile.c: fix lhs splat in massign
* compile.c (compile_massign_lhs): when index ends with splat, append rhs value to it like POSTARG, since VM_CALL_ARGS_SPLAT splats the last argument only. [ruby-core:72777] [Bug #11970] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/compile.c b/compile.c
index 1ac2fbb15d..85372ae696 100644
--- a/compile.c
+++ b/compile.c
@@ -192,11 +192,20 @@ r_value(VALUE value)
#define ADD_INSN(seq, line, insn) \
ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
+/* insert an instruction before prev */
+#define INSERT_BEFORE_INSN(prev, line, insn) \
+ INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
+
/* add an instruction with some operands (1, 2, 3, 5) */
#define ADD_INSN1(seq, line, insn, op1) \
ADD_ELEM((seq), (LINK_ELEMENT *) \
new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
+/* insert an instruction with some operands (1, 2, 3, 5) before prev */
+#define INSERT_BEFORE_INSN1(prev, line, insn, op1) \
+ INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) \
+ new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
+
#define LABEL_REF(label) ((label)->refcnt++)
/* add an instruction with label operand (alias of ADD_INSN1) */
@@ -2990,9 +2999,10 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node)
{
switch (nd_type(node)) {
case NODE_ATTRASGN: {
- INSN *iobj, *topdup;
+ INSN *iobj;
struct rb_call_info *ci;
VALUE dupidx;
+ int line = nd_line(node);
COMPILE_POPED(ret, "masgn lhs (NODE_ATTRASGN)", node);
@@ -3001,9 +3011,13 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node)
ci->orig_argc += 1;
dupidx = INT2FIX(ci->orig_argc);
- topdup = new_insn_body(iseq, nd_line(node), BIN(topn), 1, dupidx);
- INSERT_ELEM_PREV(&iobj->link, &topdup->link);
- ADD_INSN(ret, nd_line(node), pop); /* result */
+ INSERT_BEFORE_INSN1(iobj, line, topn, dupidx);
+ if (ci->flag & VM_CALL_ARGS_SPLAT) {
+ --ci->orig_argc;
+ INSERT_BEFORE_INSN1(iobj, line, newarray, INT2FIX(1));
+ INSERT_BEFORE_INSN(iobj, line, concatarray);
+ }
+ ADD_INSN(ret, line, pop); /* result */
break;
}
case NODE_MASGN: {