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

ruby-changes:2541

From: ko1@a...
Date: 27 Nov 2007 15:45:41 +0900
Subject: [ruby-changes:2541] ko1 - Ruby:r14032 (trunk): * compile.c (iseq_compile_each): "a[*b] += 1" dumps core.

ko1	2007-11-27 15:45:01 +0900 (Tue, 27 Nov 2007)

  New Revision: 14032

  Modified files:
    trunk/ChangeLog
    trunk/bootstraptest/test_syntax.rb
    trunk/compile.c

  Log:
    * compile.c (iseq_compile_each): "a[*b] += 1" dumps core.
      a patch from Yusuke ENDOH <mame AT tsg.ne.jp>.  [ruby-dev:32354]
    * bootstraptest/test_syntax.rb: add a test for above.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/compile.c?r1=14032&r2=14031
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14032&r2=14031
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_syntax.rb?r1=14032&r2=14031

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 14031)
+++ ChangeLog	(revision 14032)
@@ -1,3 +1,10 @@
+Tue Nov 27 15:40:05 2007  Koichi Sasada  <ko1@a...>
+
+	* compile.c (iseq_compile_each): "a[*b] += 1" dumps core.
+	  a patch from Yusuke ENDOH <mame AT tsg.ne.jp>.  [ruby-dev:32354]
+
+	* bootstraptest/test_syntax.rb: add a test for above.
+
 Tue Nov 27 12:47:23 2007  Koichi Sasada  <ko1@a...>
 
 	* compile.c, insns.def: change return value of "defined?"
Index: bootstraptest/test_syntax.rb
===================================================================
--- bootstraptest/test_syntax.rb	(revision 14031)
+++ bootstraptest/test_syntax.rb	(revision 14032)
@@ -608,3 +608,7 @@
          p(1, (redo; 2))
        end)
 }
+assert_equal '1', %q{
+  a = [0]
+  a[*a]+=1
+}
Index: compile.c
===================================================================
--- compile.c	(revision 14031)
+++ compile.c	(revision 14032)
@@ -3299,41 +3299,46 @@
 		  ID2SYM(node->nd_vid));
 	break;
       }
-      case NODE_OP_ASGN1:{
-	DECL_ANCHOR(args);
-	int argc;
-	ID id = node->nd_mid;
+      case NODE_OP_ASGN1: {
+	  DECL_ANCHOR(args);
+	  VALUE argc;
+	  unsigned long flag = 0;
+	  ID id = node->nd_mid;
 
-	/*
-	 * a[x] (op)= y
-	 *
-	 * eval a    # a
-	 * eval x    # a x
-	 * dupn 2    # a x a x
-	 * send :[]  # a x a[x]
-	 * eval y    # a x a[x] y
-	 * send op   # a x a[x]+y
-	 * send []=  # ret
-	 */
+	  /*
+	   * a[x] (op)= y
+	   *
+	   * eval a    # a
+	   * eval x    # a x
+	   * dupn 2    # a x a x
+	   * send :[]  # a x a[x]
+	   * eval y    # a x a[x] y
+	   * send op   # a x a[x]+y
+	   * send []=  # ret
+	   */
 
-	/*
-	 * nd_recv[nd_args->nd_body] (nd_mid)= nd_args->nd_head;
-	 * NODE_OP_ASGN nd_recv
-	 *              nd_args->nd_head
-	 *              nd_args->nd_body
-	 *              nd_mid
-	 */
+	  /*
+	   * nd_recv[nd_args->nd_body] (nd_mid)= nd_args->nd_head;
+	   * NODE_OP_ASGN nd_recv
+	   *              nd_args->nd_head
+	   *              nd_args->nd_body
+	   *              nd_mid
+	   */
 
-	INIT_ANCHOR(args);
-	COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
-	argc = compile_array(iseq, args, node->nd_args->nd_body, Qfalse);
-	POP_ELEMENT(args);
-	ADD_SEQ(ret, args);
-	ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(argc+1));
-	ADD_SEND(ret, nd_line(node), ID2SYM(idAREF), INT2FIX(argc));
+	  COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
+	  if (nd_type(node->nd_args->nd_body) != NODE_ZARRAY) {
+	      INIT_ANCHOR(args);
+	      argc = setup_args(iseq, args, node->nd_args->nd_body, &flag);
+	      ADD_SEQ(ret, args);
+	  }
+	  else {
+	      argc = FIX2INT(0);
+	  }
+	  ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(FIX2INT(argc)+1));
+	  ADD_SEND_R(ret, nd_line(node), ID2SYM(idAREF), argc, Qfalse, LONG2FIX(flag));
 
