aboutsummaryrefslogtreecommitdiffstats
path: root/variable.c
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-11-03 10:42:20 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-11-03 11:52:17 +0100
commit35da6f864a05624433be2c8059b87d30b899b370 (patch)
tree5e493a6b652a53923408e1f7feff514d08372259 /variable.c
parent1f1b9b0942ec12dde1af8000f8cb84692904fccc (diff)
downloadruby-35da6f864a05624433be2c8059b87d30b899b370.tar.gz
rb_ivar_defined: handle complex modules
It was assuming only objects can be complex.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/variable.c b/variable.c
index 27c10a27dd..6412819972 100644
--- a/variable.c
+++ b/variable.c
@@ -1809,7 +1809,27 @@ rb_ivar_defined(VALUE obj, ID id)
if (SPECIAL_CONST_P(obj)) return Qfalse;
if (rb_shape_obj_too_complex(obj)) {
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;
}