diff options
| author | Jeremy Evans <code@jeremyevans.net> | 2024-01-12 08:58:39 -0800 |
|---|---|---|
| committer | Jeremy Evans <code@jeremyevans.net> | 2024-03-04 09:49:55 -0800 |
| commit | 5899f6aa55a02f211545d9cdaef4d86fa0b49528 (patch) | |
| tree | d7be5119394b86008bbcc7feaa008ff839deb687 | |
| parent | f7adee34a33c825eef40cf803ebb83f46ff8fc77 (diff) | |
Keep hidden local variables when dumping and loading iseqs
Fixes [Bug #19975]
| -rw-r--r-- | compile.c | 11 | ||||
| -rw-r--r-- | test/ruby/test_iseq.rb | 17 |
2 files changed, 27 insertions, 1 deletions
@@ -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; i<size; i++) { - table[i] = ibf_dump_id(dump, body->local_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|"<</#{i}/"}.join) assert_iseq_to_binary("@x ||= (1..2)") |
