зеркало из https://github.com/github/ruby.git
Fix vm_getivar to handle module with TOO_COMPLEX shape
This commit is contained in:
Родитель
4c3cc25ea2
Коммит
0cb1fc3850
|
@ -275,6 +275,25 @@ class TestShapes < Test::Unit::TestCase
|
|||
end;
|
||||
end
|
||||
|
||||
def test_run_out_of_shape_for_module_ivar
|
||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||
begin;
|
||||
o = Object.new
|
||||
i = 0
|
||||
while RubyVM::Shape.shapes_available > 0
|
||||
o.instance_variable_set(:"@i#{i}", 1)
|
||||
i += 1
|
||||
end
|
||||
|
||||
module Foo
|
||||
@a = 1
|
||||
@b = 2
|
||||
assert_equal 1, @a
|
||||
assert_equal 2, @b
|
||||
end
|
||||
end;
|
||||
end
|
||||
|
||||
def test_run_out_of_shape_for_class_cvar
|
||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||
begin;
|
||||
|
|
|
@ -1289,7 +1289,27 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
|
|||
rb_shape_t *shape = rb_shape_get_shape_by_id(shape_id);
|
||||
|
||||
if (shape_id == OBJ_TOO_COMPLEX_SHAPE_ID) {
|
||||
if (!st_lookup(ROBJECT_IV_HASH(obj), id, &val)) {
|
||||
st_table *table = NULL;
|
||||
switch (BUILTIN_TYPE(obj)) {
|
||||
case T_CLASS:
|
||||
case T_MODULE:
|
||||
table = (st_table *)RCLASS_IVPTR(obj);
|
||||
break;
|
||||
|
||||
case T_OBJECT:
|
||||
table = ROBJECT_IV_HASH(obj);
|
||||
break;
|
||||
|
||||
default: {
|
||||
struct gen_ivtbl *ivtbl;
|
||||
if (rb_gen_ivtbl_get(obj, 0, &ivtbl)) {
|
||||
table = ivtbl->as.complex.table;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!table || !st_lookup(table, id, &val)) {
|
||||
val = default_value;
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче