|
26 | 26 | # include <stddef.h> |
27 | 27 | #endif |
28 | 28 |
|
| 29 | +#include "ruby/assert.h" |
29 | 30 | #include "ruby/internal/assume.h" |
30 | 31 | #include "ruby/internal/attr/artificial.h" |
31 | 32 | #include "ruby/internal/attr/flag_enum.h" |
|
94 | 95 | */ |
95 | 96 | #define RTYPEDDATA(obj) RBIMPL_CAST((struct RTypedData *)(obj)) |
96 | 97 |
|
| 98 | +static inline VALUE rbimpl_check_external_typeddata(VALUE obj); |
| 99 | + |
97 | 100 | /** |
98 | 101 | * Convenient getter macro. |
99 | 102 | * |
100 | 103 | * @param v An object, which is in fact an ::RTypedData. |
101 | 104 | * @return The passed object's ::RTypedData::data field. |
102 | 105 | */ |
103 | | -#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data) |
| 106 | +#define RTYPEDDATA_DATA(v) (RTYPEDDATA(rbimpl_check_external_typeddata(v))->data) |
104 | 107 |
|
105 | 108 | /** @old{rb_check_typeddata} */ |
106 | 109 | #define Check_TypedStruct(v, t) \ |
@@ -600,7 +603,7 @@ rbimpl_typeddata_get_data(VALUE obj) |
600 | 603 | { |
601 | 604 | /* We reuse the data pointer in embedded TypedData. */ |
602 | 605 | return rbimpl_typeddata_embedded_p(obj) ? |
603 | | - RBIMPL_CAST((void *)&RTYPEDDATA_DATA(obj)) : |
| 606 | + RBIMPL_CAST((void *)&RTYPEDDATA(obj)->data) : |
604 | 607 | RTYPEDDATA_DATA(obj); |
605 | 608 | } |
606 | 609 |
|
@@ -736,6 +739,22 @@ rbimpl_check_typeddata(VALUE obj, const rb_data_type_t *expected_type) |
736 | 739 | return RTYPEDDATA_GET_DATA(obj); |
737 | 740 | } |
738 | 741 |
|
| 742 | +RBIMPL_ATTR_PURE_UNLESS_DEBUG() |
| 743 | +RBIMPL_ATTR_ARTIFICIAL() |
| 744 | +/** |
| 745 | + * @private |
| 746 | + * |
| 747 | + * This is an implementation detail of RTYPEDDATA_DATA(). Don't use it |
| 748 | + * directly. |
| 749 | + */ |
| 750 | +static inline VALUE |
| 751 | +rbimpl_check_external_typeddata(VALUE obj) |
| 752 | +{ |
| 753 | + RBIMPL_TYPEDDATA_PRECONDITION(obj, RBIMPL_UNREACHABLE_RETURN(false)); |
| 754 | + RUBY_ASSERT(rbimpl_obj_typeddata_p(obj)); |
| 755 | + RUBY_ASSERT(!rbimpl_typeddata_embedded_p(obj)); |
| 756 | + return obj; |
| 757 | +} |
739 | 758 |
|
740 | 759 | /** |
741 | 760 | * Obtains a C struct from inside of a wrapper Ruby object. |
|
0 commit comments