Project

General

Profile

Actions

Bug #19975

closed

ISeq#to_binary loses hidden local variable indices

Added by kddnewton (Kevin Newton) 6 months ago. Updated about 2 months ago.

Status:
Closed
Assignee:
-
Target version:
-
[ruby-core:115181]

Description

When you call RubyVM::InstructionSequence#to_a, you get hidden local variables as the index in the stack from the top:

if (rb_id2str(lid)) {
    rb_ary_push(locals, ID2SYM(lid));
}
else { /* hidden variable from id_internal() */
    rb_ary_push(locals, ULONG2NUM(iseq_body->local_table_size-i+1));
}
RubyVM::InstructionSequence.compile("for foo in bar; end").to_a[13][4][2][10]
# => [2]

When you call RubyVM::InstructionSequence#to_binary, it dumps hidden local variables as 0:

if (id == 0 || rb_id2name(id) == NULL) {
    return 0;
}
return ibf_dump_object(dump, rb_id2sym(id));

When it reads that back in and then you call to_a, you get :#arg_rest:

RubyVM::InstructionSequence.load_from_binary(RubyVM::InstructionSequence.compile("for foo in bar; end").to_binary).to_a[13][4][2][10]
# => [:"#arg_rest"]

This means you end up not being able to consistently look at the locals. Instead, when reading back in from binary it could replace it with the index so that it matches up with the value before it is dumped to binary. Could we do that so that #to_a is consistent no matter where the iseq came from?

Updated by jeremyevans0 (Jeremy Evans) 4 months ago

I submitted a pull request to fix this: https://github.com/ruby/ruby/pull/9512

Actions #2

Updated by jeremyevans (Jeremy Evans) about 2 months ago

  • Status changed from Open to Closed

Applied in changeset git|5899f6aa55a02f211545d9cdaef4d86fa0b49528.


Keep hidden local variables when dumping and loading iseqs

Fixes [Bug #19975]

Actions

Also available in: Atom PDF

Like1
Like0Like0