Hi, i’ve been trying to do small changes on some objects using Fiddle, such as changing flags through Fiddle::Pointer, and passing the value based on the object_id. As far as i know in MRI an object_id coincides with a VALUE of an object on the MRI. Up to ruby 2.6 i could get the correct Pointer for an object_id and also the id of an object is the same when doing a bitwise to the left and printing as hex
Does anybody know or have any insight where to have more detail on the changes made on Ruby 2.7 regarding the object_id and the relation between the MRI objects?
I don’t know if this will help, but I took a little ‘dive’ to see.
The change in the source seems to occur in gc.c.
If you see the documentation for object_id in 2.6 vs 2.7, and click on ‘show source’, the latter calls rb_find_object_id: class Object - RDoc Documentation
This is a new function in 2.7 in the gc.c file. This calls a cached_object_id function which appears to do a lot of work in the symbol table, and uses an objspace ‘thing’ to get the next id.
Whereas in 2.6 the nonspecial_object_id macro is defined in gc.c and appears to be (more-or-less) the VALUE of the object. class Object - RDoc Documentation
I don’t understand much of this, but if you want to see the changes made, then I think this is where to start looking!
It’s interesting how the documentation is identical for object_id and to_s in both 2.6 and 2.7, but the id value is completely different.
I did more or less the same digging on the sources of Ruby, specially on gc.c, the changes are made for 2.7 on the new rb_find_object_id function
for non primitive objects, the cached_object_id function is called which uses a symbol table as you mentioned. But if we print an object using puts we’ll still get the old object_id in hex format as the nonspecial_obj_id function is called, and still exists on 2.7 (ruby/gc.c at a0c7c23c9cec0d0ffcba012279cd652d28ad5bf3 · ruby/ruby · GitHub), when calling the to_s method for an object.
So one way probably get the object memory reference on 2.7, although a bit of a hack, is to call the to_s method and extract the id from there.
Thanks for the replies. what i managed to do for getting the same object_id on Ruby 2.7 was to create a simple C extension that would use the rb_memory_id function that is similar to what rb_obj_id function did prior to 2.7 (seen on ruby/gc.c at 27958c2bd64b27d529f81a130bd488ccc6b9b1d4 · ruby/ruby · GitHub)
that was the cleanest way i did find for the latest ruby to get the object_id and then get the address memory to be able to access some of the internals through Fiddle.
Another way is to do the following without creating an extension: