From c352808fa9eb650ce8c1b268a348ad553df55caa Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 31 Dec 2025 11:27:46 +0900 Subject: [PATCH 1/2] Introduce typed-data embeddable predicate macros The combination of `&` and `&&` is confusing. --- gc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gc.c b/gc.c index 8a18a129786f33..d149c3e22ec223 100644 --- a/gc.c +++ b/gc.c @@ -1096,6 +1096,9 @@ rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_ return obj; } +#define RB_DATA_TYPE_EMBEDDABLE_P(type) ((type)->flags & RUBY_TYPED_EMBEDDABLE) +#define RTYPEDDATA_EMBEDDABLE_P(obj) RB_DATA_TYPE_EMBEDDABLE_P(RTYPEDDATA_TYPE(obj)) + static VALUE typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_t *type, size_t size) { @@ -1117,7 +1120,7 @@ typed_data_alloc(VALUE klass, VALUE typed_flag, void *datap, const rb_data_type_ VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type) { - if (UNLIKELY(type->flags & RUBY_TYPED_EMBEDDABLE)) { + if (UNLIKELY(RB_DATA_TYPE_EMBEDDABLE_P(type))) { rb_raise(rb_eTypeError, "Cannot wrap an embeddable TypedData"); } @@ -1127,7 +1130,7 @@ rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type) VALUE rb_data_typed_object_zalloc(VALUE klass, size_t size, const rb_data_type_t *type) { - if (type->flags & RUBY_TYPED_EMBEDDABLE) { + if (RB_DATA_TYPE_EMBEDDABLE_P(type)) { if (!(type->flags & RUBY_TYPED_FREE_IMMEDIATELY)) { rb_raise(rb_eTypeError, "Embeddable TypedData must be freed immediately"); } @@ -1153,7 +1156,7 @@ rb_objspace_data_type_memsize(VALUE obj) const rb_data_type_t *type = RTYPEDDATA_TYPE(obj); const void *ptr = RTYPEDDATA_GET_DATA(obj); - if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) { + if (RTYPEDDATA_EMBEDDABLE_P(obj) && !RTYPEDDATA_EMBEDDED_P(obj)) { #ifdef HAVE_MALLOC_USABLE_SIZE size += malloc_usable_size((void *)ptr); #endif @@ -1285,7 +1288,7 @@ rb_data_free(void *objspace, VALUE obj) } else if (free_immediately) { (*dfree)(data); - if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) { + if (RTYPEDDATA_EMBEDDABLE_P(obj) && !RTYPEDDATA_EMBEDDED_P(obj)) { xfree(data); } From d95bebe06c076cdf6951b81665e2b2e779937123 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 31 Dec 2025 11:29:29 +0900 Subject: [PATCH 2/2] Make `RTYPEDDATA_EMBEDDABLE_P` internal-use only It should not be exposed because it is so implementation specific that it is only used in gc.c even within the entire Ruby source tree. --- gc.c | 1 + include/ruby/internal/core/rtypeddata.h | 15 +++++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gc.c b/gc.c index d149c3e22ec223..f77ee417c52dea 100644 --- a/gc.c +++ b/gc.c @@ -1096,6 +1096,7 @@ rb_data_object_zalloc(VALUE klass, size_t size, RUBY_DATA_FUNC dmark, RUBY_DATA_ return obj; } +#define RTYPEDDATA_EMBEDDED_P rbimpl_typeddata_embedded_p #define RB_DATA_TYPE_EMBEDDABLE_P(type) ((type)->flags & RUBY_TYPED_EMBEDDABLE) #define RTYPEDDATA_EMBEDDABLE_P(obj) RB_DATA_TYPE_EMBEDDABLE_P(RTYPEDDATA_TYPE(obj)) diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index 1dd7397f7d335c..505303cefaa5aa 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -548,7 +548,7 @@ RBIMPL_SYMBOL_EXPORT_END() #endif static inline bool -RTYPEDDATA_EMBEDDED_P(VALUE obj) +rbimpl_typeddata_embedded_p(VALUE obj) { #if RUBY_DEBUG if (RB_UNLIKELY(!RB_TYPE_P(obj, RUBY_T_DATA))) { @@ -560,6 +560,13 @@ RTYPEDDATA_EMBEDDED_P(VALUE obj) return (RTYPEDDATA(obj)->type) & TYPED_DATA_EMBEDDED; } +RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() +static inline bool +RTYPEDDATA_EMBEDDED_P(VALUE obj) +{ + return rbimpl_typeddata_embedded_p(obj); +} + static inline void * RTYPEDDATA_GET_DATA(VALUE obj) { @@ -571,9 +578,9 @@ RTYPEDDATA_GET_DATA(VALUE obj) #endif /* We reuse the data pointer in embedded TypedData. */ - return RTYPEDDATA_EMBEDDED_P(obj) ? - RBIMPL_CAST((void *)&(RTYPEDDATA(obj)->data)) : - RTYPEDDATA(obj)->data; + return rbimpl_typeddata_embedded_p(obj) ? + RBIMPL_CAST((void *)&RTYPEDDATA_DATA(obj)) : + RTYPEDDATA_DATA(obj); } RBIMPL_ATTR_PURE()