rb_ivar_defined: handle complex modules
It was assuming only objects can be complex.
This commit is contained in:
parent
1f1b9b0942
commit
35da6f864a
@ -345,6 +345,45 @@ class TestShapes < Test::Unit::TestCase
|
|||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_run_out_of_shape_instance_variable_defined
|
||||||
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
class A
|
||||||
|
attr_reader :a, :b, :c, :d
|
||||||
|
def initialize
|
||||||
|
@a = @b = @c = @d = 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o = Object.new
|
||||||
|
i = 0
|
||||||
|
while RubyVM::Shape.shapes_available > 0
|
||||||
|
o.instance_variable_set(:"@i#{i}", 1)
|
||||||
|
i += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
a = A.new
|
||||||
|
assert_equal true, a.instance_variable_defined?(:@a)
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_run_out_of_shape_instance_variable_defined_on_module
|
||||||
|
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 A
|
||||||
|
@a = @b = @c = @d = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal true, A.instance_variable_defined?(:@a)
|
||||||
|
end;
|
||||||
|
end
|
||||||
def test_run_out_of_shape_remove_instance_variable
|
def test_run_out_of_shape_remove_instance_variable
|
||||||
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
begin;
|
begin;
|
||||||
|
22
variable.c
22
variable.c
@ -1809,7 +1809,27 @@ rb_ivar_defined(VALUE obj, ID id)
|
|||||||
if (SPECIAL_CONST_P(obj)) return Qfalse;
|
if (SPECIAL_CONST_P(obj)) return Qfalse;
|
||||||
if (rb_shape_obj_too_complex(obj)) {
|
if (rb_shape_obj_too_complex(obj)) {
|
||||||
VALUE idx;
|
VALUE idx;
|
||||||
if (!rb_st_lookup(ROBJECT_IV_HASH(obj), id, &idx)) {
|
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 || !rb_st_lookup(table, id, &idx)) {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user