遠藤です。

NODE_FOR の internal_id が VM::InstructionSequence#to_a で出力
されないため、to_a して load して eval すると変なことになります。

$ ./ruby -e '
VM::InstructionSequence.load(
  VM::InstructionSequence.compile(
    "for i in [1, 2, 3]; p i; end"
  ).to_a
).eval
'
-605544602
-605544602
-605544602

あんまり自信ないですが、パッチをつけます。
internal_id はバイトコード上で nil で表すようにしてみました。

ついでに、VM::InstructionSequence.load をコメントアウトではなく
マクロで無効化するのはどうでしょうか。CFLAGS だけで有効にできる
ので楽です。テストをしてくれる (地雷を踏んでくれる) 人が増える
かもしれません。


Index: iseq.c
===================================================================
--- iseq.c	(revision 17564)
+++ iseq.c	(working copy)
@@ -1034,11 +1034,11 @@
     /* locals */
     for (i=0; i<iseq->local_table_size; i++) {
 	ID lid = iseq->local_table[i];
-	if (lid) {
-	    if (rb_id2str(lid)) rb_ary_push(locals, ID2SYM(lid));
+	if (lid && rb_id2str(lid)) {
+	    rb_ary_push(locals, ID2SYM(lid));
 	}
 	else {
-	    rb_ary_push(locals, ID2SYM(rb_intern("#arg_rest")));
+	    rb_ary_push(locals, Qnil);
 	}
     }

@@ -1299,8 +1299,11 @@
     rb_define_method(rb_cISeq, "eval", iseq_eval, 0);

     /* disable this feature because there is no verifier. */
-    /* rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1); */
+#ifdef ANGEROUS_ISEQ_LOAD
+    rb_define_singleton_method(rb_cISeq, "load", iseq_s_load, -1);
+#else
     (void)iseq_s_load;
+#endif

     rb_define_singleton_method(rb_cISeq, "compile", iseq_s_compile, -1);
     rb_define_singleton_method(rb_cISeq, "new", iseq_s_compile, -1);
Index: compile.c
===================================================================
--- compile.c	(revision 17564)
+++ compile.c	(working copy)
@@ -4996,7 +4996,7 @@

     for (i=0; i<RARRAY_LEN(locals); i++) {
 	VALUE lv = RARRAY_PTR(locals)[i];
-	tbl[i] = FIXNUM_P(lv) ? FIX2INT(lv) : SYM2ID(CHECK_SYMBOL(lv));
+	tbl[i] = NIL_P(lv) ? 0 : SYM2ID(CHECK_SYMBOL(lv));
     }

     /* args */

-- 
Yusuke ENDOH <mame / tsg.ne.jp>