[前][次][番号順一覧][スレッド一覧]

ruby-changes:41422

From: nobu <ko1@a...>
Date: Sun, 10 Jan 2016 20:57:32 +0900 (JST)
Subject: [ruby-changes:41422] nobu:r53495 (trunk): compile.c: fix lhs splat in massign

nobu	2016-01-10 20:57:51 +0900 (Sun, 10 Jan 2016)

  New Revision: 53495

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53495

  Log:
    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]

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/test/ruby/test_assignment.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53494)
+++ ChangeLog	(revision 53495)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Sun Jan 10 20:57:25 2016  Nobuyoshi Nakada  <nobu@r...>
+
+	* 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@r...>
 
 	* include/ruby/missing.h (explicit_bzero_by_memset_s): remove
Index: compile.c
===================================================================
--- compile.c	(revision 53494)
+++ compile.c	(revision 53495)
@@ -192,11 +192,20 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/compile.c#L192
 #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, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L2999
 {
     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, LIN https://github.com/ruby/ruby/blob/trunk/compile.c#L3011
 	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: {
Index: test/ruby/test_assignment.rb
===================================================================
--- test/ruby/test_assignment.rb	(revision 53494)
+++ test/ruby/test_assignment.rb	(revision 53495)
@@ -758,4 +758,12 @@ class TestAssignmentGen < Test::Unit::Te https://github.com/ruby/ruby/blob/trunk/test/ruby/test_assignment.rb#L758
     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

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]