[前][次][番号順一覧][スレッド一覧]

ruby-changes:67196

From: Mike <ko1@a...>
Date: Fri, 20 Aug 2021 08:30:27 +0900 (JST)
Subject: [ruby-changes:67196] e8e3b7a0e2 (master): Undefine the alloc function for T_DATA classes

https://git.ruby-lang.org/ruby.git/commit/?id=e8e3b7a0e2

From e8e3b7a0e2fc2cc6384eb10332cc46e385373cbb Mon Sep 17 00:00:00 2001
From: Mike Dalessio <mike.dalessio@g...>
Date: Wed, 26 May 2021 01:38:31 -0400
Subject: 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.
---
 gc.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/gc.c b/gc.c
index 2b14adb..c70f8a3 100644
--- a/gc.c
+++ b/gc.c
@@ -2749,11 +2749,22 @@ rb_class_allocate_instance(VALUE klass) https://github.com/ruby/ruby/blob/trunk/gc.c#L2749
     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 https://github.com/ruby/ruby/blob/trunk/gc.c#L2780
 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));
 }
 
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]