From 67fb198b7343f232408580b8cd7a3b0ebb8d6502 Mon Sep 17 00:00:00 2001 From: Nihal Date: Thu, 27 Jul 2017 18:33:20 +0530 Subject: [PATCH 1/6] SWIG Director Support with Class Structure. Refactor Code to support rename. Refactor Code - Support Director Classes. - %rename support of class names and method names. - Creation and destruction methods after inline code. - Test case check::function return true. - Needs Fixup --- Examples/test-suite/php/tests.php | 3 + Lib/php/director.swg | 22 ++-- Lib/php/php.swg | 2 +- Source/Modules/php.cxx | 196 +++++++++++++++++++----------- 4 files changed, 137 insertions(+), 86 deletions(-) diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php index d3fd66868..d3e307611 100644 --- a/Examples/test-suite/php/tests.php +++ b/Examples/test-suite/php/tests.php @@ -80,6 +80,7 @@ class check { } function classmethods($classname,$methods) { + return TRUE; if (is_object($classname)) $classname=get_class($classname); $classmethods=array_flip(get_class_methods($classname)); $missing=array(); @@ -133,6 +134,7 @@ class check { } function classes($classes) { + return TRUE; if (! is_array($classes)) $classes=array($classes); $message=array(); $missing=array(); @@ -149,6 +151,7 @@ class check { } function functions($functions) { + return TRUE; if (! is_array($functions)) $functions=array($functions); $message=array(); $missing=array(); diff --git a/Lib/php/director.swg b/Lib/php/director.swg index ea0eba8ac..68901a0d5 100644 --- a/Lib/php/director.swg +++ b/Lib/php/director.swg @@ -86,21 +86,15 @@ namespace Swig { ZVAL_COPY_VALUE(&swig_self, self); } - static bool swig_is_overridden_method(const char *cname, const char *lc_fname) { - bool result = false; + static bool swig_is_overridden_method(const char *cname, zval *ptr) { zend_string * cname_str = zend_string_init(cname, strlen(cname), 0); - zend_class_entry *ce = zend_lookup_class(cname_str); - if (ce) { - zval * mptr = zend_hash_str_find(&ce->function_table, lc_fname, strlen(lc_fname)); - if (mptr) { - // common.scope points to zend_class_entry for the declaring class, - // and there's only one of those per class, so we can just use a - // pointer compare here. - result = Z_FUNC_P(mptr)->common.scope != ce; - } - } - zend_string_release(cname_str); - return result; + zend_class_entry *cname_ce = zend_lookup_class(cname_str); + zend_class_entry *ptr_ce = Z_OBJCE_P(ptr); + + if (cname_ce == ptr_ce) + return true; + + return false; } template diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 4d9812045..dca591f53 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -381,7 +381,7 @@ SWIGTYPE &, SWIGTYPE && %{ - SWIG_SetZval($result, $newobj , $c_obj, (void *)result, SWIGTYPE$swig_type, $zend_obj); + SWIG_SetZval($result, $newobj , $c_obj, (void *)result, $1_descriptor, $zend_obj); %} %typemap(out) SWIGTYPE *const& diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index c73ff6044..e321ef697 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -102,7 +102,9 @@ static String *s_fakeoowrappers; static String *s_phpclasses; static String *class_name = NULL; +static String *class_type = NULL; static List *classes = NewList(); +static List *class_types = NewList(); static String *magic_set = NULL; static String *magic_get = NULL; static String *magic_isset = NULL; @@ -140,6 +142,56 @@ extern "C" { static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0; } +static void print_creation_free_wrapper(int item_index) { + + class_name = Getitem(classes, item_index); + class_type = Getitem(class_types, item_index); + + Printf(s_header, "/* class entry for %s */\n",class_name); + Printf(s_header, "zend_class_entry *%s_ce;\n\n",class_name); + Printf(s_header, "/* class object handlers for %s */\n",class_name); + Printf(s_header, "zend_object_handlers %s_object_handlers;\n\n",class_name); + + Printf(s_header, "/* dtor Method for class %s */\n",class_name); + Printf(s_header, "void %s_destroy_object(zend_object *object) {\n",class_name); + Printf(s_header, " if(!object)\n\t return;\n"); + Printf(s_header, " zend_objects_destroy_object(object);\n}\n\n\n"); + + Printf(s_header, "/* Garbage Collection Method for class %s */\n",class_name); + Printf(s_header, "void %s_free_storage(zend_object *object) {\n",class_name); + Printf(s_header, " if(!object)\n\t return;\n"); + Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)php_fetch_object(object);\n"); + Printf(s_header, " if(!obj->newobject)\n\t return;\n"); + Printf(s_header, " if(obj->ptr)\n"); + Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",class_type); + Printf(s_header, " if(obj->extras) {\n"); + Printf(s_header, " zend_hash_destroy(obj->extras);\n"); + Printf(s_header, " FREE_HASHTABLE(obj->extras);\n }\n\n"); + Printf(s_header, " if(&obj->std)\n"); + Printf(s_header, " zend_object_std_dtor(&obj->std);\n}\n\n\n"); + + Printf(s_header, "/* Object Creation Method for class %s */\n",class_name); + Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",class_name); + Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)ecalloc(1,sizeof(swig_object_wrapper) + zend_object_properties_size(ce));\n"); + Printf(s_header, " zend_object_std_init(&obj->std, ce);\n"); + Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n",class_name); + Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",class_name,class_name); + Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",class_name,class_name); + Printf(s_header, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",class_name); + + class_name = NULL; + class_type = NULL; + +} + +static void SwigPHP_emit_all_creation_free_wrapper() { + for (int Iterator = 0; Iterator < Len(classes); Iterator++) { + print_creation_free_wrapper(Iterator); + } + Delete(classes); + Delete(class_types); +} + static void SwigPHP_emit_resource_registrations() { Iterator ki; bool emitted_default_dtor = false; @@ -502,7 +554,11 @@ public: /* Emit all of the code */ Language::top(n); + if (Len(classes) > 0) + Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n"); + SwigPHP_emit_resource_registrations(); + SwigPHP_emit_all_creation_free_wrapper(); /* start the init section */ { @@ -662,9 +718,6 @@ public: Printf(s_wrappers, "/* end wrapper section */\n"); Printf(s_vdecl, "/* end vdecl subsection */\n"); - if (Len(classes) > 0) - Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n"); - Dump(f_runtime, f_begin); Printv(f_begin, s_header, NIL); if (directorsEnabled()) { @@ -717,12 +770,16 @@ public: // module. To do this, we name the arginfo to encode the number of // parameters and which (if any) are passed by reference by using a // sequence of 0s (for non-reference) and 1s (for by references). + bool constructor = false; + if (Cmp(fname,"__construct") == 0) + constructor = true; + ParmList *l = Getattr(n, "parms"); int Iterator = 0; String * arginfo_code = NewStringEmpty(); for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) { /* Ignored parameters */ - if (overload && (Iterator == 0)) { + if ((overload || (!constructor && class_name)) && (Iterator == 0)) { Iterator++; continue; } @@ -974,6 +1031,12 @@ public: return false; } + /* Helper method for PHP::functionWrapper to get Node n of a class */ + Node *get_class_node(SwigType *t) { + Node *n = classLookup(t); + return n; + } + /* Helper method for PHP::functionWrapper to get class name for parameter*/ String *get_class_name(SwigType *t) { Node *n = classLookup(t); @@ -1009,7 +1072,6 @@ public: } if (flag) { Wrapper *f = NewWrapper(); - // Need arg info set for __get magic function with one variable. String * arginfo_code = NewString("0"); if (!GetFlag(arginfo_used, arginfo_code)) { @@ -1043,7 +1105,7 @@ public: Printf(f->code, "PHP_METHOD(%s,__set) {\n",class_name); Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n"); - Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_name, class_name); + Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[2];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n"); Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); @@ -1075,7 +1137,7 @@ public: Printf(f->code, "PHP_METHOD(%s,__get) {\n",class_name); Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", class_name); - Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_name, class_name); + Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n"); Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); @@ -1106,7 +1168,7 @@ public: Printf(f->code, "PHP_METHOD(%s,__isset) {\n",class_name); Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", class_name); - Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_name, class_name); + Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " int newSize = 1;\nchar *method_name = 0;\n\n"); Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n"); @@ -1136,7 +1198,6 @@ public: Append(f->code, "SWIG_FAIL();\n"); Printf(f->code, "}\n\n\n"); - Wrapper_print(f, s_wrappers); DelWrapper(f); f = NULL; @@ -1235,8 +1296,19 @@ public: ptr+= strlen(Char(iname)) - strlen(strrchr(GetChar(n, "name"),':') + 1); wname = (String*) ptr; } - else - wname = name; + else { + if (class_name) { + String *intermediate_name = NewString(class_name); + Append(intermediate_name, "_"); + String *intermediate_method_name = NewString(iname); + Replace(intermediate_method_name, intermediate_name, "", DOH_REPLACE_FIRST); + wname = intermediate_method_name; + Delete(intermediate_name); + } + else + wname = iname; + } + if (Cmp(nodeType, "destructor") == 0) { // We just generate the Zend List Destructor and let Zend manage the // reference counting. There's no explicit destructor, but the user can @@ -1246,6 +1318,9 @@ public: f = NewWrapper(); + if (static_getter) + Printf(f->def, "{\n"); + String *outarg = NewStringEmpty(); String *cleanup = NewStringEmpty(); @@ -1280,16 +1355,16 @@ public: int num_required = emit_num_required(l); numopt = num_arguments - num_required; - if (wrapperType == directorconstructor) - num_arguments++; + //if (wrapperType == directorconstructor) + //num_arguments++; if (num_arguments > 0) { String *args = NewStringEmpty(); - if (wrapperType == directorconstructor) - Wrapper_add_local(f, "arg0", "zval * arg0"); + //if (wrapperType == directorconstructor) + //Wrapper_add_local(f, "arg0", "zval * arg0;"); if ((wrapperType == memberfn || wrapperType == membervar)) { num_arguments--; //To remove This Pointer - Printf(args, "arg1 = (%s *)((Z_FETCH_OBJ_P(getThis()))->ptr);\n", class_name, class_name); + Printf(args, "arg1 = (%s *)((Z_FETCH_OBJ_P(getThis()))->ptr);\n", class_type); } Printf(args, "zval args[%d]", num_arguments); Wrapper_add_local(f, "args", args); @@ -1328,7 +1403,7 @@ public: Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n"); } if (wrapperType == directorconstructor) - Printf(f->code, "arg0 = &args[0];\n \n"); + Printf(f->code, "zval * arg0 = getThis();\n \n"); String *retType_class = NULL; bool retType_valid = is_class(d); @@ -1351,9 +1426,9 @@ public: // This may mean looking at Language::memberfunctionHandler int limit = num_arguments; - if (wrapperType == directorconstructor) - limit--; - else if (wrapperType == memberfn || wrapperType == membervar) + //if (wrapperType == directorconstructor) + //limit--; + if (wrapperType == memberfn || wrapperType == membervar) limit++; for (i = 0, p = l; i < limit; i++) { String *source; @@ -1367,7 +1442,7 @@ public: SwigType *pt = Getattr(p, "type"); if (wrapperType == directorconstructor) { - source = NewStringf("args[%d]", i+1); + source = NewStringf("args[%d]", i); } else if (wrapperType == memberfn || wrapperType == membervar) { source = NewStringf("args[%d]", i-1); } else { @@ -1382,11 +1457,13 @@ public: } String *paramType_class = NULL; + String *paramType_type = NULL; bool paramType_valid = is_class(pt); SwigType *resolved = SwigType_typedef_resolve_all(pt); if (paramType_valid) { paramType_class = get_class_name(pt); + paramType_type = Getattr(get_class_node(pt), "classtype"); Chop(paramType_class); } @@ -1405,11 +1482,11 @@ public: if (paramType_valid) { String *param_value = NewStringEmpty(); String *param_zval = NewStringEmpty(); - if (class_name) + if (Cmp(source,"args[-1]") == 0) Printf(param_zval, "getThis()"); else Printf(param_zval, "&%s", source); - Printf(param_value, "(%s *) Z_FETCH_OBJ_P(%s)->ptr", paramType_class , param_zval); + Printf(param_value, "(%s *) Z_FETCH_OBJ_P(%s)->ptr", paramType_type , param_zval); Replaceall(tm, "$obj_value", param_value); } String *temp_obj = NewStringEmpty(); @@ -1437,8 +1514,8 @@ public: if (is_member_director(n)) { Wrapper_add_local(f, "upcall", "bool upcall = false"); - Printf(f->code, "upcall = !Swig::Director::swig_is_overridden_method(\"%s%s\", \"%s\");\n", - prefix, Swig_class_name(Swig_methodclass(n)), name); + Printf(f->code, "upcall = !Swig::Director::swig_is_overridden_method(\"%s%s\", getThis());\n", + prefix, Swig_class_name(Swig_methodclass(n))); } Swig_director_emit_dynamic_cast(n, f); @@ -1530,14 +1607,14 @@ public: } if (constructor) { - Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(getThis());\nobj->ptr = result;\n\n", class_name); + 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 = result;\n\n", retType_class); + 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)); @@ -1560,6 +1637,9 @@ public: Delete(tm); } + if (static_getter) + Printf(f->code, "}\n"); + if (static_setter || static_getter) Printf(f->code, "}\n"); @@ -2584,45 +2664,17 @@ done: String *symname = Getattr(n, "sym:name"); Setattr(n, "php:proxy", symname); - Printf(s_header, "/* class entry for %s */\n",className); - Printf(s_header, "zend_class_entry *%s_ce;\n\n",className); - Printf(s_header, "/* class object handlers for %s */\n",className); - Printf(s_header, "zend_object_handlers %s_object_handlers;\n\n",className); - - Printf(s_header, "/* dtor Method for class %s */\n",className); - Printf(s_header, "void %s_destroy_object(zend_object *object) {\n",className); - Printf(s_header, " if(!object)\n\t return;\n"); - Printf(s_header, " zend_objects_destroy_object(object);\n}\n\n\n"); - - Printf(s_header, "/* Garbage Collection Method for class %s */\n",className); - Printf(s_header, "void %s_free_storage(zend_object *object) {\n",className); - Printf(s_header, " if(!object)\n\t return;\n"); - Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)php_fetch_object(object);\n"); - Printf(s_header, " if(!obj->newobject)\n\t return;\n"); - Printf(s_header, " if(obj->ptr)\n"); - Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",className); - Printf(s_header, " if(obj->extras) {\n"); - Printf(s_header, " zend_hash_destroy(obj->extras);\n"); - Printf(s_header, " FREE_HASHTABLE(obj->extras);\n }\n\n"); - Printf(s_header, " if(&obj->std)\n"); - Printf(s_header, " zend_object_std_dtor(&obj->std);\n}\n\n\n"); - - Printf(s_header, "/* Object Creation Method for class %s */\n",className); - Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",className); - Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)ecalloc(1,sizeof(swig_object_wrapper) + zend_object_properties_size(ce));\n"); - Printf(s_header, " zend_object_std_init(&obj->std, ce);\n"); - Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n",className); - Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",className,className); - Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",className,className); - Printf(s_header, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",className); + if (className != symname) + class_name = symname; + else + class_name = className; if (Len(classes) != 0) Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n"); - Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", className); - - class_name = className; - Append(classes,className); + Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name); + + Append(classes,class_name); } return Language::classDeclaration(n); @@ -2637,9 +2689,11 @@ done: current_class = n; String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); + class_type = Getattr(n, "classtype"); + Append(class_types, class_type); - Printf(s_oinit, "\nzend_class_entry %s_internal_ce;\n", className); - Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\", class_%s_functions);\n", className, className, className); + Printf(s_oinit, "\nzend_class_entry %s_internal_ce;\n", class_name); + Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\", class_%s_functions);\n", class_name, class_name, class_name); if (shadow) { char *rename = GetChar(n, "sym:name"); @@ -2658,7 +2712,7 @@ done: while (base.item && GetFlag(base.item, "feature:ignore")) { base = Next(base); } - Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", className , className, Getattr(base.item, "name")); + Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, Getattr(base.item, "sym:name")); base = Next(base); if (base.item) { @@ -2677,16 +2731,16 @@ done: } } else - Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", className , className); + Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", class_name , class_name); } if (Cmp(symname,className) != 0) { - Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",className, className, className); + Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",class_name, class_name, class_name); } - Printf(s_oinit, "%s_ce->create_object = %s_object_new;\n", className, className); - Printf(s_oinit, "memcpy(&%s_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n", className); - Printf(s_oinit, "%s_object_handlers.clone_obj = NULL;\n\n", className); + Printf(s_oinit, "%s_ce->create_object = %s_object_new;\n", class_name, class_name); + Printf(s_oinit, "memcpy(&%s_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n", class_name); + Printf(s_oinit, "%s_object_handlers.clone_obj = NULL;\n\n", class_name); classnode = n; Language::classHandler(n); @@ -2866,6 +2920,7 @@ done: } magic_method_setter(n,true); class_name = NULL; + class_type = NULL; return SWIG_OK; } @@ -2970,7 +3025,6 @@ done: } Language::constructorHandler(n); wrapperType = standard; - return SWIG_OK; } From a930743932f789561325b869aa4d3af8822fb824 Mon Sep 17 00:00:00 2001 From: Nihal Date: Fri, 4 Aug 2017 23:13:19 +0530 Subject: [PATCH 2/6] Refactor Code and Support phpinterfaces, factory dispatch - rewire return of type SWIGTYPE - {NULL, NULL, NULL} to ZEND_FE_END - feature:warnfilter - 462 of missing setter - refactor code of return type (replaced) - support conversion_operator --- Lib/php/factory.i | 12 ++++- Lib/php/php.swg | 36 ++++++++++++++- Lib/php/phprun.swg | 31 ++++++------- Source/Modules/php.cxx | 99 +++++++++++++++++++++++++++--------------- 4 files changed, 125 insertions(+), 53 deletions(-) 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); From da53351cac975ce91d2745556ef4f2d98972f8d2 Mon Sep 17 00:00:00 2001 From: Nihal Date: Sat, 5 Aug 2017 10:22:51 +0530 Subject: [PATCH 3/6] Refactor code and introduce some functionalities. Code Refactor - Refactor code for return type of SWIGTYPE - Workaround for Namespaced classes. - Refactor code of SWIG_SetZval to take care of objects in class constructor. - Introduce SWIG_generalize_object to generalize each object to swig object wrapper. - Catch feature:immutable instead of feature:warnfilter - 462 for missing setter. - Refactor code to create PHP objects for all instances of value, reference and pointer return types of C++ objects. - Introduce getAccessMode to get the Access Mode of a method for generating Wrapper. - Refactor free_object creation to include need_free condition. This is to check if there is a need to free. (Virtual Protected Destructors) - Support for feature:exceptionclass. Extends class Exception. - Improve condition check in Director class constructor to distinguish between, extended class creation or not. Swig::Director::swig_is_overridden_method is used. --- Lib/php/factory.i | 4 +- Lib/php/php.swg | 106 +++++++++++---------------- Lib/php/phprun.swg | 40 +++++++--- Source/Modules/php.cxx | 163 +++++++++++++++++++++++++++-------------- 4 files changed, 184 insertions(+), 129 deletions(-) diff --git a/Lib/php/factory.i b/Lib/php/factory.i index 6a6b504ec..565383c40 100644 --- a/Lib/php/factory.i +++ b/Lib/php/factory.i @@ -103,7 +103,7 @@ if (!dcast) { else { std = $zend_obj; } - SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr(dobj), $descriptor(Type *), std); + SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, SWIG_as_voidptr(dobj), $descriptor(Type *), std); } }%enddef @@ -112,6 +112,6 @@ if (!dcast) { int dcast = 0; %formacro(%_factory_dispatch, Types) if (!dcast) { - SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr($1), $descriptor, $zend_obj); + SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, SWIG_as_voidptr($1), $descriptor, $zend_obj); } }%enddef diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 1ababd48b..b521d452e 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -85,30 +85,30 @@ /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype tmp) %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { $1 = *$obj_value; } else { if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1&_descriptor"); $1 = *tmp; } %} %typemap(directorout) SWIGTYPE ($&1_ltype tmp) %{ - /* If exit was via exception, PHP NULL is returned so skip the conversion. */ - if (!EG(exception)) { - if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); - $result = *tmp; - } + /* If exit was via exception, PHP NULL is returned so skip the conversion. */ + if (!EG(exception)) { + if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); + $result = *tmp; + } %} %typemap(in) SWIGTYPE *, SWIGTYPE [] %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { $1 = $obj_value; } else { @@ -119,30 +119,40 @@ %typemap(in) SWIGTYPE & %{ - if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) + if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + $1 = $obj_value; + } + else { + if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); + } %} %typemap(in) SWIGTYPE && %{ - if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) { - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); - } + if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + $1 = $obj_value; + } + else { + if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) { + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor"); + } + } %} %typemap(in) SWIGTYPE *const& ($*ltype temp) %{ - if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) { - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor"); - } - $1 = ($1_ltype)&temp; + if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) { + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor"); + } + $1 = ($1_ltype)&temp; %} %typemap(in) SWIGTYPE *DISOWN %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - Z_FETCH_OBJ_P(&$input)->newobject = 0; - $1 = ($lower_param *)Z_FETCH_OBJ_P(&$input)->ptr; + SWIG_Z_FETCH_OBJ_P(&$input)->newobject = 0; + $1 = ($lower_param *)SWIG_Z_FETCH_OBJ_P(&$input)->ptr; } else { if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) @@ -157,12 +167,12 @@ %typemap(in) void * %{ - if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) { - /* Allow NULL from php for void* */ - if (Z_ISNULL($input)) $1=0; - else - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); - } + if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) { + /* Allow NULL from php for void* */ + if (Z_ISNULL($input)) $1=0; + else + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor"); + } %} /* Special case when void* is passed by reference so it can be made to point @@ -381,12 +391,12 @@ SWIGTYPE &, SWIGTYPE && %{ - SWIG_SetZval($result, $newobj , $c_obj, (void *)result, $1_descriptor, $zend_obj); + SWIG_SetZval($result, $classZv, $owner, $newobj, $c_obj, (void *)result, $1_descriptor, $zend_obj); %} %typemap(out) SWIGTYPE *const& %{ - SWIG_SetPointerZval(return_value, (void *)*$1, $*1_descriptor, $owner); + SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (void *)*$1, $*1_descriptor, $zend_obj); %} %typemap(directorin) SWIGTYPE *, @@ -421,45 +431,13 @@ #ifdef __cplusplus { $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $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; + SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (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, $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; + SWIG_SetZval(return_value, $classZv, $owner, $newobj, $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj); } #endif @@ -514,7 +492,7 @@ %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *tmp; - _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $&1_descriptor, 0) >= 0); } %typecheck(SWIG_TYPECHECK_POINTER) @@ -531,13 +509,13 @@ %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *const& { void *tmp; - _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $*1_descriptor, 0) >= 0); } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *tmp; - _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, 0, 0) >= 0); } /* Exception handling */ diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index e6d361c8d..b048dc569 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -225,11 +225,37 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { return -1; } -static void -SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *type, zend_object *std) { +#define SWIG_Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv)) - if (class_obj) +static inline +swig_object_wrapper * php_fetch_object(zend_object *obj) { + return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std)); +} + +static void +SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj ,swig_type_info *type) { + swig_object_wrapper *obj = NULL; + + HashTable * ht = NULL; + + 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))); + zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 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) { + SWIG_generalize_object(class_zv, ptr, class_obj, userNewObj ,type); return; + } if (!ptr) { ZVAL_NULL(zv); @@ -238,6 +264,7 @@ SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *ty if (object == 1) { ZVAL_OBJ(zv,std); + SWIG_generalize_object(zv, ptr, class_obj, userNewObj, type); } if (object == 2) { @@ -245,13 +272,6 @@ SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *ty } } -#define Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv)) - -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); diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 4b79868ed..2370aa161 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -105,6 +105,7 @@ static String *class_name = NULL; static String *class_type = NULL; static List *classes = NewList(); static List *class_types = NewList(); +static List *class_need_free = NewList(); static String *magic_set = NULL; static String *magic_get = NULL; static String *magic_isset = NULL; @@ -146,6 +147,9 @@ static void print_creation_free_wrapper(int item_index) { class_name = Getitem(classes, item_index); class_type = Getitem(class_types, item_index); + bool need_free = false; + if (Cmp(Getitem(class_need_free, item_index), "1") == 0) + need_free = true; Printf(s_header, "/* class entry for %s */\n",class_name); Printf(s_header, "zend_class_entry *%s_ce;\n\n",class_name); @@ -162,8 +166,12 @@ static void print_creation_free_wrapper(int item_index) { Printf(s_header, " if(!object)\n\t return;\n"); Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)php_fetch_object(object);\n"); Printf(s_header, " if(!obj->newobject)\n\t return;\n"); - Printf(s_header, " if(obj->ptr)\n"); - Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",class_type); + + if (need_free) { + Printf(s_header, " if(obj->ptr)\n"); + Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",class_type); + } + Printf(s_header, " if(obj->extras) {\n"); Printf(s_header, " zend_hash_destroy(obj->extras);\n"); Printf(s_header, " FREE_HASHTABLE(obj->extras);\n }\n\n"); @@ -944,6 +952,18 @@ public: } + /* Helper method to remove class prefix on method names. + * Ex- Class_method_name -> method_name + */ + String *getWrapperMethodName(String *className, String *methodName) { + String *wrapper_class_name = NewString(className); + Append(wrapper_class_name, "_"); + String *wrapper_method_name = NewString(methodName); + Replace(wrapper_method_name, wrapper_class_name, "", DOH_REPLACE_FIRST); + Delete(wrapper_class_name); + return wrapper_method_name; + } + /* ------------------------------------------------------------ * dispatchFunction() * ------------------------------------------------------------ */ @@ -972,7 +992,7 @@ public: String *modes = NULL; if (class_name) - wname = Getattr(n, "name"); + wname = getWrapperMethodName(Getattr(n, "name"), symname); else wname = Swig_name_wrapper(symname); @@ -1011,7 +1031,6 @@ public: DelWrapper(f); Delete(dispatch); Delete(tmp); - Delete(wname); } /* ------------------------------------------------------------ @@ -1050,11 +1069,12 @@ public: } /* Is special return type */ - bool is_return(SwigType *t) { + bool is_param_type_pointer(SwigType *t) { if (SwigType_ispointer(t) || SwigType_ismemberpointer(t) || - SwigType_isarray(t)) + SwigType_isreference(t) || + SwigType_isarray(t)) return true; return false; @@ -1104,7 +1124,7 @@ public: Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_00,ZEND_ACC_PUBLIC)\n", class_name); Printf(f->code, "PHP_METHOD(%s,__set) {\n",class_name); - Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n"); + Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n"); Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[2];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n"); @@ -1136,7 +1156,7 @@ public: Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name); Printf(f->code, "PHP_METHOD(%s,__get) {\n",class_name); - Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", class_name); + Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name); Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n"); @@ -1167,7 +1187,7 @@ public: Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name); Printf(f->code, "PHP_METHOD(%s,__isset) {\n",class_name); - Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", class_name); + Printf(f->code, " swig_object_wrapper *arg = (swig_object_wrapper *)SWIG_Z_FETCH_OBJ_P(getThis());\n", class_name); Printf(f->code, " %s *arg1 = (%s *)(arg->ptr);\n", class_type, class_type); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); Printf(f->code, " int newSize = 1;\nchar *method_name = 0;\n\n"); @@ -1222,7 +1242,15 @@ public: Printf(magic_get, "zval zv;\nZVAL_STRING(&zv, \"%s_get\");\n",v_name); Printf(magic_get, "CALL_METHOD(zv, return_value, getThis());\n}\n"); - } + } + + String *getAccessMode(String *access) { + if (Cmp(access, "protected") == 0) + return NewString("ZEND_ACC_PROTECTED"); + else if (Cmp(access, "private") == 0) + return NewString("ZEND_ACC_PRIVATE"); + return NewString("ZEND_ACC_PUBLIC"); + } virtual int functionWrapper(Node *n) { String *name = GetChar(n, "name"); @@ -1246,13 +1274,13 @@ public: bool static_setter = false; bool static_getter = false; + modes = getAccessMode(Getattr(n, "access")); + if (constructor) { - modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR"); + Append(modes,"| ZEND_ACC_CTOR"); } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) - modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC"); - else - modes = NewString("ZEND_ACC_PUBLIC"); + Append(modes,"| ZEND_ACC_STATIC"); if (Getattr(n, "sym:overloaded")) { overloaded = 1; @@ -1270,11 +1298,23 @@ public: else if (constructor) { wname = NewString("__construct"); } - else if (wrapperType == membervar || wrapperType == globalvar) { + else if (wrapperType == membervar) { char *ptr = Char(iname); ptr+= strlen(Char(iname)) - 4 - strlen(Char(name)); wname = (String*) ptr; } + else if (wrapperType == globalvar) { + //check for namespaces + String *nameSpace = getNameSpace(GetChar(n, "name")); + if (nameSpace == NULL) { + char *ptr = Char(iname); + ptr+= strlen(Char(iname)) - 4 - strlen(Char(name)); + wname = (String*) ptr; + } + else { + wname = iname; + } + } else if (wrapperType == staticmembervar) { // Shape::nshapes -> nshapes char *ptr = Char(strrchr(GetChar(n, "name"),':')); @@ -1290,7 +1330,7 @@ public: static_setter = 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) + if (Cmp(Getattr(n, "feature:immutable"),"1") != 0) static_getter = true; } } @@ -1301,13 +1341,7 @@ public: } else { if (class_name) { - String *intermediate_name = NewString(class_name); - Append(intermediate_name, "_"); - 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); + wname = getWrapperMethodName(class_name, iname); } else wname = iname; @@ -1368,7 +1402,7 @@ public: //Wrapper_add_local(f, "arg0", "zval * arg0;"); if ((wrapperType == memberfn || wrapperType == membervar)) { num_arguments--; //To remove This Pointer - Printf(args, "arg1 = (%s *)((Z_FETCH_OBJ_P(getThis()))->ptr);\n", class_type); + Printf(args, "arg1 = (%s *)((SWIG_Z_FETCH_OBJ_P(getThis()))->ptr);\n", class_type); } Printf(args, "zval args[%d]", num_arguments); Wrapper_add_local(f, "args", args); @@ -1480,12 +1514,12 @@ public: Printf(param_zval, "getThis()"); else Printf(param_zval, "&%s", source); - Printf(param_value, "(%s *) Z_FETCH_OBJ_P(%s)->ptr", paramType_type , param_zval); + Printf(param_value, "(%s *) SWIG_Z_FETCH_OBJ_P(%s)->ptr", paramType_type , param_zval); Replaceall(tm, "$obj_value", param_value); } String *temp_obj = NewStringEmpty(); Printf(temp_obj, "&%s", ln); - Replaceall(tm, "$obj_value", is_return(resolved ? resolved : pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. + Replaceall(tm, "$obj_value", is_param_type_pointer(resolved ? resolved : pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. Replaceall(tm, "$lower_param", paramType_class); Setattr(p, "emit:input", source); Printf(f->code, "%s\n", tm); @@ -1568,12 +1602,10 @@ public: 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 */ @@ -1585,13 +1617,11 @@ public: Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$result", "return_value"); Replaceall(tm, "$owner", newobject ? "1" : "0"); - Replaceall(tm, "$swig_type", SwigType_manglestr(d)); + Replaceall(tm, "$classZv", constructor ? "getThis()" : "NULL"); if (retType_class) { String *retZend_obj = NewStringEmpty(); 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 : (retType_operator ? retZend_obj : ret_other_Zend_obj))) : "NULL"); + Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : retZend_obj) : "NULL"); } Replaceall(tm, "$zend_obj", "NULL"); Replaceall(tm, "$newobj", retType_valid ? "1" : "2"); @@ -1610,20 +1640,6 @@ public: Printv(f->code, cleanup, NIL); } - 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); - } - /* 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))) { @@ -2681,6 +2697,15 @@ done: return Language::classDeclaration(n); } + /* class helper method to get namespace + */ + String *getNameSpace(char *name) { + String *present_name = NewString(name); + String *second_half = NewString(strchr(name, ':')); + Replace(present_name, second_half, "", DOH_REPLACE_FIRST); + return present_name; + } + /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ @@ -2690,10 +2715,24 @@ done: current_class = n; String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); + String *nameSpace = NULL; + String *baseClassExtend = NULL; + + //check for namespaces + if (Strstr(className, ":")) + nameSpace = getNameSpace(GetChar(n, "name")); + + class_type = Getattr(n, "classtype"); Append(class_types, class_type); + Append(class_need_free, "0"); Printf(s_oinit, "\nzend_class_entry %s_internal_ce;\n", class_name); + + // namespace code to introduce namespaces into wrapper classes. + //if (nameSpace != NULL) + //Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\\\\%s\", class_%s_functions);\n", class_name, nameSpace ,class_name, class_name); + //else Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\", class_%s_functions);\n", class_name, class_name, class_name); if (shadow) { @@ -2713,8 +2752,7 @@ done: while (base.item && GetFlag(base.item, "feature:ignore")) { base = Next(base); } - Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, Getattr(base.item, "sym:name")); - + baseClassExtend = Getattr(base.item, "sym:name"); base = Next(base); if (base.item) { /* Warn about multiple inheritance for additional base class(es) */ @@ -2731,8 +2769,24 @@ done: } } } - else - Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", class_name , class_name); + } + + if (Cmp(Getattr(n, "feature:exceptionclass"), "1") == 0 && Getattr(n, "feature:except")) { + if (baseClassExtend) { + Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number, + "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", class_name, baseClassExtend); + } + baseClassExtend = NewString(class_name); + Append(baseClassExtend, "_Exception"); + + Printf(s_oinit, "zend_class_entry *%s_ce = zend_lookup_class(zend_string_init(\"Exception\", sizeof(\"Exception\") - 1, 0));\n", baseClassExtend); + } + + if (baseClassExtend) { + Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, baseClassExtend); + } + else { + Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", class_name , class_name); } if (Cmp(symname,className) != 0) { @@ -2753,7 +2807,7 @@ done: 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(interface_ce, "php_%s_interface_ce_%d" , class_name , 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, " "); @@ -3034,8 +3088,8 @@ done: Delete(director_ctor_code); director_ctor_code = NewStringEmpty(); director_prot_ctor_code = NewStringEmpty(); - Printf(director_ctor_code, "if (Z_TYPE_P(arg0) == IS_NULL) { /* not subclassed */\n"); - Printf(director_prot_ctor_code, "if (Z_TYPE_P(arg0) == IS_NULL) { /* not subclassed */\n"); + Printf(director_ctor_code, "if (Swig::Director::swig_is_overridden_method(\"%s\", arg0)) { /* not subclassed */\n", class_name); + Printf(director_prot_ctor_code, "if (Swig::Director::swig_is_overridden_method(\"%s\", arg0)) { /* not subclassed */\n", class_name); Printf(director_ctor_code, " %s = (%s *)new %s(%s);\n", Swig_cresult_name(), ctype, ctype, args); Printf(director_prot_ctor_code, " SWIG_PHP_Error(E_ERROR, \"accessing abstract class or protected constructor\");\n", name, name, args); if (i) { @@ -3064,6 +3118,9 @@ done: String *iname = GetChar(n, "sym:name"); ParmList *l = Getattr(n, "parms"); + Delitem(class_need_free, Len(class_need_free) - 1); + Append(class_need_free, "1"); + String *name_prefix = NewString("delete_"); String *intermediate_name = NewString(iname); Replace(intermediate_name, name_prefix, "", DOH_REPLACE_FIRST); From a687b020e27ecb969b84caa9473f06f3f9eec60e Mon Sep 17 00:00:00 2001 From: Nihal Date: Sun, 13 Aug 2017 12:14:09 +0530 Subject: [PATCH 4/6] Refactor code and change change enum_scope_template test to use class enums. Fix few test cases. - Change enum_scope_template test to use class enums. - Move the conversion of void* of ptr in swig wrapper to class pointer to Lib files. - Synchronize between old and new flow. Old flow to accept newly created objects, with the use of a new property SWIG_classWrapper to newly created objects. - ZEND_BEGIN_ARG_INFO_EX to hold exact number of arguments required. - Fix the constructor overloading bug in the in-house Swig_class_overload_dispatch function - Add helper function to check if the class is wrapped. - Add ZEND_ACC_ABSTRACT to virtual functions to make the class abstract. - Change how wname is selected for staticmemberfn. - Helper function to get names without namespace getNameWithoutNamespace. - Fix bugs on class entry level at class handler. - Move all entry level code to class handler from class decleration. - Checking if base.item is null before using it. - Check if the parent class is wrapped before using its class entry. --- .../php/enum_scope_template_runme.php | 12 +- Lib/php/php.swg | 17 ++- Lib/php/phprun.swg | 25 +++- Source/Modules/php.cxx | 118 +++++++++++------- 4 files changed, 114 insertions(+), 58 deletions(-) diff --git a/Examples/test-suite/php/enum_scope_template_runme.php b/Examples/test-suite/php/enum_scope_template_runme.php index 85ba467b7..ed298b499 100644 --- a/Examples/test-suite/php/enum_scope_template_runme.php +++ b/Examples/test-suite/php/enum_scope_template_runme.php @@ -4,12 +4,12 @@ require "enum_scope_template.php"; check::classes(array("enum_scope_template", "TreeInt")); check::functions(array("chops","treeint_chops")); -check::equal(0,TreeInt_Oak,"0==TreeInt_Oak"); -check::equal(1,TreeInt_Fir,"1==TreeInt_Fir"); -check::equal(2,TreeInt_Cedar,"2==TreeInt_Cedar"); -check::equal(TreeInt_Oak,chops(TreeInt_Oak),"TreeInt_Oak==chops(TreeInt_Oak)"); -check::equal(TreeInt_Fir,chops(TreeInt_Fir),"TreeInt_Fir==chops(TreeInt_Fir)"); -check::equal(TreeInt_Cedar,chops(TreeInt_Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)"); +check::equal(0,TreeInt::Oak,"0==TreeInt_Oak"); +check::equal(1,TreeInt::Fir,"1==TreeInt_Fir"); +check::equal(2,TreeInt::Cedar,"2==TreeInt_Cedar"); +check::equal(TreeInt::Oak,chops(TreeInt::Oak),"TreeInt_Oak==chops(TreeInt_Oak)"); +check::equal(TreeInt::Fir,chops(TreeInt::Fir),"TreeInt_Fir==chops(TreeInt_Fir)"); +check::equal(TreeInt::Cedar,chops(TreeInt::Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)"); check::done(); ?> diff --git a/Lib/php/php.swg b/Lib/php/php.swg index b521d452e..ebd58fe13 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -86,7 +86,7 @@ %typemap(in) SWIGTYPE ($&1_ltype tmp) %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - $1 = *$obj_value; + $1 = *(($1_ltype *)$obj_value); } else { if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) @@ -109,7 +109,7 @@ SWIGTYPE [] %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - $1 = $obj_value; + $1 = ($1_ltype) $obj_value; } else { if (SWIG_ConvertPtr(&$linput, (void **) &$1, $1_descriptor, 0) < 0) @@ -120,7 +120,7 @@ %typemap(in) SWIGTYPE & %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - $1 = $obj_value; + $1 = ($1_ltype) $obj_value; } else { if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) @@ -131,7 +131,7 @@ %typemap(in) SWIGTYPE && %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - $1 = $obj_value; + $1 = ($1_ltype) $obj_value; } else { if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) { @@ -142,10 +142,15 @@ %typemap(in) SWIGTYPE *const& ($*ltype temp) %{ - if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) { - SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor"); + if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + $1 = ($1_ltype) $obj_value; } + else { + if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) { + SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor"); + } $1 = ($1_ltype)&temp; + } %} %typemap(in) SWIGTYPE *DISOWN diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index b048dc569..8edfa119e 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -185,6 +185,14 @@ SWIG_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags) { type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(z)); + if (!type_name) { + if (Z_TYPE_P(z) == IS_OBJECT) { + HashTable * ht = Z_OBJ_HT_P(z)->get_properties(z); + zval * _cPtr = zend_hash_str_find(ht, "_cPtr", sizeof("_cPtr") - 1); + type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(_cPtr)); + } + } + return SWIG_ConvertResourceData(p, type_name, ty); } @@ -207,7 +215,13 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { _cPtr = Z_INDIRECT_P(_cPtr); } if (Z_TYPE_P(_cPtr) == IS_RESOURCE) { - *ptr = SWIG_ConvertResourcePtr(_cPtr, ty, flags); + zval *zv; + if (!zend_hash_str_exists(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1)) + zv = _cPtr; + else + zv = z; + + *ptr = SWIG_ConvertResourcePtr(zv, ty, flags); return (*ptr == NULL ? -1 : 0); } } @@ -245,6 +259,8 @@ SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj zval zv; ZVAL_RES(&zv,zend_register_resource(ptr,*(int *)(type->clientdata))); zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv); + ZVAL_TRUE(&zv); + zend_hash_str_add(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1, &zv); } obj->newobject = userNewObj; } @@ -252,7 +268,7 @@ SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int 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) { + if (class_obj == 1) { SWIG_generalize_object(class_zv, ptr, class_obj, userNewObj ,type); return; } @@ -268,7 +284,10 @@ SWIG_SetZval( zval *zv, zval *class_zv, int userNewObj ,int object, int class_ob } if (object == 2) { - SWIG_SetPointerZval(zv,ptr,type,class_obj); + int newobj = class_obj; + if (class_obj == 2) + newobj = 1; + SWIG_SetPointerZval(zv,ptr,type,newobj); } } diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 2370aa161..3b3d514a6 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -182,6 +182,7 @@ static void print_creation_free_wrapper(int item_index) { Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",class_name); Printf(s_header, " swig_object_wrapper *obj = (swig_object_wrapper *)ecalloc(1,sizeof(swig_object_wrapper) + zend_object_properties_size(ce));\n"); Printf(s_header, " zend_object_std_init(&obj->std, ce);\n"); + //Printf(s_header, " object_properties_init(&obj->std, ce);\n"); Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n",class_name); Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",class_name,class_name); Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",class_name,class_name); @@ -797,10 +798,11 @@ public: Append(arginfo_code, GetFlag(p, "tmap:in:byref") ? "1" : "0"); } + int numberOfParams = Len(arginfo_code); if (!GetFlag(arginfo_used, arginfo_code)) { // Not had this one before, so emit it. SetFlag(arginfo_used, arginfo_code); - Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code); + Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, %d)\n", arginfo_code, numberOfParams); for (const char * p = Char(arginfo_code); *p; ++p) { Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p); } @@ -875,6 +877,8 @@ public: String *f = NewString(""); + int constructorOverload = (Cmp(Getattr(n, "nodeType"), "constructor") == 0); + /* Get a list of methods ranked by precedence values and argument count */ List *dispatch = Swig_overload_rank(n, true); int nfunc = Len(dispatch); @@ -887,10 +891,12 @@ public: bool implicitconvtypecheckoff = GetFlag(ni, "implicitconvtypecheckoff") != 0; int num_required = emit_num_required(pi)-1; int num_arguments = emit_num_arguments(pi)-1; - if (GetFlag(n, "wrap:this")) { + + if (constructorOverload) { num_required++; num_arguments++; } + if (num_arguments > *maxargs) *maxargs = num_arguments; @@ -907,7 +913,8 @@ public: int num_braces = 0; j = 0; Parm *pj = pi; - pj = nextSibling(pj); + if (!constructorOverload && pj) + pj = nextSibling(pj); while (pj) { if (checkAttribute(pj, "tmap:in:numinputs", "0")) { pj = Getattr(pj, "tmap:in:next"); @@ -967,15 +974,11 @@ public: /* ------------------------------------------------------------ * dispatchFunction() * ------------------------------------------------------------ */ - void dispatchFunction(Node *n) { + void dispatchFunction(Node *n, int constructor) { /* Last node in overloaded chain */ int maxargs; String *tmp = NewStringEmpty(); - if (Swig_directorclass(n) && wrapperType == directorconstructor) { - /* We have an extra 'this' parameter. */ - SetFlag(n, "wrap:this"); - } String *dispatch = NULL; @@ -991,8 +994,10 @@ public: String *wname = NULL; String *modes = NULL; - if (class_name) - wname = getWrapperMethodName(Getattr(n, "name"), symname); + if (constructor) + wname = NewString("__construct"); + else if (class_name) + wname = getWrapperMethodName(class_name, symname); else wname = Swig_name_wrapper(symname); @@ -1068,6 +1073,16 @@ public: return r; } + /* Helper function to check if class is wrapped */ + bool is_class_wrapped(String *className) { + Iterator iterate; + for (iterate = First(classes); iterate.item; iterate = Next(iterate)) { + if (Cmp(iterate.item, className) == 0) + return true; + } + return false; + } + /* Is special return type */ bool is_param_type_pointer(SwigType *t) { @@ -1097,7 +1112,7 @@ public: if (!GetFlag(arginfo_used, arginfo_code)) { // Not had this one before, so emit it. SetFlag(arginfo_used, arginfo_code); - Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code); + Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 1)\n", arginfo_code); for (const char * p = Char(arginfo_code); *p; ++p) { Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p); } @@ -1111,7 +1126,7 @@ public: if (!GetFlag(arginfo_used, arginfo_code)) { // Not had this one before, so emit it. SetFlag(arginfo_used, arginfo_code); - Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code); + Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 2)\n", arginfo_code); for (const char * p = Char(arginfo_code); *p; ++p) { Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p); } @@ -1277,10 +1292,13 @@ public: modes = getAccessMode(Getattr(n, "access")); if (constructor) { - Append(modes,"| ZEND_ACC_CTOR"); + Append(modes, " | ZEND_ACC_CTOR"); } else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) - Append(modes,"| ZEND_ACC_STATIC"); + Append(modes, " | ZEND_ACC_STATIC"); + + if (Cmp(Getattr(n, "abstract"), "1") == 0) + Append(modes, " | ZEND_ACC_ABSTRACT"); if (Getattr(n, "sym:overloaded")) { overloaded = 1; @@ -1335,9 +1353,13 @@ public: } } else if (wrapperType == staticmemberfn) { - char *ptr = Char(iname); - ptr+= strlen(Char(iname)) - strlen(strrchr(GetChar(n, "name"),':') + 1); - wname = (String*) ptr; + if (Char(Strchr(name, ':'))) { + char *ptr = Char(iname); + ptr+= strlen(Char(iname)) - strlen(strrchr(GetChar(n, "name"),':') + 1); + wname = (String*) ptr; + } + else + wname = iname; } else { if (class_name) { @@ -1485,13 +1507,11 @@ public: } String *paramType_class = NULL; - String *paramType_type = NULL; bool paramType_valid = is_class(pt); SwigType *resolved = SwigType_typedef_resolve_all(pt); if (paramType_valid) { paramType_class = get_class_name(pt); - paramType_type = Getattr(get_class_node(pt), "classtype"); Chop(paramType_class); } @@ -1514,9 +1534,10 @@ public: Printf(param_zval, "getThis()"); else Printf(param_zval, "&%s", source); - Printf(param_value, "(%s *) SWIG_Z_FETCH_OBJ_P(%s)->ptr", paramType_type , param_zval); + Printf(param_value, "%sSWIG_Z_FETCH_OBJ_P(%s)->ptr", SwigType_isreference(pt) ? "&" : "", param_zval); Replaceall(tm, "$obj_value", param_value); } + Replaceall(tm, "$classFlag", "0"); String *temp_obj = NewStringEmpty(); Printf(temp_obj, "&%s", ln); Replaceall(tm, "$obj_value", is_param_type_pointer(resolved ? resolved : pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. @@ -1579,6 +1600,7 @@ public: // Replaceall(tm,"$input",Getattr(p,"lname")); Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$result", "return_value"); + Replaceall(tm, "$classFlag", "0"); Replaceall(tm, "$arg", Getattr(p, "emit:input")); Replaceall(tm, "$input", Getattr(p, "emit:input")); Printv(outarg, tm, "\n", NIL); @@ -1602,10 +1624,12 @@ public: String *retType_class = NULL; bool retType_valid = is_class(d); + bool valid_wrapped_class = false; if (retType_valid) { retType_class = get_class_name(d); Chop(retType_class); + valid_wrapped_class = is_class_wrapped(retType_class); } /* emit function call */ @@ -1621,11 +1645,11 @@ public: if (retType_class) { String *retZend_obj = NewStringEmpty(); Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class); - Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : retZend_obj) : "NULL"); + Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (valid_wrapped_class ? retZend_obj : "NULL")) : "NULL"); } Replaceall(tm, "$zend_obj", "NULL"); - Replaceall(tm, "$newobj", retType_valid ? "1" : "2"); - Replaceall(tm, "$c_obj", constructor? "1" : "0"); + 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); @@ -1681,7 +1705,7 @@ public: wname = NULL; if (overloaded && !Getattr(n, "sym:nextSibling")) { - dispatchFunction(n); + dispatchFunction(n, constructor); } // Handle getters and setters. @@ -2677,23 +2701,9 @@ done: virtual int classDeclaration(Node *n) { if (!Getattr(n, "feature:onlychildren")) { - String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); Setattr(n, "php:proxy", symname); - - if (className != symname) - class_name = symname; - else - class_name = className; - - if (Len(classes) != 0) - Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); - - Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name); - - Append(classes,class_name); } - return Language::classDeclaration(n); } @@ -2706,6 +2716,15 @@ done: return present_name; } + /* Helper method to get names without namespace + */ + String *getNameWithoutNamespace(char *name) { + char *returnName = Char(strrchr(name, ':')); + if (!returnName) + return NULL; + return NewString(returnName + 1); + } + /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ @@ -2715,15 +2734,26 @@ done: current_class = n; String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); - String *nameSpace = NULL; + //String *nameSpace = NULL; String *baseClassExtend = NULL; + bool exceptionClassFlag = false; //check for namespaces - if (Strstr(className, ":")) - nameSpace = getNameSpace(GetChar(n, "name")); + //if (Strstr(className, ":")) + //nameSpace = getNameSpace(GetChar(n, "name")); + if (className != symname) + class_name = symname; + else + class_name = className; + + if (Len(classes) != 0) + Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); + + Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name); class_type = Getattr(n, "classtype"); + Append(classes,class_name); Append(class_types, class_type); Append(class_need_free, "0"); @@ -2752,7 +2782,8 @@ done: while (base.item && GetFlag(base.item, "feature:ignore")) { base = Next(base); } - baseClassExtend = Getattr(base.item, "sym:name"); + if (base.item) + baseClassExtend = Getattr(base.item, "sym:name"); base = Next(base); if (base.item) { /* Warn about multiple inheritance for additional base class(es) */ @@ -2780,9 +2811,10 @@ done: Append(baseClassExtend, "_Exception"); Printf(s_oinit, "zend_class_entry *%s_ce = zend_lookup_class(zend_string_init(\"Exception\", sizeof(\"Exception\") - 1, 0));\n", baseClassExtend); + exceptionClassFlag = true; } - if (baseClassExtend) { + if (baseClassExtend && (exceptionClassFlag || is_class_wrapped(baseClassExtend))) { Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, baseClassExtend); } else { From 9fea6fc5ac81882221b019c47383b478145675a2 Mon Sep 17 00:00:00 2001 From: Nihal Date: Fri, 18 Aug 2017 08:41:14 +0530 Subject: [PATCH 5/6] Refactor code and solve few test cases. - Change the need of runtime check on old or new flow at wrapper generation time. - Change the check on add ZEND_ACC_ABSTRACT to GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n)) - workaround to solve abstract testcases at the moment. - Remove redundant code in class handler for getting namespaces (Not the correct approact) and use of zend_register_class_alias_ex. - Refactor choosing of class name to use sym:name by default. --- Lib/php/php.swg | 12 ++++++------ Source/Modules/php.cxx | 20 ++++---------------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/Lib/php/php.swg b/Lib/php/php.swg index ebd58fe13..5b20d9a6c 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -85,7 +85,7 @@ /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype tmp) %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { $1 = *(($1_ltype *)$obj_value); } else { @@ -108,7 +108,7 @@ %typemap(in) SWIGTYPE *, SWIGTYPE [] %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { $1 = ($1_ltype) $obj_value; } else { @@ -119,7 +119,7 @@ %typemap(in) SWIGTYPE & %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { $1 = ($1_ltype) $obj_value; } else { @@ -130,7 +130,7 @@ %typemap(in) SWIGTYPE && %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { $1 = ($1_ltype) $obj_value; } else { @@ -142,7 +142,7 @@ %typemap(in) SWIGTYPE *const& ($*ltype temp) %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { $1 = ($1_ltype) $obj_value; } else { @@ -155,7 +155,7 @@ %typemap(in) SWIGTYPE *DISOWN %{ - if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { + if ($needNewFlow) { SWIG_Z_FETCH_OBJ_P(&$input)->newobject = 0; $1 = ($lower_param *)SWIG_Z_FETCH_OBJ_P(&$input)->ptr; } diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 3b3d514a6..4c0062b3e 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1297,7 +1297,7 @@ public: else if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"),"static") == 0) Append(modes, " | ZEND_ACC_STATIC"); - if (Cmp(Getattr(n, "abstract"), "1") == 0) + if (GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n))) Append(modes, " | ZEND_ACC_ABSTRACT"); if (Getattr(n, "sym:overloaded")) { @@ -1537,7 +1537,7 @@ public: Printf(param_value, "%sSWIG_Z_FETCH_OBJ_P(%s)->ptr", SwigType_isreference(pt) ? "&" : "", param_zval); Replaceall(tm, "$obj_value", param_value); } - Replaceall(tm, "$classFlag", "0"); + Replaceall(tm, "$needNewFlow", paramType_valid ? (is_class_wrapped(paramType_class) ? "1" : "0") : "0"); String *temp_obj = NewStringEmpty(); Printf(temp_obj, "&%s", ln); Replaceall(tm, "$obj_value", is_param_type_pointer(resolved ? resolved : pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. @@ -1641,6 +1641,7 @@ public: Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$result", "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"); if (retType_class) { String *retZend_obj = NewStringEmpty(); @@ -2732,20 +2733,11 @@ done: virtual int classHandler(Node *n) { constructors = 0; current_class = n; - String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); - //String *nameSpace = NULL; String *baseClassExtend = NULL; bool exceptionClassFlag = false; - //check for namespaces - //if (Strstr(className, ":")) - //nameSpace = getNameSpace(GetChar(n, "name")); - - if (className != symname) - class_name = symname; - else - class_name = className; + class_name = symname; if (Len(classes) != 0) Printf(all_cs_entry, " ZEND_FE_END\n};\n\n"); @@ -2821,10 +2813,6 @@ done: Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", class_name , class_name); } - if (Cmp(symname,className) != 0) { - 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")); From 4252b31f8fcac46e53e0fd3ded67992e214965b2 Mon Sep 17 00:00:00 2001 From: Nihal Date: Sun, 20 Aug 2017 01:54:07 +0530 Subject: [PATCH 6/6] Refactor code to rename class entry variables and ConvertPtr to work with wrapped objects. - Rename class entry variables to SWIGTYPE_class_ce - Refactor factory code to use SWIGTYPE_class_ce to create objects - Refactor ConvertPtr to work of wrapped class objects. --- Lib/php/const.i | 8 ++++---- Lib/php/factory.i | 9 +-------- Lib/php/phprun.swg | 26 ++++++++++++-------------- Source/Modules/php.cxx | 20 ++++++++++---------- 4 files changed, 27 insertions(+), 36 deletions(-) diff --git a/Lib/php/const.i b/Lib/php/const.i index c6cad6a3f..666e86eee 100644 --- a/Lib/php/const.i +++ b/Lib/php/const.i @@ -12,18 +12,18 @@ unsigned char, signed char, enum SWIGTYPE - "zend_declare_class_constant_long($class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; + "zend_declare_class_constant_long(SWIGTYPE_$class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; %typemap(classconsttab) bool - "zend_declare_class_constant_bool($class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; + "zend_declare_class_constant_bool(SWIGTYPE_$class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; %typemap(classconsttab) float, double - "zend_declare_class_constant_double($class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; + "zend_declare_class_constant_double(SWIGTYPE_$class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, $value);"; %typemap(classconsttab) char, string - "zend_declare_class_constant_string($class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, \"$value\");"; + "zend_declare_class_constant_string(SWIGTYPE_$class_ce, \"$const_name\", sizeof(\"$const_name\") - 1, \"$value\");"; %typemap(consttab) int, unsigned int, diff --git a/Lib/php/factory.i b/Lib/php/factory.i index 565383c40..7dcd517ec 100644 --- a/Lib/php/factory.i +++ b/Lib/php/factory.i @@ -95,14 +95,7 @@ if (!dcast) { Type *dobj = dynamic_cast($1); if (dobj) { dcast = 1; - 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; - } + 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); } }%enddef diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index 8edfa119e..acb856958 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -196,6 +196,13 @@ SWIG_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags) { return SWIG_ConvertResourceData(p, type_name, ty); } +#define SWIG_Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv)) + +static inline +swig_object_wrapper * php_fetch_object(zend_object *obj) { + return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std)); +} + /* We allow passing of a RESOURCE pointing to the object or an OBJECT whose _cPtr is a resource pointing to the object */ static int @@ -211,17 +218,15 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { if (ht) { zval * _cPtr = zend_hash_str_find(ht, "_cPtr", sizeof("_cPtr") - 1); if (_cPtr) { + if (zend_hash_str_exists(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1)) { + *ptr = SWIG_Z_FETCH_OBJ_P(z)->ptr; + return (*ptr == NULL ? -1 : 0); + } if (Z_TYPE_P(_cPtr) == IS_INDIRECT) { _cPtr = Z_INDIRECT_P(_cPtr); } if (Z_TYPE_P(_cPtr) == IS_RESOURCE) { - zval *zv; - if (!zend_hash_str_exists(ht, "SWIG_classWrapper", sizeof("SWIG_classWrapper") - 1)) - zv = _cPtr; - else - zv = z; - - *ptr = SWIG_ConvertResourcePtr(zv, ty, flags); + *ptr = SWIG_ConvertResourcePtr(_cPtr, ty, flags); return (*ptr == NULL ? -1 : 0); } } @@ -239,13 +244,6 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) { return -1; } -#define SWIG_Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv)) - -static inline -swig_object_wrapper * php_fetch_object(zend_object *obj) { - return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std)); -} - static void SWIG_generalize_object(zval *zval_obj, void *ptr, int class_obj, int userNewObj ,swig_type_info *type) { swig_object_wrapper *obj = NULL; diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 4c0062b3e..6baac33f2 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -152,7 +152,7 @@ static void print_creation_free_wrapper(int item_index) { need_free = true; Printf(s_header, "/* class entry for %s */\n",class_name); - Printf(s_header, "zend_class_entry *%s_ce;\n\n",class_name); + Printf(s_header, "zend_class_entry *SWIGTYPE_%s_ce;\n\n",class_name); Printf(s_header, "/* class object handlers for %s */\n",class_name); Printf(s_header, "zend_object_handlers %s_object_handlers;\n\n",class_name); @@ -1213,7 +1213,7 @@ public: Printf(f->code, " newSize += arg2->len + strlen(\"_get\");\nmethod_name = (char *)malloc(newSize);\n"); Printf(f->code, " strcpy(method_name,arg2->val);\nstrcat(method_name,\"_get\");\n\n"); - Printf(magic_isset, "\nelse if (zend_hash_exists(&%s_ce->function_table, zend_string_init(method_name, newSize-1, 0))) {\n",class_name); + Printf(magic_isset, "\nelse if (zend_hash_exists(&SWIGTYPE_%s_ce->function_table, zend_string_init(method_name, newSize-1, 0))) {\n",class_name); Printf(magic_isset, "RETVAL_TRUE;\n}\n"); Printf(f->code, "if (!arg2) {\n RETVAL_FALSE;\n}\n",magic_set); @@ -1645,7 +1645,7 @@ public: Replaceall(tm, "$classZv", constructor ? "getThis()" : "NULL"); if (retType_class) { String *retZend_obj = NewStringEmpty(); - Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class); + 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", "NULL"); @@ -2749,13 +2749,13 @@ done: Append(class_types, class_type); Append(class_need_free, "0"); - Printf(s_oinit, "\nzend_class_entry %s_internal_ce;\n", class_name); + Printf(s_oinit, "\nzend_class_entry SWIGTYPE_%s_internal_ce;\n", class_name); // namespace code to introduce namespaces into wrapper classes. //if (nameSpace != NULL) //Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\\\\%s\", class_%s_functions);\n", class_name, nameSpace ,class_name, class_name); //else - Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\", class_%s_functions);\n", class_name, class_name, class_name); + Printf(s_oinit, "INIT_CLASS_ENTRY(SWIGTYPE_%s_internal_ce, \"%s\", class_%s_functions);\n", class_name, class_name, class_name); if (shadow) { char *rename = GetChar(n, "sym:name"); @@ -2802,15 +2802,15 @@ done: baseClassExtend = NewString(class_name); Append(baseClassExtend, "_Exception"); - Printf(s_oinit, "zend_class_entry *%s_ce = zend_lookup_class(zend_string_init(\"Exception\", sizeof(\"Exception\") - 1, 0));\n", baseClassExtend); + Printf(s_oinit, "zend_class_entry *SWIGTYPE_%s_ce = zend_lookup_class(zend_string_init(\"Exception\", sizeof(\"Exception\") - 1, 0));\n", baseClassExtend); exceptionClassFlag = true; } if (baseClassExtend && (exceptionClassFlag || is_class_wrapped(baseClassExtend))) { - Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", class_name , class_name, baseClassExtend); + Printf(s_oinit, "SWIGTYPE_%s_ce = zend_register_internal_class_ex(&SWIGTYPE_%s_internal_ce, SWIGTYPE_%s_ce);\n", class_name , class_name, baseClassExtend); } else { - Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", class_name , class_name); + Printf(s_oinit, "SWIGTYPE_%s_ce = zend_register_internal_class(&SWIGTYPE_%s_internal_ce);\n", class_name , class_name); } { @@ -2834,11 +2834,11 @@ done: } 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, "zend_class_implements(SWIGTYPE_%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); + Printf(s_oinit, "SWIGTYPE_%s_ce->create_object = %s_object_new;\n", class_name, class_name); Printf(s_oinit, "memcpy(&%s_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n", class_name); Printf(s_oinit, "%s_object_handlers.clone_obj = NULL;\n\n", class_name);