diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-22 05:01:32 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2016-04-22 05:01:32 +0000 |
commit | 01828cf45ab6d002b2d9f2907581db5e841cb57f (patch) | |
tree | 09daaad900fb9b2839c2c0b1254342762b4e10ed | |
parent | 8f93c59ecab7b7279a78324db869f1cac78319d9 (diff) |
merge revision(s) 53495: [Backport #11970]
* 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/branches/ruby_2_2@54671 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | compile.c | 46 | ||||
-rw-r--r-- | test/ruby/test_assignment.rb | 8 | ||||
-rw-r--r-- | version.h | 8 |
4 files changed, 57 insertions, 11 deletions
@@ -1,3 +1,9 @@ +Fri Apr 22 13:41:38 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] + Thu Mar 31 05:06:02 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> * sprintf.c (rb_str_format): fix buffer overflow, length must be @@ -187,11 +187,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))) + /* add an instruction with label operand (alias of ADD_INSN1) */ #define ADD_INSNL(seq, line, insn, label) ADD_INSN1(seq, line, insn, label) @@ -737,6 +746,20 @@ compile_data_alloc_adjust(rb_iseq_t *iseq) } /* + * elem1, elemX => elemX, elem2, elem1 + */ +static void +INSERT_ELEM_PREV(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2) +{ + elem2->prev = elem1->prev; + elem2->next = elem1; + elem1->prev = elem2; + if (elem2->prev) { + elem2->prev->next = elem2; + } +} + +/* * elem1, elemX => elem1, elem2, elemX */ static void @@ -782,6 +805,12 @@ FIRST_ELEMENT(LINK_ANCHOR *anchor) } static LINK_ELEMENT * +LAST_ELEMENT(LINK_ANCHOR *anchor) +{ + return anchor->last; +} + +static LINK_ELEMENT * POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor) { LINK_ELEMENT *elem = anchor->last; @@ -2663,19 +2692,22 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) INSN *iobj; rb_call_info_t *ci; VALUE dupidx; + int line = nd_line(node); COMPILE_POPED(ret, "masgn lhs (NODE_ATTRASGN)", node); - POP_ELEMENT(ret); /* pop pop insn */ - iobj = (INSN *)POP_ELEMENT(ret); /* pop send insn */ + iobj = (INSN *)get_prev_insn((INSN *)LAST_ELEMENT(ret)); /* send insn */ ci = (rb_call_info_t *)iobj->operands[0]; - ci->orig_argc += 1; ci->argc = ci->orig_argc; + ci->orig_argc += 1; dupidx = INT2FIX(ci->orig_argc); - ADD_INSN1(ret, nd_line(node), topn, dupidx); - ADD_ELEM(ret, (LINK_ELEMENT *)iobj); - ADD_INSN(ret, nd_line(node), pop); /* result */ - ADD_INSN(ret, nd_line(node), pop); /* rhs */ + 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: { diff --git a/test/ruby/test_assignment.rb b/test/ruby/test_assignment.rb index 9c0fd48725..81ae3b0d25 100644 --- a/test/ruby/test_assignment.rb +++ b/test/ruby/test_assignment.rb @@ -757,4 +757,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 @@ -1,10 +1,10 @@ #define RUBY_VERSION "2.2.5" -#define RUBY_RELEASE_DATE "2016-03-31" -#define RUBY_PATCHLEVEL 292 +#define RUBY_RELEASE_DATE "2016-04-22" +#define RUBY_PATCHLEVEL 293 #define RUBY_RELEASE_YEAR 2016 -#define RUBY_RELEASE_MONTH 3 -#define RUBY_RELEASE_DAY 31 +#define RUBY_RELEASE_MONTH 4 +#define RUBY_RELEASE_DAY 22 #include "ruby/version.h" |