rb_gc_impl_copy_finalizer: generate a new object id

Fix a regression introduced by: https://github.com/ruby/ruby/pull/13155
This commit is contained in:
Jean Boussier 2025-05-15 14:04:36 +02:00
parent a294427017
commit ec8900e3eb
Notes: git 2025-05-16 18:17:06 +00:00
4 changed files with 25 additions and 4 deletions

View File

@ -2805,7 +2805,8 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
int lev = rb_gc_vm_lock();
if (RB_LIKELY(st_lookup(finalizer_table, obj, &data))) {
table = (VALUE)data;
table = rb_ary_dup((VALUE)data);
RARRAY_ASET(table, 0, rb_obj_id(dest));
st_insert(finalizer_table, dest, table);
FL_SET(dest, FL_FINALIZE);
}

View File

@ -985,7 +985,8 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
int lev = rb_gc_vm_lock();
if (RB_LIKELY(st_lookup(objspace->finalizer_table, obj, &data))) {
table = (VALUE)data;
table = rb_ary_dup((VALUE)data);
RARRAY_ASET(table, 0, rb_obj_id(dest));
st_insert(objspace->finalizer_table, dest, table);
FL_SET(dest, FL_FINALIZE);
}

View File

@ -409,11 +409,11 @@ init_copy(VALUE dest, VALUE obj)
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
// Copies the shape id from obj to dest
RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR);
rb_gc_copy_attributes(dest, obj);
rb_copy_generic_ivar(dest, obj);
if (RB_TYPE_P(obj, T_OBJECT)) {
rb_obj_copy_ivar(dest, obj);
}
rb_gc_copy_attributes(dest, obj);
}
static VALUE immutable_obj_clone(VALUE obj, VALUE kwfreeze);

View File

@ -94,7 +94,7 @@ End
end
def test_finalizer
assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok), [])
a = []
ObjectSpace.define_finalizer(a) { p :ok }
b = a.dup
@ -137,6 +137,25 @@ End
}
end
def test_finalizer_copy
assert_in_out_err(["-e", <<~'RUBY'], "", %w(:ok), [])
def fin
ids = Set.new
->(id) { puts "object_id (#{id}) reused" unless ids.add?(id) }
end
OBJ = Object.new
ObjectSpace.define_finalizer(OBJ, fin)
OBJ.freeze
10.times do
OBJ.clone
end
p :ok
RUBY
end
def test_finalizer_with_super
assert_in_out_err(["-e", <<-END], "", %w(:ok), [])
class A