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