diff --git a/compile.c b/compile.c index 1336982d32..810e206adf 100644 --- a/compile.c +++ b/compile.c @@ -11863,6 +11863,10 @@ ibf_load_id(const struct ibf_load *load, const ID id_index) return 0; } VALUE sym = ibf_load_object(load, id_index); + if (rb_type_p(sym, T_FIXNUM)) { + /* Load hidden local variables as indexes */ + return FIX2INT(sym); + } return rb_sym2id(sym); } @@ -12386,7 +12390,12 @@ ibf_dump_local_table(struct ibf_dump *dump, const rb_iseq_t *iseq) int i; for (i=0; ilocal_table[i]); + VALUE v = ibf_dump_id(dump, body->local_table[i]); + if (v == 0) { + /* Dump hidden local variables as indexes, so load_from_binary will work with them */ + v = ibf_dump_object(dump, ULONG2NUM(size-i+1)); + } + table[i] = v; } IBF_W_ALIGN(ID); diff --git a/test/ruby/test_iseq.rb b/test/ruby/test_iseq.rb index 9b584c540c..ebb28af116 100644 --- a/test/ruby/test_iseq.rb +++ b/test/ruby/test_iseq.rb @@ -566,6 +566,23 @@ class TestISeq < Test::Unit::TestCase iseq2 end + def test_to_binary_with_hidden_local_variables + assert_iseq_to_binary("for foo in bar; end") + + bin = RubyVM::InstructionSequence.compile(<<-RUBY).to_binary + Object.new.instance_eval do + a = [] + def self.bar; [1] end + for foo in bar + a << (foo * 2) + end + a + end + RUBY + v = RubyVM::InstructionSequence.load_from_binary(bin).eval + assert_equal([2], v) + end + def test_to_binary_with_objects assert_iseq_to_binary("[]"+100.times.map{|i|"<