From e6f6c77d1dc368e240dcb6b827e9e868efb6c06f Mon Sep 17 00:00:00 2001 From: nobu Date: Sun, 10 Jan 2016 11:57:51 +0000 Subject: 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 --- compile.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'compile.c') 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: { -- cgit v1.2.3