diff options
author | Mike Dalessio <mike.dalessio@gmail.com> | 2021-05-26 01:38:31 -0400 |
---|---|---|
committer | Nobuyoshi Nakada <nobu@ruby-lang.org> | 2021-08-20 08:30:06 +0900 |
commit | e8e3b7a0e2fc2cc6384eb10332cc46e385373cbb (patch) | |
tree | 3f83f009f282c5f6f72935ffd70de4d49fad2692 /gc.c | |
parent | 6963f8f743b42f9004a0879cd66c550f18987352 (diff) | |
download | ruby-e8e3b7a0e2fc2cc6384eb10332cc46e385373cbb.tar.gz |
Undefine the alloc function for T_DATA classes
which have not undefined or redefined it.
When a `T_DATA` object is created whose class has not undefined or
redefined the alloc function, the alloc function now gets undefined by
Data_Wrap_Struct et al. Optionally, a future release may also warn
that this being done.
This should help developers of C extensions to meet the requirements
explained in "doc/extension.rdoc". Without a check like this, there is
no easy way for an author of a C extension to see where they have made
a mistake.
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 15 |
1 files changed, 13 insertions, 2 deletions
@@ -2749,11 +2749,22 @@ rb_class_allocate_instance(VALUE klass) return obj; } +static inline void +rb_data_object_check(VALUE klass) +{ + if (klass != rb_cObject && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) { + rb_undef_alloc_func(klass); +#if 0 /* TODO: enable at the next release */ + rb_warn("undefining the allocator of T_DATA class %"PRIsVALUE, klass); +#endif + } +} + VALUE rb_data_object_wrap(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree) { RUBY_ASSERT_ALWAYS(dfree != (RUBY_DATA_FUNC)1); - if (klass) Check_Type(klass, T_CLASS); + if (klass) rb_data_object_check(klass); return newobj_of(klass, T_DATA, (VALUE)dmark, (VALUE)dfree, (VALUE)datap, FALSE, sizeof(RVALUE)); } @@ -2769,7 +2780,7 @@ VALUE rb_data_typed_object_wrap(VALUE klass, void *datap, const rb_data_type_t *type) { RUBY_ASSERT_ALWAYS(type); - if (klass) Check_Type(klass, T_CLASS); + if (klass) rb_data_object_check(klass); return newobj_of(klass, T_DATA, (VALUE)type, (VALUE)1, (VALUE)datap, type->flags & RUBY_FL_WB_PROTECTED, sizeof(RVALUE)); } |