diff options
author | Jean Boussier <byroot@ruby-lang.org> | 2023-11-03 10:42:20 +0100 |
---|---|---|
committer | Jean Boussier <jean.boussier@gmail.com> | 2023-11-03 11:52:17 +0100 |
commit | 35da6f864a05624433be2c8059b87d30b899b370 (patch) | |
tree | 5e493a6b652a53923408e1f7feff514d08372259 /variable.c | |
parent | 1f1b9b0942ec12dde1af8000f8cb84692904fccc (diff) | |
download | ruby-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.c | 22 |
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; } |