From: Yusuke ENDOH Date: 2007-11-25T11:10:08+09:00 Subject: [ruby-dev:32354] a[*a]+=1 dumps core 遠藤と申します。 1.9 で以下を実行すると落ちます。 $ ./ruby -e 'a[*a]+=1' -- control frame ---------- c:0001 p:---- s:0001 b:-001 l:000000 d:000000 ------ --------------------------- -- backtrace of native function call (Use addr2line) -- 0x80e8065 0x8105bd3 0x8105c9b 0x8116a6d 0x8116a88 0x81106e4 0x811725e 0x80dc4e2 0x80dc5b6 0x8059ec4 0x805de00 0x8057be0 0xb7dd3ea8 0x8057b01 ------------------------------------------------------- [BUG] compile_array: This node is not NODE_ARRAY, but NODE_SPLAT ruby 1.9.0 (2007-11-23) [i686-linux] アボートしました ちゃんと setup_args するようにすればいいと思います。 おそらくこんな感じでしょうか。 Index: compile.c =================================================================== --- compile.c (revision 14010) +++ compile.c (working copy) @@ -3298,8 +3298,9 @@ break; } case NODE_OP_ASGN1:{ + unsigned long flag = 0; DECL_ANCHOR(args); - int argc; + VALUE argc; ID id = node->nd_mid; /* @@ -3324,11 +3325,15 @@ 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)); + if (nd_type(node->nd_args->nd_body) != NODE_ZARRAY) { + 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 @@ -3356,8 +3361,16 @@ COMPILE(ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head); - ADD_SEND(ret, nd_line(node), ID2SYM(idASET), - INT2FIX(argc + 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)); + } ADD_INSNL(ret, nd_line(node), jump, lfin); ADD_LABEL(ret, label); if (id == 0) { /* or */ @@ -3377,8 +3390,16 @@ 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)); + 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) { -- Yusuke ENDOH