-	if (id == 0 || id == 1) {
-	    /* 0: or, 1: and
+	  if (id == 0 || id == 1) {
+	      /* 0: or, 1: and
 	       a[x] ||= y
 
 	       unless/if a[x]
@@ -3341,53 +3346,67 @@
 	       else
 	       nil
 	       end
-	    */
-	    LABEL *label = NEW_LABEL(nd_line(node));
-	    LABEL *lfin = NEW_LABEL(nd_line(node));
+	       */
+	      LABEL *label = NEW_LABEL(nd_line(node));
+	      LABEL *lfin = NEW_LABEL(nd_line(node));
 
-	    if (id == 0) {
-		/* or */
-		ADD_INSN(ret, nd_line(node), dup);
-		ADD_INSNL(ret, nd_line(node), branchif, label);
-		ADD_INSN(ret, nd_line(node), pop);
-	    }
-	    else {
-		/* and */
-		ADD_INSNL(ret, nd_line(node), branchunless, label);
-	    }
+	      if (id == 0) {
+		  /* or */
+		  ADD_INSN(ret, nd_line(node), dup);
+		  ADD_INSNL(ret, nd_line(node), branchif, label);
+		  ADD_INSN(ret, nd_line(node), pop);
+	      }
+	      else {
+		  /* and */
+		  ADD_INSNL(ret, nd_line(node), branchunless, label);
+	      }
 
-	    COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
-		    node->nd_args->nd_head);
-	    ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
-		     INT2FIX(argc + 1));
-	    ADD_INSNL(ret, nd_line(node), jump, lfin);
-	    ADD_LABEL(ret, label);
-	    if (id == 0) {	/* or */
-		ADD_INSN(ret, nd_line(node), swap);
-		ADD_INSN(ret, nd_line(node), pop);
-		ADD_INSN(ret, nd_line(node), swap);
-		ADD_INSN(ret, nd_line(node), pop);
-	    }
-	    else if (id == 1) {	/* and */
-		ADD_INSN(ret, nd_line(node), pop);
-		ADD_INSN(ret, nd_line(node), pop);
-		ADD_INSN(ret, nd_line(node), putnil);
-	    }
-	    ADD_LABEL(ret, lfin);
-	}
-	else {
-	    COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
-		    node->nd_args->nd_head);
-	    ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
-	    ADD_SEND(ret, nd_line(node), ID2SYM(idASET),
-		     INT2FIX(argc + 1));
-	}
+	      COMPILE(ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
+	      if (flag & VM_CALL_ARGS_SPLAT_BIT) {
+		  ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
+		  ADD_INSN(ret, nd_line(node), concatarray);
+		  ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
+			     argc, Qfalse, LONG2FIX(flag));
+	      }
+	      else {
+		  ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
+			     INT2FIX(FIX2INT(argc) + 1), Qfalse, LONG2FIX(flag));
+	      }
+	      ADD_INSNL(ret, nd_line(node), jump, lfin);
+	      ADD_LABEL(ret, label);
+	      if (id == 0) {	/* or */
+		  ADD_INSN(ret, nd_line(node), swap);
+		  ADD_INSN(ret, nd_line(node), pop);
+		  ADD_INSN(ret, nd_line(node), swap);
+		  ADD_INSN(ret, nd_line(node), pop);
+	      }
+	      else if (id == 1) {	/* and */
+		  ADD_INSN(ret, nd_line(node), pop);
+		  ADD_INSN(ret, nd_line(node), pop);
+		  ADD_INSN(ret, nd_line(node), putnil);
+	      }
+	      ADD_LABEL(ret, lfin);
+	  }
+	  else {
+	      COMPILE(ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
+	      ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
+	      if (flag & VM_CALL_ARGS_SPLAT_BIT) {
+		  ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
+		  ADD_INSN(ret, nd_line(node), concatarray);
+		  ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
+			     argc, Qfalse, LONG2FIX(flag));
+	      }
+	      else {
+		  ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
+			     INT2FIX(FIX2INT(argc) + 1), Qfalse, LONG2FIX(flag));
+	      }
+	  }
 
-	if (poped) {
-	    ADD_INSN(ret, nd_line(node), pop);
-	}
+	  if (poped) {
+	      ADD_INSN(ret, nd_line(node), pop);
+	  }
 
-	break;
+	  break;
       }
       case NODE_OP_ASGN2:{
 	ID atype = node->nd_next->nd_mid;
@@ -3663,7 +3682,7 @@
 			for (j=0; j<post_len; j++) {
 			    int idx = liseq->local_size - (post_start + j);
 			    ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
-		    }
+			}
 			ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
 			ADD_INSN (args, nd_line(node), concatarray);
 			/* argc is setteled at above */

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

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