summaryrefslogtreecommitdiff
path: root/Lib/php
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/php')
-rw-r--r--Lib/php/phprun.swg19
1 files changed, 18 insertions, 1 deletions
diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg
index a24b2551c..97d17d9ca 100644
--- a/Lib/php/phprun.swg
+++ b/Lib/php/phprun.swg
@@ -93,6 +93,12 @@ static int default_error_code = E_ERROR;
#define SWIG_GetModule(clientdata) SWIG_Php_GetModule()
#define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer, *(int*)clientdata)
+static zend_class_entry SWIG_Php_swig_wrapped_interface_ce;
+
+#if PHP_MAJOR_VERSION == 7
+# define zend_class_implements_interface(C, I) instanceof_function_ex(C, I, 1)
+#endif
+
/* used to wrap returned objects in so we know whether they are newobject
and need freeing, or not */
typedef struct {
@@ -156,7 +162,18 @@ SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_o
switch (Z_TYPE_P(z)) {
case IS_OBJECT: {
- swig_object_wrapper *value = SWIG_Z_FETCH_OBJ_P(z);
+ zend_object *obj = Z_OBJ_P(z);
+ swig_object_wrapper *value;
+ if (ty && ty->clientdata == (void*)obj->ce) {
+ // Object is exactly the class asked for - this handles common cases cheaply,
+ // and in particular the PHP classes we use to wrap a pointer to a non-class.
+ } else if (!zend_class_implements_interface(obj->ce, &SWIG_Php_swig_wrapped_interface_ce)) {
+ // Not an object we've wrapped.
+ return -1;
+ }
+
+ /* convert and cast value->ptr from value->type to ptr as ty. */
+ value = swig_php_fetch_object(obj);
if (!ty) {
/* They don't care about the target type, so just pass on the pointer! */
*ptr = value->ptr;