summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shape.c8
-rw-r--r--test/ruby/test_shapes.rb30
2 files changed, 36 insertions, 2 deletions
diff --git a/shape.c b/shape.c
index e402344615..4510c618d4 100644
--- a/shape.c
+++ b/shape.c
@@ -583,12 +583,16 @@ remove_shape_recursive(VALUE obj, ID id, rb_shape_t * shape, VALUE * removed)
// We found a new parent. Create a child of the new parent that
// has the same attributes as this shape.
if (new_parent) {
- bool dont_care;
- rb_shape_t * new_child = get_next_shape_internal(new_parent, shape->edge_name, shape->type, &dont_care, true);
if (UNLIKELY(new_parent->type == SHAPE_OBJ_TOO_COMPLEX)) {
return new_parent;
}
+ bool dont_care;
+ rb_shape_t * new_child = get_next_shape_internal(new_parent, shape->edge_name, shape->type, &dont_care, true);
+ if (UNLIKELY(new_child->type == SHAPE_OBJ_TOO_COMPLEX)) {
+ return new_child;
+ }
+
new_child->capacity = shape->capacity;
if (new_child->type == SHAPE_IVAR) {
move_iv(obj, id, shape->next_iv_index - 1, new_child->next_iv_index - 1);
diff --git a/test/ruby/test_shapes.rb b/test/ruby/test_shapes.rb
index b052a4a647..b627b58281 100644
--- a/test/ruby/test_shapes.rb
+++ b/test/ruby/test_shapes.rb
@@ -577,6 +577,36 @@ class TestShapes < Test::Unit::TestCase
assert_equal [0, 1, nil, 3, 4], ivars
end
+ def test_remove_instance_variable_when_out_of_shapes
+ assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ ivars_count = 5
+ object = Object.new
+ ivars_count.times do |i|
+ object.instance_variable_set("@ivar_#{i}", i)
+ end
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, 2, 3, 4], ivars
+
+ o = Object.new
+ i = 0
+ while RubyVM::Shape.shapes_available > 0
+ o.instance_variable_set(:"@i#{i}", 1)
+ i += 1
+ end
+
+ object.remove_instance_variable(:@ivar_2)
+
+ ivars = ivars_count.times.map do |i|
+ object.instance_variable_get("@ivar_#{i}")
+ end
+ assert_equal [0, 1, nil, 3, 4], ivars
+ end;
+ end
+
def test_freeze_after_complex
ensure_complex