mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
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
This commit is contained in:
parent
a5beed9ff4
commit
e6f6c77d1d
3 changed files with 32 additions and 4 deletions
|
@ -1,3 +1,9 @@
|
|||
Sun Jan 10 20:57:25 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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]
|
||||
|
||||
Sun Jan 10 15:45:10 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* include/ruby/missing.h (explicit_bzero_by_memset_s): remove
|
||||
|
|
22
compile.c
22
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: {
|
||||
|
|
|
@ -758,4 +758,12 @@ class TestAssignmentGen < Test::Unit::TestCase
|
|||
o = bug9448.new
|
||||
assert_equal("ok", o['current'] = "ok")
|
||||
end
|
||||
|
||||
def test_massign_aref_lhs_splat
|
||||
bug11970 = '[ruby-core:72777] [Bug #11970]'
|
||||
h = {}
|
||||
k = [:key]
|
||||
h[*k], = ["ok", "ng"]
|
||||
assert_equal("ok", h[:key], bug11970)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue