A bare #define at the start of a line in a brace delimited %fragment body is
consumed by the SWIG preprocessor and never reaches the generated wrapper. The
macro therefore only exists at SWIG level and code that SWIG does not macro
expand, such as a typemap delimited with %{ ... %}, is left referring to an
undefined name. Use %#define so the definition is emitted for the C compiler.
Fixes SWIG_FromCharPtrAndSize for Python, SWIG_FromBinaryCharPtrAndSize for
Octave, Perl, R and Ruby, SWIG_ToUint8Array and SWIG_FromUint8Array for
JavaScript, and the SWIG_AsVal_* and SWIG_From_* macros in the Scilab char,
short, signed char, unsigned char, unsigned long and long long files.
Lib/scilab/scipointer.swg is deliberately left alone. Its fragments are never
requested by any typemap, so they are only emitted as SWIG preprocessor
definitions; switching them to %#define drops SWIG_ConvertPtr and
SWIG_NewPointerObj from the generated code entirely. Fixing those needs the
definitions moving to a runtime insert, as the other target languages do.
Add a common test case charptr_fragment. It uses a %{ ... %} delimited typemap
so the macro name survives into the wrapper, which only compiles when the
library defines the macro for the C compiler. The target languages without
these macros wrap the same functions using their default typemaps. Verified
that the generated Python module fails to load before this change with an
undefined symbol for SWIG_FromCharPtrAndSize.
Follows on from #3522.
Assisted-by: Claude Code (Opus 5)
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)
Embedded data (RUBY_TYPED_EMBEDDABLE) was only enabled on the anonymous
swig_type_data_type descriptor. Wrapped class objects use the per-class
SwigClass*.cext_type descriptor, whose flags were left zero, so they were never
embedded: the swig_ruby_wrapped_object was allocated separately and, since the
free callback no longer calls ruby_xfree once embedding is compiled in, leaked
on every object.
Set cext_type.flags from a shared SWIG_RUBY_TYPED_DATA_FLAGS macro, used by both
the static swig_type_data_type and the generated per-class descriptors so they
can not drift apart. The flags member, and the macro, only exist from Ruby 2.1
(guarded by RUBY_TYPED_FREE_IMMEDIATELY), so the build still works on Ruby 2.0.
Add test ruby_typeddata_embedded which checks that a wrapped object is embedded
on Ruby 3.3 and later via RTYPEDDATA_EMBEDDED_P.
Assisted-by: Claude Opus 4.8
SWIG_Ruby_SetModule wrapped an instance of the swig_runtime_data class with
TypedData_Wrap_Struct and only then called rb_undef_alloc_func on the class.
Wrapping first marks the class as a T_DATA class, so undefining its allocator
afterwards makes Ruby 3.x print, on every module load:
warning: undefining the allocator of T_DATA class swig_runtime_data
Undefine the allocator before the class has any instances to avoid the warning.
The class still can not be instantiated from Ruby.
This warning has been emitted for every Ruby module since commit
4748a6c31a (Ruby: use TypedData API instead of
deprecated untyped Data API) switched from the untyped Data API to TypedData.
Assisted-by: Claude Opus 4.8
Two things disabled objects embedded data usage:
1. RUBY_TYPED_EMBEDDABLE is no `define`, but only an `enum` in ruby-3.3 to 4.0.
It will be a define in ruby-4.1, but to enable the feature we better check for TYPED_DATA_EMBEDDED which is defined in all rubies 3.3 and following.
The ruby docs are a bit misleading about this: https://github.com/ruby/ruby/blob/master/doc/extension.rdoc#c-struct-to-ruby-object
2. RUBY_TYPED_EMBEDDABLE should be OR'ed bitwise to have an effect.
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.
SWIG source is not run through Doxygen, so the Doxygen comment markers /**,
/*!, /// and //! are just noise; SWIG uses plain /* ... */ block comments.
Document this in the swig-conventions skill and convert the existing Doxygen
markers in SWIG's own C/C++ source (the Source/ tree and the Ruby runtime in
Lib/ruby) to plain /* comments.
Target language documentation comments that the library templates emit into generated code
- for example the C# /// comments in Lib/csharp and the JavaScript and Java /** comments -
are left unchanged, since they are part of the generated output rather than SWIG's own source.
Assisted-by: Claude Code (Opus 4.8)
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)
Convert the hidden SwigGCReferences marker object - added with the deprecated
Data_Wrap_Struct by the #3385 GC compaction fix - to TypedData_Wrap_Struct,
removing the last use of the untyped Data API from the Ruby runtime. The
st_table registry and the pinning mark are unchanged; the marker still wraps a
non-NULL pointer so its mark function is not skipped by the garbage collector.
Drop -Wno-deprecated-declarations from the Ruby test flags so that any
reintroduced Data_Wrap_Struct, Data_Make_Struct or Data_Get_Struct fails to
compile under -Werror: Ruby 3.4 warns about the untyped Data API by default and
Ruby 4.0 removes it entirely, so no extra define is needed. The flag dated to an
unrelated macOS isfinite/finite workaround, which is still applied on macOS
through the common flags.
Also add the CHANGES entry and the Ruby manual note describing the migration and
the DATA_PTR / Data_Get_Struct replacement that hand written code must use.
Issue #3170
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.
Ruby objects stored in wrapped STL containers are held by swig::GC_VALUE
as raw VALUEs in C++ - the std::map and std::set keys and the
BinaryPredicate comparator proc. The keep alive registry SwigGCReferences
kept those objects alive but did not pin them, so Ruby 3.x heap
compaction (GC.compact or GC.auto_compact) could relocate them, leaving
the C++ copies dangling and segfaulting the next time the comparator ran.
SwigGCReferences now backs its registry with an st_table instead of a
Ruby Hash, avoiding any C++ STL dependency in the wrapper, and registers
a mark callback that marks every tracked object with the pinning mark
rb_gc_mark. That keeps the objects alive and stops compaction moving
them. Keying the st_table by the VALUE also means register and unregister
no longer dispatch a method on the object.
Add a compaction stress regression to li_std_functors_runme.rb, and drop
the Ruby 3.3 skip that was previously hiding this crash.
Assisted-by: Claude Code (Opus 4.8)
The cdata.i (const void *BYTES, size_t LENGTH) typemap took LENGTH from
SWIG_AsCharPtrAndSize, whose psize includes a trailing NUL (data length
+ 1). When the destination buffer is sized exactly to the data, memmove
wrote one byte past the end. Confirmed with valgrind: "Invalid write of
size 1, 0 bytes after a block of size 512".
- Make SWIG_AsCharPtrAndSize binary aware in the languages that use the
generic Lib/cdata.i (Python, Perl, Ruby, Octave, R): when the caller
passes SWIG_BINARYSTR it now reports the exact byte count, not data
+ 1. Non cdata callers are unaffected as they never set the flag.
- Lua li_cdata_bytes tests looped to 0x99 instead of 0xff, verifying
only 154 of the 256 byte values; corrected to 0xff.
- Tcl cdata.i passed an int * to Tcl_GetSizeIntFromObj, which expects
a Tcl_Size * on Tcl 8.7 and 9; use Tcl_Size and reject values that
are not a byte.
- CHANGES.current: document the cdata type change and the overflow fix.
Assisted-by: Claude Opus 4.7
Use the full English word in the identifiers added by the previous
commit for cdata raw byte handling:
SWIG_BINSTR -> SWIG_BINARYSTR
SWIG_BINSTRMASK -> SWIG_BINARYSTRMASK
SWIG_AddBinMask -> SWIG_AddBinaryStrMask
SWIG_DelBinMask -> SWIG_DelBinaryStrMask
SWIG_IsBinStr -> SWIG_IsBinaryStr
SWIG_FromBinCharPtrAndSize -> SWIG_FromBinaryCharPtrAndSize
useBin (local variable) -> use_binary
Touches the constants in Lib/swigrun.swg, the SWIG_FromBinary*
macro defines in pystrings.swg, perlstrings.swg, rubystrings.swg,
octprimtypes.swg and rfragments.swg, and all call sites in
Lib/cdata.i and Lib/python/pystrings.swg.
Assisted-by: Claude Opus 4.7
Fix guile cdata.
Add SWIG_BINSTR flag
- Add SWIG_FromBinCharPtrAndSize with the new flag
To add languages that use Lib/cdata.i.
- python use binary string by using the new SWIG_BINSTR
in SWIG_AsCharPtrAndSize and SWIG_FromBinCharPtrAndSize.
Languages that were changed to uses list
- Tcl use list of integers.
- scilab use list of uint8.
And support passing list of numbers to C.
Add support to JavaScript
- use Uint8Array instead of strings.
- Add li_cdata_carrays. tests.
- Add li_cdata_bytes tests.
- Use Debian node-addon-api package location.
- napi folder location to Examples/test-suite/javascript/Makefile.in.
- Update documentation.
Update cdata.i documentation
This new cdata test focus on:
- Ensure we can receive proper data from C and pass proper data back to C.
- Use all possoble byte values , i.e. the full range of 0 to 255
and ensure values 128 to 255 do not pass Unicode transformation (UTF-8/16).
- Ensure zero is a valid value and not a string null termination
nor a modified UTF-8 which transform U+0000 to 0xC0 0x80.
- Check mutability of the cdata object.
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
- [Lua] Fix off-by-one when nil terminates the table early: use $1 = i
(not i + 1) to match the count of strings actually copied, and pop
the nil from the Lua stack before breaking.
- [Python] In SWIG_AsCharPtrAndSize (pystrings.swg) decref bytes / obj
on the SWIG_MemoryError early returns added by the previous commits,
so an allocation failure no longer leaks the temporary PyObject.
- [Octave, Python] In argcargv.i free already-allocated string entries
and the array itself before failing on a per-element OOM (Python uses
the existing break path so the freearg typemap performs the cleanup).
- [Perl, PHP, Tcl] Drop unreachable `goto fail` after SWIG_croak /
SWIG_PHP_Error / SWIG_exception_fail, all of which already invoke
SWIG_fail. Compilers warning on unreachable code complained.
- Standardise the OOM error wording across languages and fix the
3- and 5-space indentation introduced by the previous commits.
- Update Examples/perl5/xmlstring/xmlstring.i to the new
%typemaps_string signature (it picks up the missing WarningLeakMsg
argument too) and add a SWIG_NewCopyXMLChArray fragment.
- CHANGES.current: document the API breakages introduced by removing
%new_copy_array, removing %typemaps_string_alloc and extending
%typemaps_string, including the actual error text users will see.
Assisted-by: Claude Opus 4.7 <noreply@anthropic.com>
SWIG_NOEXCEPT is generated instead of throw() which is deprecated in
c++11. If c++11 or later is being used, then this macro expands to
noexcept instead of throw().
Affects director code only.
Also fix up some testcase to not use throw() when using c++11 or later.
Tested with clang and -Wdeprecated-dynamic-exception-spec as gcc
doesn't seem to warn for this deprecation.
Closes#3027
We had versions of it for octave, python, ruby and scilab, which were
exactly the same except for using explicit target language types instead
of SWIG_Object (which is an equivalent type for all these languages),
and except that scilab passed by const reference (but SwigSciObject is
actually an int so there's no benefit to passing by const reference).
This fixes a missing definition of this fragment for SWIG/R which was
triggering a warning when you did `%include std_deque.i` in SWIG/R:
Warning 490: Fragment 'StdDequeTraits' not found.
* Improve mutex for director use:
- Use C++ 11 mutex and lock classes.
Most compilers support C++ 11 by default.
Leave Win32 and POSIX support for older compiler.
- Use a single file for Python and Ruby.
- Use macro also for guard definition instead of using '#ifdef'.
- Rename old '__THREAD__' to 'SWIG_THREADS' to
avoid collide with other libraries.
- Remove the use of '__PTHREAD__' as it may collide with other libraries.
- Remove mutex from OCaml, as it is not used in Director class.
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
* Fixes follow @wsfulton.
Improve description of director_guard.swg.
Remove duplicate line.
Change to SWIG_GUARD_DEFINITION and SWIG_GUARD_DECLARATION
as full English words are much more easily understood
than abbreviations.
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
---------
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
* char_binary_java_fix-tidyup:
Move SWIGStringWithLengthHelper to csharphead.swg
cdata whitespace/cosmetic fixups
cdata doc updates
Rename `typemaps/cdata_struct.swg` to `typemaps/cdata_begin.swg`. And `typemaps/cdata.swg` to `typemaps/cdata.swg`. Move `cdata_apply.swg` content to `typemaps/cdata.swg`.
Group the C# marshalling of STRING-LENGTH typemap into C# class named SWIGStringWithLengthHelper.
Leave Length & string reverse order typemap in typemaps/strings.swg
Support old C# as "LPUTF8Str" was add in 2017.
Improve documentation. Follow @wsfulton reviews.
Use a dummy for MzScheme and untested OCaml cdate. To prevent compilation error.
Further fixing follow reviews.
Reorganise raw data typemap, so typemaps folder contain only common part. Improve document.
Inline SWIG_string_to_utf8_bytes SWIG_utf8_bytes_to_string code
Fixes of STRING/BYTES LENGTH typemaps.
Conflicts:
CHANGES.current
For Javascript, MzScheme, Python, Ruby.
Removes the vast majority of the /*@SWIG:...*/ locator strings in the
generated wrappers for these 4 languages to help with reproducible builds.
Issue #202
Fix Java STRING LENGTH typemap.
Use string type in static typed languages (Java, C#, D and Go).
Add BYTES LENGTH typemap and apply it for binary data.
Use byte type in static typed languages.
Add li_cdata_cpp, li_cdata and char_binary
tests for most of languages(apart from R and experimental).
Fix the director_binary_string test and add it to C#, D, Go,
Perl, PHP, Python, Ruby and octave.
Update documents.
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
Fix setslice(), reinitialise iterator to begin after calling erase().
Fix comparison of integer expressions of different signedness
in getslice() functions.
Fix __setitem__() resize use with new item only if any.
In RubySequence_Cont structure, use standard 'size_t' for size_type.
Add 'li_std_containers_int' test to ruby.
Signed-off-by: Erez Geva <ErezGeva2@gmail.com>
* ruby-lower-bound-checking:
Ruby: Add check for lower bounds of unsigned long (long) parameters
Ruby: Add test case for checking bounds of integral function parameters
in the %array_functions and %array_class macros.
Affects C#, D, Go, Guile, Java, Javascript, Lua, Ocaml, R, Racket.
Closes#1680
If the old types are required for backwards compatibility, use %apply to
restore the old types as follows:
%include "carrays.i"
%apply int { size_t nelements, size_t index }
... %array_functions and %array_class ...
%clear size_t nelements, size_t index; # To be safe in case used elsewhere
* issue/2625:
Enhanced std::map for non-default constructible types changes entry
Add missing exception.i for std::map wrappers for MzScheme and Guile
std::map wrappers and non-default constructible
Fixed make file ordering
Fixed line endings
Added unit test
Using #ifdef instead of #if to prevent warnings
Fix for #2625 Using c++17 insert_or_assign for std::map when available.
Conflicts:
CHANGES.current