diff --git a/Lib/php/factory.i b/Lib/php/factory.i index 7dcd517ec..399ef8c1b 100644 --- a/Lib/php/factory.i +++ b/Lib/php/factory.i @@ -96,7 +96,7 @@ if (!dcast) { if (dobj) { dcast = 1; zend_object *std = $descriptor(Type)##_ce->create_object($descriptor(Type)##_ce); - SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, SWIG_as_voidptr(dobj), $descriptor(Type *), std); + SWIG_SetZval(return_value, $needNewFlow, $owner, SWIG_as_voidptr(dobj), $descriptor(Type *), std); } }%enddef @@ -105,6 +105,6 @@ if (!dcast) { int dcast = 0; %formacro(%_factory_dispatch, Types) if (!dcast) { - SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, SWIG_as_voidptr($1), $descriptor, $zend_obj); + SWIG_SetZval(return_value, $needNewFlow, $owner, SWIG_as_voidptr($1), $descriptor, $zend_obj); } }%enddef diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 5b20d9a6c..55fafcdbe 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -396,12 +396,12 @@ SWIGTYPE &, SWIGTYPE && %{ - SWIG_SetZval($result, $classZv, $owner, $newobj, $c_obj, (void *)result, $1_descriptor, $zend_obj); + SWIG_SetZval($result, $needNewFlow, $owner, (void *)result, $1_descriptor, $zend_obj); %} %typemap(out) SWIGTYPE *const& %{ - SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (void *)*$1, $*1_descriptor, $zend_obj); + SWIG_SetZval(return_value, $needNewFlow, $owner, (void *)*$1, $*1_descriptor, $zend_obj); %} %typemap(directorin) SWIGTYPE *, @@ -436,13 +436,13 @@ #ifdef __cplusplus { $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1); - SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj); + SWIG_SetZval(return_value, $needNewFlow, $owner, (void *)resultobj, $&1_descriptor, $zend_obj); } #else { $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type)); memcpy(resultobj, &$1, sizeof($1_type)); - SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj); + SWIG_SetZval(return_value, $needNewFlow, $owner, (void *)resultobj, $&1_descriptor, $zend_obj); } #endif diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index acb856958..0467b5bd1 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -245,14 +245,19 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { } static void -SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj ,swig_type_info *type) { +SWIG_pack_zval(zval *zv, void *ptr, int userNewObj) { swig_object_wrapper *obj = NULL; + obj = (swig_object_wrapper *) SWIG_Z_FETCH_OBJ_P(zv); + obj->ptr = ptr; + obj->newobject = userNewObj; +} - HashTable * ht = NULL; +static void +SWIG_generalize_object(zval *zval_obj, void *ptr, int userNewObj ,swig_type_info *type) { + SWIG_pack_zval(zval_obj, ptr, userNewObj); + + HashTable *ht = Z_OBJ_HT_P(zval_obj)->get_properties(zval_obj); - obj = (swig_object_wrapper *) SWIG_Z_FETCH_OBJ_P(zval_obj); - obj->ptr = (void *)ptr; - ht = Z_OBJ_HT_P(zval_obj)->get_properties(zval_obj); if(ht) { zval zv; ZVAL_RES(&zv,zend_register_resource(ptr,*(int *)(type->clientdata))); @@ -260,32 +265,23 @@ SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj ZVAL_TRUE(&zv); zend_hash_str_add(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1, &zv); } - obj->newobject = userNewObj; } static void -SWIG_SetZval( zval *zv, zval *class_zv, int userNewObj ,int object, int class_obj ,void *ptr, swig_type_info *type, zend_object *std) { - - if (class_obj == 1) { - SWIG_generalize_object(class_zv, ptr, class_obj, userNewObj ,type); - return; - } +SWIG_SetZval( zval *zv, int newFlow, int userNewObj, void *ptr, swig_type_info *type, zend_object *std) { if (!ptr) { ZVAL_NULL(zv); return; } - if (object == 1) { - ZVAL_OBJ(zv,std); - SWIG_generalize_object(zv, ptr, class_obj, userNewObj, type); + if (newFlow) { + if (newFlow == 1) + ZVAL_OBJ(zv,std); + SWIG_generalize_object(zv, ptr, userNewObj, type); } - - if (object == 2) { - int newobj = class_obj; - if (class_obj == 2) - newobj = 1; - SWIG_SetPointerZval(zv,ptr,type,newobj); + else { + SWIG_SetPointerZval(zv, ptr, type, userNewObj); } } diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 1d93e0c63..763dccfd2 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1000,16 +1000,28 @@ public: String *symname = Getattr(n, "sym:name"); String *wname = NULL; String *modes = NULL; + bool constructorRenameOverload = false; if (constructor) { - wname = NewString("__construct"); + // Renamed constructor - turn into static factory method + if (Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) != 0) { + constructorRenameOverload = true; + wname = Copy(Getattr(n, "constructorHandler:sym:name")); + } else { + wname = NewString("__construct"); + } } else if (class_name) { wname = getWrapperMethodName(class_name, symname); } else { wname = Swig_name_wrapper(symname); } - if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) { + if (constructor) { + modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR"); + if (constructorRenameOverload) { + Append(modes, " | ZEND_ACC_STATIC"); + } + } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) { modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC"); } else { modes = NewString("ZEND_ACC_PUBLIC"); @@ -1330,10 +1342,10 @@ public: if (constructor) { Append(modes, " | ZEND_ACC_CTOR"); - } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) { + } + if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) { Append(modes, " | ZEND_ACC_STATIC"); } - if (GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n))) Append(modes, " | ZEND_ACC_ABSTRACT"); @@ -1345,8 +1357,8 @@ public: return SWIG_ERROR; } - // Test for overloading if (overname) { + // Test for overloading wname = Swig_name_wrapper(iname); Printf(wname, "%s", overname); } else if (constructor) { @@ -1649,6 +1661,7 @@ public: String *retType_class = NULL; bool retType_valid = is_class(d); bool valid_wrapped_class = false; + bool constructorRenameOverload = false; if (retType_valid) { retType_class = get_class_name(d); @@ -1656,6 +1669,10 @@ public: valid_wrapped_class = is_class_wrapped(retType_class); } + if (constructor && Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) != 0) { + constructorRenameOverload = true; + } + /* emit function call */ String *actioncode = emit_action(n); @@ -1663,18 +1680,15 @@ public: Replaceall(tm, "$input", Swig_cresult_name()); Replaceall(tm, "$source", Swig_cresult_name()); Replaceall(tm, "$target", "return_value"); - Replaceall(tm, "$result", "return_value"); + Replaceall(tm, "$result", constructor ? (constructorRenameOverload ? "return_value" : "getThis()") : "return_value"); Replaceall(tm, "$owner", newobject ? "1" : "0"); - Replaceall(tm, "$needNewFlow", retType_valid ? (valid_wrapped_class ? "1" : "0") : "0"); - Replaceall(tm, "$classZv", constructor ? "getThis()" : "NULL"); + Replaceall(tm, "$needNewFlow", retType_valid ? (constructor ? (constructorRenameOverload ? "1" : "2") : (valid_wrapped_class ? "1" : "0")) : "0"); if (retType_class) { String *retZend_obj = NewStringEmpty(); Printf(retZend_obj, "%s_object_new(SWIGTYPE_%s_ce)", retType_class, retType_class); - Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (valid_wrapped_class ? retZend_obj : "NULL")) : "NULL"); + Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? (constructorRenameOverload ? retZend_obj : "NULL") : (valid_wrapped_class ? retZend_obj : "NULL")) : "NULL"); } Replaceall(tm, "$zend_obj", "NULL"); - Replaceall(tm, "$newobj", retType_valid ? (valid_wrapped_class ? "1" : "2") : "2"); - Replaceall(tm, "$c_obj", newobject? (valid_wrapped_class ? (constructor ? "1" : "0") : "2") : "0"); Printf(f->code, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);