diff --git a/Lib/php/factory.i b/Lib/php/factory.i index c4e082dd2..6a6b504ec 100644 --- a/Lib/php/factory.i +++ b/Lib/php/factory.i @@ -95,7 +95,15 @@ if (!dcast) { Type *dobj = dynamic_cast($1); if (dobj) { dcast = 1; - SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj),$descriptor(Type *), $owner); + zend_object *std = NULL; + if ($newobj) { + zend_class_entry *ce = zend_lookup_class(zend_string_init("Type", sizeof("Type")-1, 0)); + std = ce->create_object(ce); + } + else { + std = $zend_obj; + } + SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr(dobj), $descriptor(Type *), std); } }%enddef @@ -104,6 +112,6 @@ if (!dcast) { int dcast = 0; %formacro(%_factory_dispatch, Types) if (!dcast) { - SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1),$descriptor, $owner); + SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr($1), $descriptor, $zend_obj); } }%enddef diff --git a/Lib/php/php.swg b/Lib/php/php.swg index dca591f53..1ababd48b 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -421,13 +421,45 @@ #ifdef __cplusplus { $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1); - SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1); + SWIG_SetZval(return_value, $newobj , $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj); + swig_object_wrapper *obj = NULL; + + HashTable * ht = NULL; + + obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value); + obj->ptr = (void *)resultobj; + ht = Z_OBJ_HT_P(return_value)->get_properties(return_value); + if(ht) { + zval zv; + ZVAL_RES(&zv,zend_register_resource(resultobj,*(int *)($&1_descriptor->clientdata))); + zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv); + } + if ($newobj == 1) + obj->newobject = 1; + else + obj->newobject = 0; } #else { $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type)); memcpy(resultobj, &$1, sizeof($1_type)); - SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1); + SWIG_SetZval(return_value, $newobj , $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj); + swig_object_wrapper *obj = NULL; + + HashTable * ht = NULL; + + obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value); + obj->ptr = (void *)resultobj; + ht = Z_OBJ_HT_P(return_value)->get_properties(return_value); + if(ht) { + zval zv; + ZVAL_RES(&zv,zend_register_resource(resultobj,*(int *)($&1_descriptor->clientdata))); + zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv); + } + if ($newobj) + obj->newobject = 1; + else + obj->newobject = 0; } #endif diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index 0c867754c..e6d361c8d 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -225,21 +225,6 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { return -1; } -static char const_name[] = "swig_runtime_data_type_pointer"; -static swig_module_info *SWIG_Php_GetModule() { - zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1); - if (pointer) { - if (Z_TYPE_P(pointer) == IS_LONG) { - return (swig_module_info *) pointer->value.lval; - } - } - return NULL; -} - -static void SWIG_Php_SetModule(swig_module_info *pointer) { - REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, CONST_PERSISTENT | CONST_CS); -} - static void SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *type, zend_object *std) { @@ -266,3 +251,19 @@ static inline swig_object_wrapper * php_fetch_object(zend_object *obj) { return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std)); } + +static char const_name[] = "swig_runtime_data_type_pointer"; +static swig_module_info *SWIG_Php_GetModule() { + zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1); + if (pointer) { + if (Z_TYPE_P(pointer) == IS_LONG) { + return (swig_module_info *) pointer->value.lval; + } + } + return NULL; +} + +static void SWIG_Php_SetModule(swig_module_info *pointer) { + REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, CONST_PERSISTENT | CONST_CS); +} + diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index e321ef697..4b79868ed 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -555,7 +555,7 @@ public: Language::top(n); if (Len(classes) > 0) - Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n"); + Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); SwigPHP_emit_resource_registrations(); SwigPHP_emit_all_creation_free_wrapper(); @@ -727,7 +727,7 @@ public: Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry, " SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n" " SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n" - " { NULL, NULL, NULL }\n};\n\n", NIL); + " ZEND_FE_END\n};\n\n", NIL); Printv(f_begin, s_init, NIL); Delete(s_header); Delete(s_wrappers); @@ -1288,8 +1288,11 @@ public: */ if (Cmp(strrchr(GetChar(n, "sym:name"),'_'),"_set") == 0) static_setter = true; - else - static_getter = true; + else if (Cmp(strrchr(GetChar(n, "sym:name"),'_'),"_get") == 0) { + // This is to overcome types that can't be set and hence no setter. + if (Cmp(Getattr(n, "feature:warnfilter"),"462") != 0) + static_getter = true; + } } else if (wrapperType == staticmemberfn) { char *ptr = Char(iname); @@ -1303,6 +1306,7 @@ public: String *intermediate_method_name = NewString(iname); Replace(intermediate_method_name, intermediate_name, "", DOH_REPLACE_FIRST); wname = intermediate_method_name; + //Printf(s_oinit, "ASd %s %s %s\n", iname, name ,wname); Delete(intermediate_name); } else @@ -1405,16 +1409,6 @@ public: if (wrapperType == directorconstructor) Printf(f->code, "zval * arg0 = getThis();\n \n"); - String *retType_class = NULL; - bool retType_valid = is_class(d); - - if (retType_valid) { - retType_class = get_class_name(d); - Chop(retType_class); - Printf(f->code, "\nswig_object_wrapper *obj = NULL;\n"); - Printf(f->code, "\nHashTable * ht = NULL;\n"); - } - /* Now convert from PHP to C variables */ // At this point, argcount if used is the number of deliberately passed args // not including this_ptr even if it is used. @@ -1572,6 +1566,16 @@ public: Setattr(n, "wrap:name", wname); } + String *retType_class = NULL; + bool retType_valid = is_class(d); + bool retType_operator = false; + + if (retType_valid) { + retType_class = get_class_name(d); + Chop(retType_class); + retType_operator = Getattr(n, "conversion_operator") ? true : false; + } + /* emit function call */ String *actioncode = emit_action(n); @@ -1587,7 +1591,7 @@ public: Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class); String *ret_other_Zend_obj = NewStringEmpty(); Printf(ret_other_Zend_obj, "zend_objects_new(%s_ce)", retType_class); - Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (newobject ? retZend_obj : ret_other_Zend_obj)) : "NULL"); + Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (newobject ? retZend_obj : (retType_operator ? retZend_obj : ret_other_Zend_obj))) : "NULL"); } Replaceall(tm, "$zend_obj", "NULL"); Replaceall(tm, "$newobj", retType_valid ? "1" : "2"); @@ -1606,23 +1610,20 @@ public: Printv(f->code, cleanup, NIL); } - if (constructor) { - Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(getThis());\nobj->ptr = (void *)result;\n\n"); - Printf(f->code,"ht = Z_OBJ_HT_P(getThis())->get_properties(getThis());\n"); - Printf(f->code,"if(ht) {\nzval zv;\n"); - Printf(f->code,"ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d)); - Printf(f->code,"zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n"); - } - else if (retType_valid) { - Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value);\nobj->ptr = (void *)result;\n\n"); - Printf(f->code,"ht = Z_OBJ_HT_P(return_value)->get_properties(return_value);\n"); - Printf(f->code,"if(ht) {\nzval zv;\n"); - Printf(f->code,"ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d)); - Printf(f->code,"zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n"); + String *zval_ret_obj = constructor ? NewString("getThis()") : NewString("return_value"); + + if (retType_valid && !SwigType_issimple(d)) { + Printf(f->code, "\n{\nswig_object_wrapper *obj = NULL;\n"); + Printf(f->code, "\nHashTable * ht = NULL;\n\n"); + Printf(f->code, "obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(%s);\n", zval_ret_obj); + Printf(f->code, "obj->ptr = (void *)result;\n"); + Printf(f->code, "ht = Z_OBJ_HT_P(%s)->get_properties(%s);\n", zval_ret_obj, zval_ret_obj); + Printf(f->code, "if(ht) {\nzval zv;\n"); + Printf(f->code, "ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d)); + Printf(f->code, "zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n"); + Printf(f->code, "if (obj)\nobj->newobject = %d;\n}\n\n", newobject ? 1 : 0); } - if (retType_valid) - Printf(f->code, "if (obj)\nobj->newobject = %d;\n", newobject ? 1 : 0); /* Look to see if there is any newfree cleanup code */ if (GetFlag(n, "feature:new")) { if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) { @@ -2670,7 +2671,7 @@ done: class_name = className; if (Len(classes) != 0) - Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n"); + Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name); @@ -2735,7 +2736,32 @@ done: } if (Cmp(symname,className) != 0) { - Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",class_name, class_name, class_name); + Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",symname, symname, symname); + } + + { + Node *node = NewHash(); + Setattr(node, "type", Getattr(n, "name")); + Setfile(node, Getfile(n)); + Setline(node, Getline(n)); + String *interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0); + Replaceall(interfaces, " ", ""); + if (interfaces) { + List *interface_list = Split(interfaces, ',', -1); + int num_interfaces = Len(interface_list); + String *append_interface = NewStringEmpty(); + for(int Iterator = 1; Iterator <= num_interfaces; Iterator++) { + String *interface = Getitem(interface_list, Iterator-1); + String *interface_ce = NewStringEmpty(); + Printf(interface_ce, "php_interface_ce_%d" , Iterator); + Printf(s_oinit, "zend_class_entry *%s = zend_lookup_class(zend_string_init(\"%s\", sizeof(\"%s\") - 1, 0));\n", interface_ce , interface, interface); + Append(append_interface, interface_ce); + Append(append_interface, " "); + } + Chop(append_interface); + Replaceall(append_interface, " ", ","); + Printf(s_oinit, "zend_class_implements(%s_ce, %d, %s);\n", class_name, num_interfaces, append_interface); + } } Printf(s_oinit, "%s_ce->create_object = %s_object_new;\n", class_name, class_name); @@ -3038,17 +3064,22 @@ done: String *iname = GetChar(n, "sym:name"); ParmList *l = Getattr(n, "parms"); + String *name_prefix = NewString("delete_"); + String *intermediate_name = NewString(iname); + Replace(intermediate_name, name_prefix, "", DOH_REPLACE_FIRST); + String *destructorname = NewStringEmpty(); Printf(destructorname, "_%s", Swig_name_wrapper(iname)); Setattr(classnode, "destructor", destructorname); Wrapper *f = NewWrapper(); + Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n"); Printf(f->def, "/* to typecast and do the actual destruction */\n"); Printf(f->def, "static void %s(zend_resource *res, const char *type_name) {\n", destructorname); - Printf(f->code, "if(zend_lookup_class(zend_string_init(\"%s\",sizeof(\"%s\")-1,0))) {\n", name, name); - Printf(f->code, "return;\n}\n\n"); + Printf(f->def, "\n\nif(zend_lookup_class(zend_string_init(\"%s\",sizeof(\"%s\")-1,0))) {\n", intermediate_name, intermediate_name); + Printf(f->def, "return;\n}\n"); Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) res->ptr", NIL); Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);