The typemaps for long long and unsigned long long didn't handle a
string input correctly, and long_long_runme.php had a flawed test
in this case.
Fixes#2155
It seems instanceof_function_ex() isn't a viable option for PHP 7.3 and
earlier - the implementation is strangely wrong.
So let's just provide a compatibility implementation which does what
zend_class_implements_interface() does in 8.x and use that for all 7.x
so there are fewer variants to worry about testing.
The sense of parameter 3 of instanceof_function_ex() appears to have
changed in PHP 7.4 and we need to pass 0 for older versions and 1 for
PHP 7.4. Words fail me.
Since the switch to wrapping classes using PHP's C API, we now
internally need to be able to tell if a PHP object is of or derived
from a class that is wrapped by SWIG so we know if we can offset the
zend_object pointer to get to the swig_object_wrapper. If we try to
do this to an object which isn't wrapped by SWIG then we invoke C/C++
undefined behaviour (and typically get a segmentation fault).
This check is implemented by having a SWIG\wrapped empty interface which
we make all SWIG-wrapped classes implement simply so we can test for it
to detect such classes.
Fixes#2125
As discussed and agreed in #1629, it's become hard to test with Perl
5.6 or earlier, such old versions are no longer in active use, and
4.1.0 is an appropriate time to make such a change.
I've dropped the compatibility code that was obvious to me, but there's
probably more that can be cleaned up now.
Fix access to C++ static member functions using Python class
staticmethod syntax, such as Klass.memberfunction instead of
Klass_memberfunction, when using -fastproxy and -builtin in
combination with %callback.
The docstring containing the callback pointers were not being patched
during module initialisation.
We have the swig_type_info available and SWIG_TypeCheckStruct
is more efficient because it uses a pointer comparison instead of the
string comparison SWIG_TypeCheck uses (this change speeds up `make
check-php-test-suite` by about 10%).
Add PHP keyword 'readonly' (added in 8.1) to the list SWIG knows to
automatically rename. This keyword is special in that PHP allows it to
be used as a function (or method) name.
Previously the zend_class_entry for Foo was named SWIGTYPE_Foo_ce, but
this can collide in some cases - e.g. if there's a class named p_Foo
then its zend_class entry will be SWIGTYPE_p_Foo_ce, but that's the same
as the swig_type_info for a class named p_Foo_ce.
Do more initialisation at module load time.
Use a shared set of handlers for cases when the C/C++ object is
destroyed with free().
Most of the code in the free_obj and create_object handlers is the
same for every wrapped class so factor that out into common functions.
This typemap which would wrap C++ bool as PHP int is later overridden
by another which wraps it as PHP bool. The current result is what
we want so just remove the redundant one.
Move this function definition to cexcept.swg from the code and only
define it if SWIG_swig_check_DEFINED is not defined yet, which both
simplifies the code in C.cxx and makes exception handling code more
flexible, as it's now possible to predefine SWIG_swig_check_DEFINED
in the code injected into the "cxxheader" section to replace the default
implementation. Show an example of doing this in the documentation and
document handling exceptions with C API too.
The changes above required adding a new "cxxcode" section, corresponding
to the "implementation" part of C++ wrappers and defining a new
SWIG_CXX_WRAPPERS preprocessor symbol to allow only adding C++-specific
code when C++ wrappers are actually generated. Also improve the
documentation of the C-specific sections in the manual.
The correct macro to test is PHP_MAJOR_VERSION so these two PHP 8 cases
weren't ever used, which hid that the PHP8 version of the code was
broken in one of them.
Highlighted in #2113.
This is much more convenient and allows checking if the shared pointer
is empty easily, unlike before, when it couldn't be done and adding
support for it would have required adding extra functions.
Also add a way to check whether an object is null in C++ wrappers of the
classes handled via shared pointers and static null() method for
creating null objects of such classes.
This makes using returning strings much simpler to use from C++ code as
the returned pointers don't have to be deleted manually -- although, of
course, this does require an extra allocation and copy and so should be
avoided for the very long strings.
Add a new runtime test showing how simple and convenient it is to use
the functions working with string using the C++ wrappers now.
Add typecheck typemaps for primitive types and string and call
Swig_overload_check() to ensure that we don't generate two wrappers
functions taking the same "const char*" type if we have overloads taking
it and "std::string" (or a reference) in the original code.
Avoid unnecessary heap allocations, just use temporary variables.
Actually update the string parameters passed by pointer/non-const
reference. This requires the pointers passed to actually be non-const,
so update the C-specific unit test runme to use a char buffer instead of
a literal string.
Also simplify the code copying the string contents to just use strdup()
(if there are ever any platforms where this POSIX functions is not
available, we could just define it ourselves once instead of using
strlen() + malloc() + memcpy() manually twice).
Fixes#2101. There are 3 related changes made here:
1. Move the SWIG_globals() singleton into pyrun from pyint so it
is visible to SWIG_Python_DestroyModule(). The static globals
varlink has been extracted out of the function so that it can
be set to NULL in SWIG_Python_DestroyModule(), which fixes the
issue described in #2101. (Now when the second interpreter
starts up, the Swig_Globals_global pointer will be NULL, so it
knows it has to create a new one.)
2. Remove a Py_DECREF on the globals varlink. The decrement is now
performed by DestroyModule(), so there's no need to do it in
SWIG_init().
3. Fixed similar issue with SWIG_Python_TypeCache().
Use enum types instead of int for the enum-valued parameters and
function return values, this is more type-safe and clear for the users
of the library.
Change cpp_enum unit test to use C++ to check that C++ enum wrappers
can at least be compiled, but still use C API in it.
Note that enum whose underlying type is bigger than int still don't
work, but this is no different from what it was before, so just document
this limitation but don't do anything else about it for now.
This commit is best viewed ignoring whitespace-only changes.
This allows different threads to use the same library concurrently
without corrupting each other's exceptions.
Note that this requires C++11 support for wrapper compilation too. If
this really turns out to be a problem, we could always just #define
thread_local as compiler-specific equivalent such as "__thread" for gcc
or "__declspec(thread)" for MSVC, which are available since forever.
Ensure that we have only a single SWIG_CException_Raise() function
across all modules instead of having per-module functions and, worse,
per-module PendingException variables, which resulted in compile-time
errors and couldn't work anyhow because function checking for the
current exception didn't necessarily use the same "global" variable
where it was stored. More formally, old version resulted in ODR
violations and undefined behaviour.
The way we avoid it now is rather ugly and consists in excluding
SWIG_CException from wrapping using the hack in the source code which
postpones wrapping this class until the very end and checks if we had
encountered any %import directives and simply doesn't wrap it if we did.
The same code is used to define the special SWIG_CException_DEFINED
preprocessor symbol which is then used in the generated code to prevent
the SWIG_CException class declaration from being compiled as part of the
wrapper too (because this still happens due to %inline being used for
its definition, and there doesn't seem to be any better way to avoid
this).
This is definitely not pretty, but at least adding "throw(char*)" to a
couple of functions in mod_[ab].i test suite files works now instead of
failing (even without linking and running) as before. This commit
doesn't modify the test suite to avoid possible problems with the other
languages, however.
Check for the pending exception after every call to a wrapper function
not marked "noexcept" and throw a C++ exception if necessary.
Add C++ version of the exception example to show how this works.
Also change SWIG_CException to use member functions for checking for and
resetting pending exceptions, this seems better than having separate
functions for it and will make it easier to customize exception handling
later by just replacing SWIG_CException class with something else.
Note that we still use a global (and not a member) function for raising
the exception, but this one is not exported at all, and needs to be a
function in order to be easily callable from other modules (see the
upcoming commit).