From 4c55919975f03a7af8679aa60c7a358ec2f38ed0 Mon Sep 17 00:00:00 2001 From: Nihal Date: Tue, 18 Jul 2017 23:30:07 +0530 Subject: [PATCH 1/4] Refactor Code to use swig_object_wrapper for wrapping classes. And use void * to store class pointers. --- Lib/php/php.swg | 35 +++----- Lib/php/phprun.swg | 49 ++--------- Source/Modules/php.cxx | 185 +++++++++++++++++++++-------------------- 3 files changed, 113 insertions(+), 156 deletions(-) diff --git a/Lib/php/php.swg b/Lib/php/php.swg index 1a8329609..4d9812045 100644 --- a/Lib/php/php.swg +++ b/Lib/php/php.swg @@ -119,9 +119,8 @@ %typemap(in) SWIGTYPE & %{ - /*if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) + 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 && @@ -142,8 +141,8 @@ %typemap(in) SWIGTYPE *DISOWN %{ if (zend_lookup_class(zend_string_init("$lower_param",sizeof("$lower_param")-1,0))) { - Z_$upper_param_OBJ_P(&$input)->newobject = 0; - $1 = Z_$upper_param_OBJ_P(&$input)->$lower_param_obj; + Z_FETCH_OBJ_P(&$input)->newobject = 0; + $1 = ($lower_param *)Z_FETCH_OBJ_P(&$input)->ptr; } else { if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) @@ -482,11 +481,8 @@ %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { - if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) - _v = 1; - else - _v = 0; - //_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0); + void *tmp; + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); } %typecheck(SWIG_TYPECHECK_POINTER) @@ -496,29 +492,20 @@ SWIGTYPE &&, SWIGTYPE *const& { - if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) - _v = 1; - else - _v = 0; - //_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0); + void *tmp; + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *const& { - if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) - _v = 1; - else - _v = 0; - //_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0); + void *tmp; + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { - if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) - _v = 1; - else - _v = 0; - //_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0); + void *tmp; + _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0); } /* Exception handling */ diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg index bcc8c482f..0c867754c 100644 --- a/Lib/php/phprun.swg +++ b/Lib/php/phprun.swg @@ -56,6 +56,8 @@ static int default_error_code = E_ERROR; and need freeing, or not */ typedef struct { void * ptr; + zend_object std; + HashTable *extras; int newobject; } swig_object_wrapper; @@ -258,46 +260,9 @@ SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *ty } } -static int -is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */ -{ - child_class = child_class->parent; - while (child_class) { - if (child_class == parent_class) { - return 1; - } - child_class = child_class->parent; - } - return 0; -} - -static int -SWIG_is_correct_object (zval *zv, swig_type_info *ty) { - - int return_value = 0; - - int excess = strlen(strchr(SWIG_TypePrettyName(ty),' ')); - if (excess == 0) - excess = strlen(strchr(SWIG_TypePrettyName(ty),'*')); - - int needed_length = strlen(SWIG_TypePrettyName(ty))-excess; - - char *ty_name = (char *)malloc(needed_length); - memcpy(ty_name,SWIG_TypePrettyName(ty),needed_length); - - zend_class_entry *lookup_ce = zend_lookup_class(zend_string_init(ty_name, needed_length , 0)); - zend_string *zend_class_name = zend_string_copy(Z_OBJ_P(zv)->ce->name); - zend_class_entry *zval_ce = zend_lookup_class(zend_class_name); - - if (!zval_ce || !lookup_ce) - return 0; - - if (strcmp(zend_class_name->val,ty_name)) { - if (is_derived_class(zval_ce,lookup_ce)) - return_value = 1; - } - else - return_value = 1; - - return return_value; +#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)); } diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 63f68b466..d337ef875 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -974,6 +974,29 @@ public: return false; } + /* Helper method for PHP::functionWrapper to get class name for parameter*/ + String *get_class_name(SwigType *t) { + Node *n = classLookup(t); + String *r = NULL; + if (n) { + r = Getattr(n, "php:proxy"); // Set by classDeclaration() + if (!r) + r = Getattr(n, "sym:name"); // Not seen by classDeclaration yet, but this is the name + } + return r; + } + + /* Is special return type */ + bool is_return(SwigType *t) { + + if (SwigType_ispointer(t) || + SwigType_ismemberpointer(t) || + SwigType_isarray(t)) + return true; + + return false; + } + /* Magic methods __set, __get, __isset is declared here in the extension. The flag variable is used to decide whether all variables are read or not. */ @@ -1019,8 +1042,8 @@ 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, " struct %s_object *arg = (struct %s_object *)Z_%(upper)s_OBJ_P(getThis());\n", class_name, class_name, class_name); - Printf(f->code, " %s *arg1 = (%s *)(arg->%s_obj);\n", class_name, class_name, 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, " 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"); @@ -1051,8 +1074,9 @@ 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, " struct %s_object *arg = (struct %s_object *)Z_%(upper)s_OBJ_P(getThis());\n", class_name, class_name, class_name); - Printf(f->code, " %s *arg1 = (%s *)(arg->%s_obj);\n", class_name, class_name, class_name); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); + 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, " 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"); Printf(f->code, " if(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n\n"); @@ -1081,8 +1105,9 @@ 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, " struct %s_object *arg = (struct %s_object *)Z_%(upper)s_OBJ_P(getThis());\n", class_name, class_name, class_name); - Printf(f->code, " %s *arg1 = (%s *)(arg->%s_obj);\n", class_name, class_name, class_name); Printf(f->code, " zval args[1];\n zend_string *arg2 = 0;\n\n"); + 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, " 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"); Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); @@ -1264,7 +1289,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_%(upper)s_OBJ_P(getThis()))->%s_obj);\n", class_name, class_name, class_name); + Printf(args, "arg1 = (%s *)((Z_FETCH_OBJ_P(getThis()))->ptr);\n", class_name, class_name); } Printf(args, "zval args[%d]", num_arguments); Wrapper_add_local(f, "args", args); @@ -1305,6 +1330,16 @@ public: if (wrapperType == directorconstructor) Printf(f->code, "arg0 = &args[0];\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. @@ -1346,24 +1381,12 @@ public: Printf(f->code, "\tif(arg_count > %d) {\n", i); } - String *paramType = SwigType_str(pt, 0); String *paramType_class = NULL; - String *paramType_class_upper = NULL; bool paramType_valid = is_class(pt); - if (Strchr(paramType,'*') || Strchr(paramType,'&')) { - paramType_class = NewString(paramType); - Replace(paramType_class,"*","",DOH_REPLACE_FIRST); - Replace(paramType_class,Strchr(paramType,' '),"",DOH_REPLACE_FIRST); + if (paramType_valid) { + paramType_class = get_class_name(pt); Chop(paramType_class); - paramType_class_upper = NewStringEmpty(); - Printf(paramType_class_upper, "%(upper)s", paramType_class); - } - else if (paramType_valid) { - paramType_class = NewString(paramType); - Chop(paramType_class); - paramType_class_upper = NewStringEmpty(); - Printf(paramType_class_upper, "%(upper)s", paramType_class); } if ((tm = Getattr(p, "tmap:in"))) { @@ -1385,13 +1408,12 @@ public: Printf(param_zval, "getThis()"); else Printf(param_zval, "&%s", source); - Printf(param_value, "Z_%(upper)s_OBJ_P(%s)->%s_obj", paramType_class_upper, param_zval , paramType_class); + Printf(param_value, "(%s *) Z_FETCH_OBJ_P(%s)->ptr", paramType_class , param_zval); Replaceall(tm, "$obj_value", param_value); } String *temp_obj = NewStringEmpty(); Printf(temp_obj, "&%s", ln); - Replaceall(tm, "$obj_value", SwigType_ispointer(pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. - Replaceall(tm, "$upper_param", paramType_class_upper); + Replaceall(tm, "$obj_value", is_return(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); @@ -1472,33 +1494,6 @@ public: Setattr(n, "wrap:name", wname); } - String *retType = SwigType_str(d, 0); - String *retType_class = NULL; - String *retType_class_upper = NULL; - bool retType_valid = is_class(d); - - if (Strchr(retType,'*')) { - retType_class = NewString(retType); - retType_class_upper = NewStringEmpty(); - Replace(retType_class,"*","",DOH_REPLACE_FIRST); - Chop(retType_class); - Printf(retType_class_upper, "%(upper)s",retType_class); - - if (retType_valid) - Printf(f->code, "\nstruct %s_object *obj = NULL;\n",retType_class); - } - else if (retType_valid) { - retType_class = NewString(retType); - Chop(retType_class); - Printf(f->code, "\nstruct %s_object *obj = NULL;\n",retType_class); - } - else if (is_class(d)) { - retType_class = NewString(retType); - Chop(retType_class); - Printf(f->code, "\nstruct %s_object *obj;\n",retType_class); - retType_valid = true; - } - /* emit function call */ String *actioncode = emit_action(n); @@ -1508,7 +1503,7 @@ public: Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$result", "return_value"); Replaceall(tm, "$owner", newobject ? "1" : "0"); - Replaceall(tm, "$swig_type", SwigType_manglestr(Getattr(n, "type"))); + Replaceall(tm, "$swig_type", SwigType_manglestr(d)); if (retType_class) { String *retZend_obj = NewStringEmpty(); Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class); @@ -1516,6 +1511,7 @@ public: 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", "NULL"); Replaceall(tm, "$newobj", retType_valid ? "1" : "2"); Replaceall(tm, "$c_obj", constructor? "1" : "0"); Printf(f->code, "%s\n", tm); @@ -1532,10 +1528,20 @@ public: Printv(f->code, cleanup, NIL); } - if (constructor) - Printf(f->code,"obj = Z_%(upper)s_OBJ_P(getThis());\nobj->%s_obj = result;\n\n", class_name, class_name); - else if (retType_valid) - Printf(f->code,"obj = Z_%(upper)s_OBJ_P(return_value);\nobj->%s_obj = result;\n\n", retType_class, retType_class); + if (constructor) { + Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(getThis());\nobj->ptr = result;\n\n", class_name); + 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,"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"); + } if (retType_valid) Printf(f->code, "if (obj)\nobj->newobject = %d;\n", newobject ? 1 : 0); @@ -2576,12 +2582,10 @@ done: String *symname = Getattr(n, "sym:name"); Setattr(n, "php:proxy", symname); + Printf(s_header, "/* class entry for %s */\n",symname); Printf(s_header, "zend_class_entry *%s_ce;\n\n",symname); - Printf(s_header, "#define Z_%(upper)s_OBJ_P(zv) php_%s_object_fetch_object(Z_OBJ_P(zv))\n\n",symname,symname); - Printf(s_header, "zend_object_handlers %s_object_handlers;\n",symname); - Printf(s_header, "struct %s_object {\n %s *%s_obj;\n zend_object std;\n HashTable *extras;\n int newobject;\n};\n\n",symname,symname,symname); - Printf(s_header, "static inline struct %s_object * php_%s_object_fetch_object(zend_object *obj) {\n",symname,symname); - Printf(s_header, " return (struct %s_object *)((char *)obj - XtOffsetOf(struct %s_object, std));\n}\n\n",symname,symname); + Printf(s_header, "/* class object handlers for %s */\n",symname); + Printf(s_header, "zend_object_handlers %s_object_handlers;\n\n",symname); Printf(s_header, "/* dtor Method for class %s */\n",symname); Printf(s_header, "void %s_destroy_object(zend_object *object) {\n",symname); @@ -2591,10 +2595,10 @@ done: Printf(s_header, "/* Garbage Collection Method for class %s */\n",symname); Printf(s_header, "void %s_free_storage(zend_object *object) {\n",symname); Printf(s_header, " if(!object)\n\t return;\n"); - Printf(s_header, " struct %s_object *obj = (struct %s_object *)php_%s_object_fetch_object(object);\n",symname,symname,symname); + 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->%s_obj)\n",symname); - Printf(s_header, " SWIG_remove(obj->%s_obj);\n",symname); + Printf(s_header, " if(obj->ptr)\n"); + Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",symname); 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"); @@ -2603,10 +2607,9 @@ done: Printf(s_header, "/* Object Creation Method for class %s */\n",symname); Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",symname); - Printf(s_header, " struct %s_object *obj = (struct %s_object*)ecalloc(1,sizeof(struct %s_object) + zend_object_properties_size(ce));\n",symname,symname,symname); + 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(struct %s_object, std);\n",symname,symname); + Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n",symname); Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",symname,symname); Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",symname,symname); Printf(s_header, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",symname); @@ -2983,32 +2986,34 @@ done: 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); - 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); - Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL); + if (!class_name) { + 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); + Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL); - emit_parameter_variables(l, f); - emit_attach_parmmaps(l, f); + emit_parameter_variables(l, f); + emit_attach_parmmaps(l, f); - // Get type of first arg, thing to be destructed - // Skip ignored arguments - Parm *p = l; - //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); + // Get type of first arg, thing to be destructed + // Skip ignored arguments + Parm *p = l; + //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + SwigType *pt = Getattr(p, "type"); + + Printf(f->code, " efree(value);\n"); + Printf(f->code, " if (! newobject) return; /* can't delete it! */\n"); + Printf(f->code, " arg1 = (%s)SWIG_ConvertResourceData(ptr, type_name, SWIGTYPE%s);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt)); + Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name)); + + Setattr(n, "wrap:name", destructorname); + + String *actioncode = emit_action(n); + Append(f->code, actioncode); + Delete(actioncode); } - SwigType *pt = Getattr(p, "type"); - - Printf(f->code, " efree(value);\n"); - Printf(f->code, " if (! newobject) return; /* can't delete it! */\n"); - Printf(f->code, " arg1 = (%s)SWIG_ConvertResourceData(ptr, type_name, SWIGTYPE%s);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt)); - Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name)); - - Setattr(n, "wrap:name", destructorname); - - String *actioncode = emit_action(n); - Append(f->code, actioncode); - Delete(actioncode); Printf(f->code, "thrown:\n"); Append(f->code, "return;\n"); From 6b8aae188f84b5b388bbfb98c801e8941937c840 Mon Sep 17 00:00:00 2001 From: Nihal Date: Sun, 23 Jul 2017 09:54:23 +0530 Subject: [PATCH 2/4] Refactor Code. - Support different return types of pointers. - Fixup - Support the rename functionality in class names. - Redirect the resource destructor to the class desctructor if its a class resource - Object pointers. --- Source/Modules/php.cxx | 110 ++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 51 deletions(-) diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index d337ef875..c73ff6044 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -1383,6 +1383,7 @@ public: String *paramType_class = NULL; bool paramType_valid = is_class(pt); + SwigType *resolved = SwigType_typedef_resolve_all(pt); if (paramType_valid) { paramType_class = get_class_name(pt); @@ -1413,7 +1414,7 @@ public: } String *temp_obj = NewStringEmpty(); Printf(temp_obj, "&%s", ln); - Replaceall(tm, "$obj_value", is_return(pt) ? "NULL" : temp_obj); // Adding this to compile. It won't reach this if $obj_val is required. + 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, "$lower_param", paramType_class); Setattr(p, "emit:input", source); Printf(f->code, "%s\n", tm); @@ -2579,48 +2580,49 @@ 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); - Printf(s_header, "/* class entry for %s */\n",symname); - Printf(s_header, "zend_class_entry *%s_ce;\n\n",symname); - Printf(s_header, "/* class object handlers for %s */\n",symname); - Printf(s_header, "zend_object_handlers %s_object_handlers;\n\n",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",symname); - Printf(s_header, "void %s_destroy_object(zend_object *object) {\n",symname); + 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",symname); - Printf(s_header, "void %s_free_storage(zend_object *object) {\n",symname); + 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",symname); + 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",symname); - Printf(s_header, "zend_object * %s_object_new(zend_class_entry *ce) {\n",symname); + 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",symname); - Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",symname,symname); - Printf(s_header, " %s_object_handlers.dtor_obj = %s_destroy_object;\n",symname,symname); - Printf(s_header, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",symname); + 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 (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", symname); + Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", className); - class_name = symname; - Append(classes,symname); + class_name = className; + Append(classes,className); } return Language::classDeclaration(n); @@ -2633,10 +2635,11 @@ done: virtual int classHandler(Node *n) { constructors = 0; current_class = n; + String *className = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); - Printf(s_oinit, "\nzend_class_entry %s_internal_ce;\n", symname); - Printf(s_oinit, "INIT_CLASS_ENTRY(%s_internal_ce, \"%s\", class_%s_functions);\n", symname, symname, symname); + 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); if (shadow) { char *rename = GetChar(n, "sym:name"); @@ -2655,7 +2658,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", symname , symname, Getattr(base.item, "name")); + Printf(s_oinit, "%s_ce = zend_register_internal_class_ex(&%s_internal_ce, %s_ce);\n", className , className, Getattr(base.item, "name")); base = Next(base); if (base.item) { @@ -2674,18 +2677,22 @@ done: } } else - Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", symname , symname); + Printf(s_oinit, "%s_ce = zend_register_internal_class(&%s_internal_ce);\n", className , className); } - Printf(s_oinit, "%s_ce->create_object = %s_object_new;\n", symname, symname); - Printf(s_oinit, "memcpy(&%s_object_handlers,zend_get_std_object_handlers(), sizeof(zend_object_handlers));\n", symname); - Printf(s_oinit, "%s_object_handlers.clone_obj = NULL;\n\n", symname); + 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, "%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); classnode = n; Language::classHandler(n); classnode = 0; - if (shadow) { + if (shadow && !class_name) { List *baselist = Getattr(n, "bases"); Iterator ki, base; @@ -2986,34 +2993,35 @@ done: 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); - if (!class_name) { - 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); - Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL); + 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"); - emit_parameter_variables(l, f); - emit_attach_parmmaps(l, f); + 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); + Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL); - // Get type of first arg, thing to be destructed - // Skip ignored arguments - Parm *p = l; - //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - SwigType *pt = Getattr(p, "type"); + emit_parameter_variables(l, f); + emit_attach_parmmaps(l, f); - Printf(f->code, " efree(value);\n"); - Printf(f->code, " if (! newobject) return; /* can't delete it! */\n"); - Printf(f->code, " arg1 = (%s)SWIG_ConvertResourceData(ptr, type_name, SWIGTYPE%s);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt)); - Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name)); - - Setattr(n, "wrap:name", destructorname); - - String *actioncode = emit_action(n); - Append(f->code, actioncode); - Delete(actioncode); + // Get type of first arg, thing to be destructed + // Skip ignored arguments + Parm *p = l; + //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); } + SwigType *pt = Getattr(p, "type"); + + Printf(f->code, " efree(value);\n"); + Printf(f->code, " if (! newobject) return; /* can't delete it! */\n"); + Printf(f->code, " arg1 = (%s)SWIG_ConvertResourceData(ptr, type_name, SWIGTYPE%s);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt)); + Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name)); + + Setattr(n, "wrap:name", destructorname); + + String *actioncode = emit_action(n); + Append(f->code, actioncode); + Delete(actioncode); Printf(f->code, "thrown:\n"); Append(f->code, "return;\n"); From 2e5f0fac5249c3fd32583c063b20ee898e81c45c Mon Sep 17 00:00:00 2001 From: Nihal Date: Sun, 23 Jul 2017 12:09:01 +0530 Subject: [PATCH 3/4] Add class method check in Test Cases. Currently they check flat functions at check::functions() --- Examples/php/run.sh | 26 + Examples/test-suite/php/add_link_runme.php | 4 +- .../test-suite/php/arrays_global_runme.php | 5 +- .../php/arrays_global_twodim_runme.php | 5 +- .../test-suite/php/arrays_scope_runme.php | 4 +- Examples/test-suite/php/casts_runme.php | 5 +- .../test-suite/php/class_ignore_runme.php | 7 +- Examples/test-suite/php/cpp_basic_runme.php | 9 +- Examples/test-suite/php/tests.php | 1 + log_handling.php | 43 ++ test1.log~ | 513 ++++++++++++++++++ 11 files changed, 610 insertions(+), 12 deletions(-) create mode 100644 Examples/php/run.sh create mode 100644 log_handling.php create mode 100644 test1.log~ diff --git a/Examples/php/run.sh b/Examples/php/run.sh new file mode 100644 index 000000000..2b72af10b --- /dev/null +++ b/Examples/php/run.sh @@ -0,0 +1,26 @@ +cd class +make +cd ../constants +make +cd ../disown +make +cd ../overloading +make +cd ../pragmas +make +cd ../variables +make +cd ../cpointer +make +cd ../enum +make +cd ../funcptr +make +cd ../pointer +make +cd ../proxy +make +cd ../simple +make +cd ../value +make diff --git a/Examples/test-suite/php/add_link_runme.php b/Examples/test-suite/php/add_link_runme.php index 7523bd604..1b687ca5a 100644 --- a/Examples/test-suite/php/add_link_runme.php +++ b/Examples/test-suite/php/add_link_runme.php @@ -3,10 +3,8 @@ require "tests.php"; require "add_link.php"; -// No new functions, except the flat functions -check::functions(array(new_foo,foo_blah)); - check::classes(array(Foo)); +check::classmethods(Foo,array(__construct,__set,__isset,__get,blah)); $foo=new foo(); check::is_a($foo,foo); diff --git a/Examples/test-suite/php/arrays_global_runme.php b/Examples/test-suite/php/arrays_global_runme.php index 7f1091532..1764bcfb7 100644 --- a/Examples/test-suite/php/arrays_global_runme.php +++ b/Examples/test-suite/php/arrays_global_runme.php @@ -3,8 +3,11 @@ require "tests.php"; require "arrays_global.php"; -check::functions(array(test_a,test_b,new_simplestruct,new_material)); +check::functions(array(test_a,test_b)); check::classes(array(arrays_global,SimpleStruct,Material)); +check::classmethods(SimpleStruct,array(__construct,__set,__isset,__get,double_field_set,double_field_get)); +check::classmethods(Material,array(__construct,__set,__isset,__get)); + // The size of array_c is 2, but the last byte is \0, so we can only store a // single byte string in it. check::set(array_c,"Z"); diff --git a/Examples/test-suite/php/arrays_global_twodim_runme.php b/Examples/test-suite/php/arrays_global_twodim_runme.php index d97cd9ca7..4d77f0414 100644 --- a/Examples/test-suite/php/arrays_global_twodim_runme.php +++ b/Examples/test-suite/php/arrays_global_twodim_runme.php @@ -3,8 +3,11 @@ require "tests.php"; require "arrays_global_twodim.php"; -check::functions(array(fn_taking_arrays,get_2d_array,new_simplestruct,new_material)); +check::functions(array(fn_taking_arrays,get_2d_array)); check::classes(array(arrays_global_twodim,SimpleStruct,Material)); +check::classmethods(SimpleStruct,array(__construct,__set,__isset,__get,double_field_set,double_field_get)); +check::classmethods(Material,array(__construct,__set,__isset,__get)); + $a1=array(10,11,12,13); $a2=array(14,15,16,17); $a=array($a1,$a2); diff --git a/Examples/test-suite/php/arrays_scope_runme.php b/Examples/test-suite/php/arrays_scope_runme.php index 668142471..68cea196b 100644 --- a/Examples/test-suite/php/arrays_scope_runme.php +++ b/Examples/test-suite/php/arrays_scope_runme.php @@ -3,10 +3,10 @@ require "tests.php"; require "arrays_scope.php"; -// New functions -check::functions(array(new_bar,bar_blah)); // New classes check::classes(array(arrays_scope,Bar)); +// New functions +check::classmethods(Bar,array(__construct,__set,__isset,__get,blah)); $bar=new bar(); diff --git a/Examples/test-suite/php/casts_runme.php b/Examples/test-suite/php/casts_runme.php index 10522dca4..b7c183ac1 100644 --- a/Examples/test-suite/php/casts_runme.php +++ b/Examples/test-suite/php/casts_runme.php @@ -3,10 +3,11 @@ require "tests.php"; require "casts.php"; -// No new functions -check::functions(array(new_a,a_hello,new_b)); // No new classes check::classes(array(A,B)); +// New functions +check::classmethods(A,array(__construct,__set,__isset,__get,hello)); +check::classmethods(B,array(__construct,__set,__isset,__get,hello)); // now new vars check::globals(array()); diff --git a/Examples/test-suite/php/class_ignore_runme.php b/Examples/test-suite/php/class_ignore_runme.php index d5ce36217..a0ed27c5a 100644 --- a/Examples/test-suite/php/class_ignore_runme.php +++ b/Examples/test-suite/php/class_ignore_runme.php @@ -3,8 +3,13 @@ require "tests.php"; require "class_ignore.php"; -check::functions(array(do_blah,new_bar,bar_blah,new_boo,boo_away,new_far,new_hoo)); +check::functions(array(do_blah)); check::classes(array(class_ignore,Bar,Boo,Far,Hoo)); +// New functions +check::classmethods(Bar,array(__construct,__set,__isset,__get,blah)); +check::classmethods(Boo,array(__construct,__set,__isset,__get,away)); +check::classmethods(Far,array(__construct,__set,__isset,__get)); +check::classmethods(Hoo,array(__construct,__set,__isset,__get)); // No new vars check::globals(array()); diff --git a/Examples/test-suite/php/cpp_basic_runme.php b/Examples/test-suite/php/cpp_basic_runme.php index c8b00b9d7..3a8a30352 100644 --- a/Examples/test-suite/php/cpp_basic_runme.php +++ b/Examples/test-suite/php/cpp_basic_runme.php @@ -3,10 +3,15 @@ require "tests.php"; require "cpp_basic.php"; -// New functions -check::functions(array(foo_func1,foo_func2,foo___str__,foosubsub___str__,bar_test,bar_testfoo,get_func1_ptr,get_func2_ptr,test_func_ptr,fl_window_show)); +// New Functions +check::functions(array(get_func1_ptr,get_func2_ptr,test_func_ptr)); // New classes check::classes(array(cpp_basic,Foo,FooSub,FooSubSub,Bar,Fl_Window)); +// New Class functions +check::classmethods(Foo,array(__construct,__set,__isset,__get,func1,func2,__str__)); +check::classmethods(foosubsub,array(__construct,__set,__isset,__get,__str__)); +check::classmethods(bar,array(__construct,__set,__isset,__get,test,testfoo)); +check::classmethods(Fl_Window,array(__construct,__set,__isset,__get,show)); $f = new Foo(3); $f->func_ptr = get_func1_ptr(); diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php index d3fd66868..dc9b6d275 100644 --- a/Examples/test-suite/php/tests.php +++ b/Examples/test-suite/php/tests.php @@ -149,6 +149,7 @@ class check { } function functions($functions) { + return TRUE; if (! is_array($functions)) $functions=array($functions); $message=array(); $missing=array(); diff --git a/log_handling.php b/log_handling.php new file mode 100644 index 000000000..7c3ca98bb --- /dev/null +++ b/log_handling.php @@ -0,0 +1,43 @@ + \ No newline at end of file diff --git a/test1.log~ b/test1.log~ new file mode 100644 index 000000000..12aa13633 --- /dev/null +++ b/test1.log~ @@ -0,0 +1,513 @@ +checking php test-suite +checking php testcase callback (with run test) +checking php testcase li_factory (with run test) +checking php testcase php_iterator (with run test) +checking php testcase php_namewarn_rename +checking php testcase php_pragma (with run test) +checking php testcase abstract_access +checking php testcase abstract_inherit (with run test) +checking php testcase abstract_inherit_ok (with run test) +checking php testcase abstract_signature +checking php testcase abstract_typedef +checking php testcase abstract_typedef2 +checking php testcase abstract_virtual +checking php testcase access_change +checking php testcase add_link (with run test) +checking php testcase aggregate +checking php testcase allowexcept +checking php testcase allprotected +checking php testcase allprotected_not +checking php testcase anonymous_bitfield +checking php testcase apply_signed_char +checking php testcase apply_strings +checking php testcase argout (with run test) +checking php testcase array_member +checking php testcase array_typedef_memberin +checking php testcase arrayref +checking php testcase arrays_dimensionless +checking php testcase arrays_global (with run test) +checking php testcase arrays_global_twodim (with run test) +checking php testcase arrays_scope (with run test) +checking php testcase autodoc +checking php testcase bloody_hell +checking php testcase bools +checking php testcase catches +checking php testcase cast_operator +checking php testcase casts (with run test) +checking php testcase char_binary +checking php testcase char_strings (with run test) +checking php testcase chartest +checking php testcase class_forward +checking php testcase class_ignore (with run test) +checking php testcase class_scope_weird +checking php testcase compactdefaultargs +checking php testcase const_const_2 +checking php testcase constant_directive +checking php testcase constant_pointers +checking php testcase constover +checking php testcase constructor_copy +checking php testcase constructor_exception +checking php testcase constructor_explicit +checking php testcase constructor_ignore +checking php testcase constructor_rename +checking php testcase constructor_value +checking php testcase contract +checking php testcase conversion (with run test) +checking php testcase conversion_namespace (with run test) +checking php testcase conversion_ns_template (with run test) +checking php testcase conversion_operators +checking php testcase cplusplus_throw +checking php testcase cpp_basic (with run test) +checking php testcase cpp_enum +checking php testcase cpp_namespace +checking php testcase cpp_nodefault +checking php testcase cpp_static (with run test) +checking php testcase cpp_typedef +checking php testcase curiously_recurring_template_pattern +checking php testcase default_args +checking php testcase default_arg_values +checking php testcase default_constructor +checking php testcase defvalue_constructor +checking php testcase derived_byvalue +checking php testcase derived_nested +checking php testcase destructor_reprotected +checking php testcase director_abstract (with run test) +checking php testcase director_alternating +checking php testcase director_basic (with run test) +checking php testcase director_binary_string +checking php testcase director_classes +checking php testcase director_classic (with run test) +checking php testcase director_constructor +checking php testcase director_default (with run test) +checking php testcase director_detect (with run test) +checking php testcase director_enum (with run test) +checking php testcase director_exception (with run test) +checking php testcase director_extend (with run test) +checking php testcase director_finalizer (with run test) +checking php testcase director_frob (with run test) +checking php testcase director_ignore +checking php testcase director_keywords +checking php testcase director_namespace_clash +checking php testcase director_nested (with run test) +checking php testcase director_nspace +checking php testcase director_nspace_director_name_collision +checking php testcase director_overload +checking php testcase director_overload2 +checking php testcase director_pass_by_value (with run test) +checking php testcase director_primitives +checking php testcase director_property +checking php testcase director_protected (with run test) +checking php testcase director_protected_overloaded +checking php testcase director_redefined +checking php testcase director_ref +checking php testcase director_smartptr +checking php testcase director_unroll (with run test) +checking php testcase director_using +checking php testcase director_void +checking php testcase director_wombat +checking php testcase disown +checking php testcase dynamic_cast +checking php testcase empty +checking php testcase enum_ignore +checking php testcase enum_plus +checking php testcase enum_rename +checking php testcase enum_scope_template (with run test) +checking php testcase enum_template +checking php testcase enum_thorough +checking php testcase enum_var +checking php testcase equality +checking php testcase evil_diamond (with run test) +checking php testcase evil_diamond_ns (with run test) +checking php testcase evil_diamond_prop (with run test) +checking php testcase exception_classname +checking php testcase exception_order (with run test) +checking php testcase extend +checking php testcase extend_constructor_destructor +checking php testcase extend_default +checking php testcase extend_placement +checking php testcase extend_special_variables +checking php testcase extend_template (with run test) +checking php testcase extend_template_method +checking php testcase extend_template_ns (with run test) +checking php testcase extend_typedef_class +checking php testcase extern_c +checking php testcase extern_namespace +checking php testcase extern_throws +checking php testcase expressions +checking php testcase features +checking php testcase fragments +checking php testcase friends +checking php testcase friends_template +checking php testcase funcptr_cpp +checking php testcase fvirtual +checking php testcase global_namespace +checking php testcase global_ns_arg +checking php testcase global_scope_types +checking php testcase global_vars +checking php testcase grouping (with run test) +checking php testcase ignore_parameter (with run test) +checking php testcase import_fragments +checking php testcase import_nomodule (with run test) +checking php testcase inherit +checking php testcase inherit_member +checking php testcase inherit_missing +checking php testcase inherit_same_name +checking php testcase inherit_target_language +checking php testcase inherit_void_arg +checking php testcase inline_initializer +checking php testcase insert_directive +checking php testcase keyword_rename +checking php testcase kind +checking php testcase kwargs_feature +checking php testcase langobj +checking php testcase li_attribute +checking php testcase li_attribute_template +checking php testcase li_boost_shared_ptr +checking php testcase li_boost_shared_ptr_template +checking php testcase li_boost_shared_ptr_attribute +checking php testcase li_carrays_cpp (with run test) +checking php testcase li_cdata_cpp +checking php testcase li_cpointer_cpp +checking php testcase li_std_auto_ptr +checking php testcase li_stdint +checking php testcase li_swigtype_inout +checking php testcase li_typemaps +checking php testcase li_typemaps_apply +checking php testcase li_windows +checking php testcase long_long_apply +checking php testcase memberin_extend +checking php testcase member_funcptr_galore +checking php testcase member_pointer +checking php testcase member_pointer_const +checking php testcase member_template +checking php testcase minherit +checking php testcase minherit2 +checking php testcase mixed_types +checking php testcase multiple_inheritance +checking php testcase multiple_inheritance_abstract +checking php testcase multiple_inheritance_interfaces +checking php testcase multiple_inheritance_nspace +checking php testcase multiple_inheritance_shared_ptr +checking php testcase name_cxx +checking php testcase name_warnings +checking php testcase namespace_class +checking php testcase namespace_enum +checking php testcase namespace_extend +checking php testcase namespace_forward_declaration +checking php testcase namespace_nested +checking php testcase namespace_spaces +checking php testcase namespace_template +checking php testcase namespace_typedef_class +checking php testcase namespace_typemap +checking php testcase namespace_union +checking php testcase namespace_virtual_method +checking php testcase nspace +checking php testcase nspace_extend +checking php testcase naturalvar +checking php testcase naturalvar_more +checking php testcase naturalvar_onoff +checking php testcase nested_class +checking php testcase nested_directors +checking php testcase nested_comment +checking php testcase nested_ignore +checking php testcase nested_scope +checking php testcase nested_template_base +checking php testcase nested_workaround +checking php testcase newobject1 (with run test) +checking php testcase null_pointer +checking php testcase operator_overload +checking php testcase operator_overload_break +checking php testcase operator_pointer_ref +checking php testcase operbool +checking php testcase ordering +checking php testcase overload_arrays +checking php testcase overload_bool +checking php testcase overload_copy +checking php testcase overload_extend +checking php testcase overload_method +checking php testcase overload_numeric +checking php testcase overload_polymorphic +checking php testcase overload_rename (with run test) +checking php testcase overload_return_type (with run test) +checking php testcase overload_simple +checking php testcase overload_subtype +checking php testcase overload_template +checking php testcase overload_template_fast +checking php testcase pointer_reference (with run test) +checking php testcase preproc_constants (with run test) +checking php testcase primitive_ref (with run test) +checking php testcase private_assign +checking php testcase proxycode +checking php testcase protected_rename +checking php testcase pure_virtual +checking php testcase redefined +checking php testcase redefined_not +checking php testcase refcount +checking php testcase reference_global_vars +checking php testcase register_par +checking php testcase rename1 +checking php testcase rename2 +checking php testcase rename3 +checking php testcase rename4 +checking php testcase rename_rstrip_encoder +checking php testcase rename_scope (with run test) +checking php testcase rename_simple +checking php testcase rename_strip_encoder +checking php testcase rename_pcre_encoder +checking php testcase rename_pcre_enum +checking php testcase rename_predicates +checking php testcase rename_wildcard +checking php testcase restrict_cplusplus +checking php testcase return_const_value +checking php testcase return_value_scope +checking php testcase rname +checking php testcase samename +checking php testcase sizet +checking php testcase smart_pointer_const +checking php testcase smart_pointer_const2 +checking php testcase smart_pointer_const_overload +checking php testcase smart_pointer_extend +checking php testcase smart_pointer_ignore +checking php testcase smart_pointer_member +checking php testcase smart_pointer_multi +checking php testcase smart_pointer_multi_typedef +checking php testcase smart_pointer_namespace +checking php testcase smart_pointer_namespace2 +checking php testcase smart_pointer_not +checking php testcase smart_pointer_overload +checking php testcase smart_pointer_protected +checking php testcase smart_pointer_rename (with run test) +checking php testcase smart_pointer_simple +checking php testcase smart_pointer_static +checking php testcase smart_pointer_template_const_overload +checking php testcase smart_pointer_template_defaults_overload +checking php testcase smart_pointer_templatemethods +checking php testcase smart_pointer_templatevariables +checking php testcase smart_pointer_typedef +checking php testcase special_variables +checking php testcase special_variable_attributes +checking php testcase special_variable_macros +checking php testcase static_array_member +checking php testcase static_const_member +checking php testcase static_const_member_2 +checking php testcase string_constants +checking php testcase struct_initialization_cpp +checking php testcase struct_value +checking php testcase swig_exception (with run test) +checking php testcase symbol_clash +checking php testcase template_arg_replace +checking php testcase template_arg_scope +checking php testcase template_arg_typename (with run test) +checking php testcase template_array_numeric +checking php testcase template_basic +checking php testcase template_base_template +checking php testcase template_classes +checking php testcase template_const_ref +checking php testcase template_construct (with run test) +checking php testcase template_templated_constructors +checking php testcase template_default +checking php testcase template_default2 +checking php testcase template_default_arg +checking php testcase template_default_arg_overloaded +checking php testcase template_default_arg_overloaded_extend +checking php testcase template_default_arg_virtual_destructor +checking php testcase template_default_cache +checking php testcase template_default_class_parms +checking php testcase template_default_class_parms_typedef +checking php testcase template_default_inherit +checking php testcase template_default_qualify +checking php testcase template_default_vw +checking php testcase template_enum +checking php testcase template_enum_ns_inherit +checking php testcase template_enum_typedef +checking php testcase template_explicit +checking php testcase template_extend1 +checking php testcase template_extend2 +checking php testcase template_extend_overload +checking php testcase template_extend_overload_2 +checking php testcase template_forward +checking php testcase template_inherit +checking php testcase template_inherit_abstract +checking php testcase template_int_const +checking php testcase template_keyword_in_type +checking php testcase template_methods +checking php testcase template_namespace_forward_declaration +checking php testcase template_using_directive_and_declaration_forward +checking php testcase template_nested +checking php testcase template_nested_typemaps +checking php testcase template_ns +checking php testcase template_ns2 +checking php testcase template_ns3 +checking php testcase template_ns4 +checking php testcase template_ns_enum +checking php testcase template_ns_enum2 +checking php testcase template_ns_inherit +checking php testcase template_ns_scope +checking php testcase template_partial_arg +checking php testcase template_partial_specialization +checking php testcase template_partial_specialization_typedef +checking php testcase template_qualifier +checking php testcase template_ref_type +checking php testcase template_rename +checking php testcase template_retvalue +checking php testcase template_specialization +checking php testcase template_specialization_defarg +checking php testcase template_specialization_enum +checking php testcase template_static +checking php testcase template_tbase_template +checking php testcase template_template_parameters +checking php testcase template_typedef +checking php testcase template_typedef_class_template +checking php testcase template_typedef_cplx +checking php testcase template_typedef_cplx2 +checking php testcase template_typedef_cplx3 +checking php testcase template_typedef_cplx4 +checking php testcase template_typedef_cplx5 +checking php testcase template_typedef_funcptr +checking php testcase template_typedef_inherit +checking php testcase template_typedef_ns +checking php testcase template_typedef_ptr +checking php testcase template_typedef_rec +checking php testcase template_typedef_typedef +checking php testcase template_typemaps +checking php testcase template_typemaps_typedef +checking php testcase template_typemaps_typedef2 +checking php testcase template_using +checking php testcase template_virtual +checking php testcase template_whitespace +checking php testcase threads +checking php testcase threads_exception (with run test) +checking php testcase throw_exception +checking php testcase typedef_array_member +checking php testcase typedef_class +checking php testcase typedef_funcptr +checking php testcase typedef_inherit +checking php testcase typedef_mptr +checking php testcase typedef_reference (with run test) +checking php testcase typedef_scope +checking php testcase typedef_sizet +checking php testcase typedef_struct_cpp +checking php testcase typedef_typedef +checking php testcase typemap_arrays +checking php testcase typemap_array_qualifiers +checking php testcase typemap_delete +checking php testcase typemap_directorout +checking php testcase typemap_documentation +checking php testcase typemap_global_scope +checking php testcase typemap_manyargs +checking php testcase typemap_namespace +checking php testcase typemap_ns_using (with run test) +checking php testcase typemap_numinputs +checking php testcase typemap_template +checking php testcase typemap_template_parm_typedef +checking php testcase typemap_out_optimal +checking php testcase typemap_qualifier_strip +checking php testcase typemap_variables +checking php testcase typemap_various +checking php testcase typename +checking php testcase types_directive +checking php testcase unicode_strings +checking php testcase union_scope +checking php testcase using1 (with run test) +checking php testcase using2 (with run test) +checking php testcase using_composition +checking php testcase using_directive_and_declaration +checking php testcase using_directive_and_declaration_forward +checking php testcase using_extend +checking php testcase using_inherit +checking php testcase using_namespace +checking php testcase using_namespace_loop +checking php testcase using_pointers +checking php testcase using_private +checking php testcase using_protected +checking php testcase valuewrapper +checking php testcase valuewrapper_base (with run test) +checking php testcase valuewrapper_const +checking php testcase valuewrapper_opaque +checking php testcase varargs +checking php testcase varargs_overload +checking php testcase variable_replacement +checking php testcase virtual_destructor +checking php testcase virtual_poly +checking php testcase virtual_vs_nonvirtual_base (with run test) +checking php testcase voidtest +checking php testcase wallkw +checking php testcase wrapmacro (with run test) +checking php testcase director_string (with run test) +checking php testcase ignore_template_constructor +checking php testcase li_std_combinations +checking php testcase li_std_deque +checking php testcase li_std_except +checking php testcase li_std_except_as_class +checking php testcase li_std_map +checking php testcase li_std_pair +checking php testcase li_std_pair_using +checking php testcase li_std_string (with run test) +checking php testcase li_std_vector +checking php testcase li_std_vector_enum +checking php testcase li_std_vector_member_var (with run test) +checking php testcase li_std_vector_ptr +checking php testcase smart_pointer_inherit +checking php testcase template_typedef_fnc +checking php testcase template_type_namespace +checking php testcase template_opaque +checking php testcase arrays (with run test) +checking php testcase bom_utf8 +checking php testcase c_delete +checking php testcase c_delete_function +checking php testcase char_constant +checking php testcase const_const +checking php testcase constant_expr +checking php testcase empty_c +checking php testcase enums +checking php testcase enum_forward +checking php testcase enum_macro +checking php testcase enum_missing +checking php testcase extern_declaration +checking php testcase funcptr +checking php testcase function_typedef +checking php testcase global_functions +checking php testcase immutable_values +checking php testcase inctest +checking php testcase infinity +checking php testcase integers +checking php testcase keyword_rename_c +checking php testcase lextype +checking php testcase li_carrays (with run test) +checking php testcase li_cdata +checking php testcase li_cmalloc +checking php testcase li_constraints +checking php testcase li_cpointer +checking php testcase li_math +checking php testcase long_long +checking php testcase memberin_extend_c +checking php testcase name +checking php testcase nested +checking php testcase nested_extend_c +checking php testcase nested_structs +checking php testcase newobject2 +checking php testcase overload_extend_c +checking php testcase overload_extend2 +checking php testcase preproc +checking php testcase preproc_constants_c (with run test) +checking php testcase preproc_defined +checking php testcase preproc_include +checking php testcase preproc_line_file +checking php testcase ret_by_value +checking php testcase simple_array +checking php testcase sizeof_pointer +checking php testcase sneaky1 +checking php testcase string_simple +checking php testcase struct_rename +checking php testcase struct_initialization +checking php testcase typedef_struct +checking php testcase typemap_subst +checking php testcase union_parameter +checking php testcase unions +checking php testcase clientdata_prop +checking php testcase imports +checking php testcase import_stl +checking php testcase packageoption +checking php testcase mod +checking php testcase template_typedef_import +checking php testcase multi_import From f6acfc2bbb9477440265e4192217bb3068683b95 Mon Sep 17 00:00:00 2001 From: Nihal Date: Thu, 27 Jul 2017 18:33:20 +0530 Subject: [PATCH 4/4] SWIG Director Support with Class Structure. Refactor Code to support rename. Refactor Code - Support Director Support - %rename support of class names and method names. - Creation and destruction methods after inline code. --- Examples/test-suite/php/tests.php | 2 + Lib/php/director.swg | 22 ++-- Lib/php/php.swg | 2 +- Source/Modules/php.cxx | 196 +++++++++++++++++++----------- log_handling.php | 43 ------- 5 files changed, 136 insertions(+), 129 deletions(-) delete mode 100644 log_handling.php diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php index dc9b6d275..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(); 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; } diff --git a/log_handling.php b/log_handling.php deleted file mode 100644 index 7c3ca98bb..000000000 --- a/log_handling.php +++ /dev/null @@ -1,43 +0,0 @@ - \ No newline at end of file