summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-11-10 11:53:50 +0100
committerJean Boussier <jean.boussier@gmail.com>2023-11-10 15:56:42 +0100
commita9f45aac6e2389ff826987771198729441bf6a85 (patch)
tree717a4d5f5b31a2fccadae4ec75695c4e93285e04 /gc.c
parenta2442e91fded557fe79a49a86b84565ee66e34cc (diff)
rb_data_free: Fix freeing embedded TypedData
The previous implementation was using the pointer given by `DATA_PTR` in all cases. But in the case of an embedded TypedData, that pointer is garbage, we need to use RTYPEDDATA_GET_DATA to get the proper data pointer. Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index d38f35837d..4da9ad8447 100644
--- a/gc.c
+++ b/gc.c
@@ -3188,7 +3188,7 @@ rb_objspace_data_type_memsize(VALUE obj)
size_t size = 0;
if (RTYPEDDATA_P(obj)) {
const rb_data_type_t *type = RTYPEDDATA_TYPE(obj);
- const void *ptr = RTYPEDDATA_DATA(obj);
+ const void *ptr = RTYPEDDATA_GET_DATA(obj);
if (RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_EMBEDDABLE && !RTYPEDDATA_EMBEDDED_P(obj)) {
#ifdef HAVE_MALLOC_USABLE_SIZE
@@ -3471,10 +3471,10 @@ obj_free_object_id(rb_objspace_t *objspace, VALUE obj)
static bool
rb_data_free(rb_objspace_t *objspace, VALUE obj)
{
- if (DATA_PTR(obj)) {
+ void *data = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
+ if (data) {
int free_immediately = false;
void (*dfree)(void *);
- void *data = DATA_PTR(obj);
if (RTYPEDDATA_P(obj)) {
free_immediately = (RANY(obj)->as.typeddata.type->flags & RUBY_TYPED_FREE_IMMEDIATELY) != 0;
@@ -10699,7 +10699,7 @@ gc_update_object_references(rb_objspace_t *objspace, VALUE obj)
case T_DATA:
/* Call the compaction callback, if it exists */
{
- void *const ptr = DATA_PTR(obj);
+ void *const ptr = RTYPEDDATA_P(obj) ? RTYPEDDATA_GET_DATA(obj) : DATA_PTR(obj);
if (ptr) {
if (RTYPEDDATA_P(obj) && gc_declarative_marking_p(any->as.typeddata.type)) {
gc_ref_update_from_offset(objspace, obj);