Fix remove_instance_variable for too complex class

This commit is contained in:
Peter Zhu 2023-10-31 16:38:05 -04:00
parent b7a3e2e71d
commit 8889992b75
2 changed files with 24 additions and 2 deletions

View File

@ -233,7 +233,7 @@ class TestShapes < Test::Unit::TestCase
end;
end
def test_run_out_of_shape
def test_run_out_of_shape_for_object
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
class A
@ -252,6 +252,23 @@ class TestShapes < Test::Unit::TestCase
end;
end
def test_run_out_of_shape_for_class
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;
c = Class.new
i = 0
while RubyVM::Shape.shapes_available > 0
c.instance_variable_set(:"@i#{i}", 1)
i += 1
end
c.instance_variable_set(:@a, 1)
assert_equal(1, c.instance_variable_get(:@a))
c.remove_instance_variable(:@a)
assert_nil(c.instance_variable_get(:@a))
end;
end
def test_run_out_of_shape_generic_ivar_set
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
begin;

View File

@ -2198,7 +2198,12 @@ rb_obj_remove_instance_variable(VALUE obj, VALUE name)
case T_CLASS:
case T_MODULE:
IVAR_ACCESSOR_SHOULD_BE_MAIN_RACTOR(id);
rb_shape_transition_shape_remove_ivar(obj, id, shape, &val);
if (rb_shape_obj_too_complex(obj)) {
st_delete(RCLASS_IV_HASH(obj), (st_data_t *)&id, (st_data_t *)&val);
}
else {
rb_shape_transition_shape_remove_ivar(obj, id, shape, &val);
}
break;
case T_OBJECT: {
if (rb_shape_obj_too_complex(obj)) {