Hand written code targeting SWIG 4.4 and earlier invalidates a proxy object
with 'DATA_PTR(obj) = NULL', which used to clear the wrapped C/C++ pointer.
SWIG 4.5 stores that pointer in a swig_ruby_wrapped_object reached through
RTYPEDDATA_GET_DATA, so the assignment now detaches the wrapper itself unless
Ruby embedded it in the object slot, which it only does from Ruby 3.3. The next
conversion of the object then dereferenced a null wrapper and crashed.
Treat a detached object as one whose pointer has been cleared, restoring the
pre 4.5 behaviour, and guard the remaining wrapper dereferences in
SWIG_Ruby_AcquirePtr, SWIG_RubyUnlinkObjects and the mark and free callbacks.
Extend ruby_manual_proxy, which models the Subversion Ruby bindings, with the
legacy close idiom that this fixes.
Closes#3512
Assisted-by: Claude Code (Opus 5)
Ruby-3.3+ allows to embed the wrapper data into the objects memory slot.
This is particular useful for SWIG since the `struct swig_ruby_wrapped_object` is a small and fixed size piece of memory.
Also the rest of the restrictions apply: https://github.com/ruby/ruby/blob/master/doc/extension.rdoc#c-struct-to-ruby-object
This commit reverts several changes of commit 98ea4cdf2d :
1. Revert allocation of `struct swig_ruby_wrapped_object` per malloc:
When using `TypedData_Make_Struct` the corresponding deacclocation should call `ruby_xfree` instead of `free`.
That's the better fix than changing to `malloc` allocation.
2. RTYPEDDATA_DATA is reverted back to RTYPEDDATA_GET_DATA
Because RTYPEDDATA_GET_DATA was in preparation of using RUBY_TYPED_EMBEDDABLE.
3. Revert back to use plain pointer for `$swig_runtime_data_type_pointer`
Because there's no need an no advantage in using `struct swig_ruby_wrapped_object` for this object.
It's makes things only more complicated and needs more memory.
4. The simple type check of $swig_runtime_data_type_pointer was removed
It should be re-added as it protects for accident changes or GC issues.
Rename the per-object wrapper struct from ruby_wrapped_object to
swig_ruby_wrapped_object: a ruby_ prefix in the global namespace is reserved
for the Ruby project itself (swig/swig#3326 review). Also reword the
handleClassName comment.
The other review points are already satisfied by the implementation: the
TypedData descriptors use positional rather than C99 designated initializers
(C90), the generic callbacks take a plainly named parameter, and object
wrapping uses the documented TypedData_Wrap_Struct rather than the internal
Data API.
Assisted-by: Claude Code (Opus 4.8)
The previous commit allocated each object's ruby_wrapped_object with
TypedData_Make_Struct and freed it from the descriptor's free callback. That
only installed the free callback for classes with a destructor or %freefunc, so
the wrapper leaked for destructor-less classes and for the anonymous SWIG::TYPE*
pointer objects, and it freed a Ruby-allocated block with plain free().
Allocate the wrapper with malloc and bind it with TypedData_Wrap_Struct, and
always install the generic mark and free trampolines on every descriptor, the
approach taken in #3456.
The free trampoline runs the per-object free function, if any, and then frees the
wrapper, so malloc and free are paired and nothing leaks regardless of whether the
class owns a destructor. Because TypedData_Wrap_Struct never embeds the data,
RTYPEDDATA_DATA is the correct accessor and the RTYPEDDATA_GET_DATA shim is no longer needed.
See issue #3170.
Assisted-by: Claude Code (deepseek-v4-flash)
The untyped Data API (Data_Wrap_Struct, Data_Get_Struct, DATA_PTR and direct
access to RDATA()->dfree) is deprecated. Ruby 3.4 warns about it by default,
which becomes an error when building generated wrappers with -Werror, and Ruby
4.0 removes the API altogether.
The generated runtime now wraps every object with the TypedData API. Because a
TypedData rb_data_type_t is static per class, it can not carry the per-object
mark and free functions that SWIG needs (ownership is transferred at runtime),
so each object holds a small ruby_wrapped_object that keeps the wrapped pointer
together with its mark and free functions. Generic mark and free callbacks in
the per-class descriptor dispatch to these per-object functions. Each class
gets its own descriptor whose struct name is the C++ class name, which shows up
in Ruby heap dumps and ObjectSpace statistics.
This is not fully backwards compatible: hand written code that reached the
wrapped pointer through DATA_PTR or Data_Get_Struct must instead use the SWIG
conversion functions, which work with old and new SWIG. The ruby_manual_proxy
test is updated to demonstrate the migration.
See issue #3170.
The source of this code is extracted from #3326. Also see followup commit.
This commit fixes the signatures of various callback methods
and cleans up the macro definitions used for casting callbacks.
Note that the transparent version of the macro RUBY_METHOD_FUNC
is currently masked behind RUBY_DEVEL, see commit
1d91feaf13
In order to still support strict signature checking and prevent
nasty deprecation warnings, the use of RUBY_METHOD_FUNC had to
be replaced with VALUEFUNC.
Fixes issue #1168.
Remove a call to abort() (introduced by commit
0e725b5d9b) made when SWIG_RubyUnlinkObjects()
is called on non T_DATA objects. It can happen when the destruction of T_DATA
objects is deferred: the Ruby GC first turn them to T_ZOMBIE, then calls their
free method (SWIG_RubyUnlinkObjects()).
This is a patch to resolve SF bug 2034216 (Github issue #225)
The bug is that the tracking code uses a ruby hash and thus may
allocate objects (Bignum) while running the GC. This was tolerated in
1.8 but is invalid (raises an exception) in 1.9.
The patch uses a C hash (also used by ruby) instead.
Use whichever of "long" or "long long" is the same size as "void*"
to hold pointers as integers, rather than whichever matches off_t.
Fixes compilation on OS X and GCC warnings on platforms where
sizeof(void*) < sizeof(off_t) (SF patch #1731979).
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9852 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Removed object reporting in non-verbose from
newobject demos.
Made wstring treat them as normal strings as
advertised.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9771 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Added swig_assert.rb and started using it in some tests.
Added my patches to ruby.cxx, rubyrun.swg, rubystrings.swg
and rubytracking.swg [see: sourceforge]
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@9691 626c5289-ae23-0410-ae9c-e8d60b6d4f22