Handle SHAPE_TOO_COMPLEX in generic_ivar_set
This commit is contained in:
parent
4aacc559d9
commit
ac7f913ca3
@ -226,6 +226,26 @@ class TestShapes < Test::Unit::TestCase
|
||||
end;
|
||||
end
|
||||
|
||||
def test_run_out_of_shape_generic_ivar_set
|
||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||
begin;
|
||||
class TooComplex < Hash
|
||||
end
|
||||
|
||||
# Try to run out of shapes
|
||||
o = Object.new
|
||||
i = 0
|
||||
while RubyVM::Shape.shapes_available > 0
|
||||
o.instance_variable_set(:"@i#{i}", 1)
|
||||
i += 1
|
||||
end
|
||||
|
||||
tc = TooComplex.new
|
||||
tc.instance_variable_set(:@a, 1)
|
||||
tc.instance_variable_set(:@b, 2)
|
||||
end;
|
||||
end
|
||||
|
||||
def test_run_out_of_shape_rb_obj_copy_ivar
|
||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||
begin;
|
||||
|
@ -1484,6 +1484,11 @@ generic_ivar_set(VALUE obj, ID id, VALUE val)
|
||||
attr_index_t index;
|
||||
// The returned shape will have `id` in its iv_table
|
||||
rb_shape_t *shape = rb_shape_get_shape(obj);
|
||||
if (UNLIKELY(shape->type == SHAPE_OBJ_TOO_COMPLEX)) {
|
||||
rb_complex_ivar_set(obj, id, val);
|
||||
return;
|
||||
}
|
||||
|
||||
bool found = rb_shape_get_iv_index(shape, id, &index);
|
||||
rb_shape_t *next_shape = shape;
|
||||
if (!found) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user