diff options
Diffstat (limited to 'include/ruby/internal')
| -rw-r--r-- | include/ruby/internal/core/rtypeddata.h | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index aed4bd89b8..72044562df 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -615,13 +615,24 @@ RBIMPL_ATTR_ARTIFICIAL() * directly. */ static inline void * -rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *type) +rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *expected_type) { - if (RB_LIKELY(RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj) && RTYPEDDATA_TYPE(obj) == type)) { - return RTYPEDDATA_GET_DATA(obj); + if (RB_LIKELY(RB_TYPE_P(obj, T_DATA) && RTYPEDDATA_P(obj))) { + const rb_data_type_t *actual_type = RTYPEDDATA_TYPE(obj); + void *data = RTYPEDDATA_GET_DATA(obj); + if (RB_LIKELY(actual_type == expected_type)) { + return data; + } + + while (actual_type) { + actual_type = actual_type->parent; + if (actual_type == expected_type) { + return data; + } + } } - return rb_check_typeddata(obj, type); + return rb_check_typeddata(obj, expected_type); } |
