[php] Allow testing if an object is SWIG-wrapped
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
This commit is contained in:
parent
0cfc750d44
commit
c417250b4e
3 changed files with 35 additions and 4 deletions
|
|
@ -87,6 +87,15 @@ static String *fake_class_name() {
|
|||
return result;
|
||||
}
|
||||
|
||||
static String *swig_wrapped_interface_ce() {
|
||||
static String *result = NULL;
|
||||
if (!result) {
|
||||
result = NewStringf("SWIG_Php_swig_wrapped_interface_ce");
|
||||
Printf(s_oinit, " INIT_CLASS_ENTRY(%s, \"SWIG\\\\wrapped\", NULL);\n", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* To reduce code size (generated and compiled) we only want to emit each
|
||||
* different arginfo once, so we need to track which have been used.
|
||||
*/
|
||||
|
|
@ -163,12 +172,14 @@ static void SwigPHP_emit_pointer_type_registrations() {
|
|||
while (ki.key) {
|
||||
String *type = ki.key;
|
||||
|
||||
String *swig_wrapped = swig_wrapped_interface_ce();
|
||||
Printf(s_creation, "/* class entry for pointer to %s */\n", type);
|
||||
Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", type);
|
||||
|
||||
Printf(s_oinit, " INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", NULL);\n", "SWIG", type);
|
||||
Printf(s_oinit, " SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", type);
|
||||
Printf(s_oinit, " SWIG_Php_ce_%s->create_object = swig_ptr_object_new;\n", type);
|
||||
Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", type, ", &", swig_wrapped, ");\n", NIL);
|
||||
Printf(s_oinit, " SWIG_TypeClientData(SWIGTYPE%s,SWIG_Php_ce_%s);\n", type, type);
|
||||
Printf(s_oinit, "\n");
|
||||
|
||||
|
|
@ -1633,6 +1644,8 @@ public:
|
|||
if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
|
||||
Printf(s_oinit, " SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
|
||||
}
|
||||
String *swig_wrapped = swig_wrapped_interface_ce();
|
||||
Printv(s_oinit, " zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);
|
||||
|
||||
{
|
||||
Node *node = NewHash();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue