Refactor Code to use swig_object_wrapper for wrapping classes.

And use void * to store class pointers.
This commit is contained in:
Nihal 2017-07-18 23:30:07 +05:30
commit b5c408ddc1
3 changed files with 102 additions and 156 deletions

View file

@ -119,9 +119,8 @@
%typemap(in) SWIGTYPE & %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"); SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
*/
%} %}
%typemap(in) SWIGTYPE && %typemap(in) SWIGTYPE &&
@ -142,8 +141,8 @@
%typemap(in) SWIGTYPE *DISOWN %typemap(in) SWIGTYPE *DISOWN
%{ %{
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))) {
Z_$upper_param_OBJ_P(&$input)->newobject = 0; Z_FETCH_OBJ_P(&$input)->newobject = 0;
$1 = Z_$upper_param_OBJ_P(&$input)->$lower_param_obj; $1 = ($lower_param *)Z_FETCH_OBJ_P(&$input)->ptr;
} }
else { else {
if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0)
@ -482,11 +481,8 @@
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE
{ {
if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) void *tmp;
_v = 1; _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0);
else
_v = 0;
//_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0);
} }
%typecheck(SWIG_TYPECHECK_POINTER) %typecheck(SWIG_TYPECHECK_POINTER)
@ -496,29 +492,20 @@
SWIGTYPE &&, SWIGTYPE &&,
SWIGTYPE *const& SWIGTYPE *const&
{ {
if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) void *tmp;
_v = 1; _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0);
else
_v = 0;
//_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0);
} }
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *const& %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *const&
{ {
if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) void *tmp;
_v = 1; _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0);
else
_v = 0;
//_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0);
} }
%typecheck(SWIG_TYPECHECK_VOIDPTR) void * %typecheck(SWIG_TYPECHECK_VOIDPTR) void *
{ {
if (Z_TYPE($input) == IS_OBJECT && SWIG_is_correct_object(&$input,$1_descriptor)) void *tmp;
_v = 1; _v = (SWIG_ConvertPtr(&$input, (void **)&tmp, $1_descriptor, 0) >= 0);
else
_v = 0;
//_v = (SWIG_ConvertPtr(&$input, (void**)&tmp, $1_descriptor, 0) >= 0);
} }
/* Exception handling */ /* Exception handling */

View file

@ -56,6 +56,8 @@ static int default_error_code = E_ERROR;
and need freeing, or not */ and need freeing, or not */
typedef struct { typedef struct {
void * ptr; void * ptr;
zend_object std;
HashTable *extras;
int newobject; int newobject;
} swig_object_wrapper; } swig_object_wrapper;
@ -258,46 +260,9 @@ SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *ty
} }
} }
static int #define Z_FETCH_OBJ_P(zv) php_fetch_object(Z_OBJ_P(zv))
is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */
{ static inline
child_class = child_class->parent; swig_object_wrapper * php_fetch_object(zend_object *obj) {
while (child_class) { return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std));
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;
} }

View file

@ -974,6 +974,18 @@ public:
return false; 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;
}
/* Magic methods __set, __get, __isset is declared here in the extension. /* 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. The flag variable is used to decide whether all variables are read or not.
*/ */
@ -1019,8 +1031,8 @@ public:
Printf(all_cs_entry, " PHP_ME(%s,__set,swig_arginfo_00,ZEND_ACC_PUBLIC)\n", class_name); 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, "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, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n");
Printf(f->code, " %s *arg1 = (%s *)(arg->%s_obj);\n", class_name, class_name, class_name); 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, " 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, " if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n"); Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
@ -1051,8 +1063,9 @@ public:
Printf(all_cs_entry, " PHP_ME(%s,__get,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name); 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, "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, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", 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, " %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, " 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, "\tWRONG_PARAM_COUNT;\n}\n\n");
Printf(f->code, " if(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n\n"); Printf(f->code, " if(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n\n");
@ -1081,8 +1094,9 @@ public:
Printf(all_cs_entry, " PHP_ME(%s,__isset,swig_arginfo_0,ZEND_ACC_PUBLIC)\n", class_name); 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, "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, " swig_object_wrapper *arg = (swig_object_wrapper *)Z_FETCH_OBJ_P(getThis());\n", 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, " %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, " 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, " 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, "\tWRONG_PARAM_COUNT;\n}\n\n");
@ -1264,7 +1278,7 @@ public:
Wrapper_add_local(f, "arg0", "zval * arg0"); Wrapper_add_local(f, "arg0", "zval * arg0");
if ((wrapperType == memberfn || wrapperType == membervar)) { if ((wrapperType == memberfn || wrapperType == membervar)) {
num_arguments--; //To remove This Pointer 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); Printf(args, "zval args[%d]", num_arguments);
Wrapper_add_local(f, "args", args); Wrapper_add_local(f, "args", args);
@ -1305,6 +1319,16 @@ public:
if (wrapperType == directorconstructor) if (wrapperType == directorconstructor)
Printf(f->code, "arg0 = &args[0];\n \n"); 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 */ /* Now convert from PHP to C variables */
// At this point, argcount if used is the number of deliberately passed args // At this point, argcount if used is the number of deliberately passed args
// not including this_ptr even if it is used. // not including this_ptr even if it is used.
@ -1346,24 +1370,12 @@ public:
Printf(f->code, "\tif(arg_count > %d) {\n", i); Printf(f->code, "\tif(arg_count > %d) {\n", i);
} }
String *paramType = SwigType_str(pt, 0);
String *paramType_class = NULL; String *paramType_class = NULL;
String *paramType_class_upper = NULL;
bool paramType_valid = is_class(pt); bool paramType_valid = is_class(pt);
if (Strchr(paramType,'*') || Strchr(paramType,'&')) { if (paramType_valid) {
paramType_class = NewString(paramType); paramType_class = get_class_name(pt);
Replace(paramType_class,"*","",DOH_REPLACE_FIRST);
Replace(paramType_class,Strchr(paramType,' '),"",DOH_REPLACE_FIRST);
Chop(paramType_class); 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"))) { if ((tm = Getattr(p, "tmap:in"))) {
@ -1385,13 +1397,12 @@ public:
Printf(param_zval, "getThis()"); Printf(param_zval, "getThis()");
else else
Printf(param_zval, "&%s", source); 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); Replaceall(tm, "$obj_value", param_value);
} }
String *temp_obj = NewStringEmpty(); String *temp_obj = NewStringEmpty();
Printf(temp_obj, "&%s", ln); 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, "$obj_value", (SwigType_isreference(pt) || SwigType_issimple(pt)) ? temp_obj : "NULL"); // Adding this to compile. It won't reach this if $obj_val is required.
Replaceall(tm, "$upper_param", paramType_class_upper);
Replaceall(tm, "$lower_param", paramType_class); Replaceall(tm, "$lower_param", paramType_class);
Setattr(p, "emit:input", source); Setattr(p, "emit:input", source);
Printf(f->code, "%s\n", tm); Printf(f->code, "%s\n", tm);
@ -1472,33 +1483,6 @@ public:
Setattr(n, "wrap:name", wname); 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 */ /* emit function call */
String *actioncode = emit_action(n); String *actioncode = emit_action(n);
@ -1508,7 +1492,7 @@ public:
Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$target", "return_value");
Replaceall(tm, "$result", "return_value"); Replaceall(tm, "$result", "return_value");
Replaceall(tm, "$owner", newobject ? "1" : "0"); 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) { if (retType_class) {
String *retZend_obj = NewStringEmpty(); String *retZend_obj = NewStringEmpty();
Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class); Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class);
@ -1516,6 +1500,7 @@ public:
Printf(ret_other_Zend_obj, "zend_objects_new(%s_ce)", retType_class); 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 : ret_other_Zend_obj)) : "NULL");
} }
Replaceall(tm, "$zend_obj", "NULL");
Replaceall(tm, "$newobj", retType_valid ? "1" : "2"); Replaceall(tm, "$newobj", retType_valid ? "1" : "2");
Replaceall(tm, "$c_obj", constructor? "1" : "0"); Replaceall(tm, "$c_obj", constructor? "1" : "0");
Printf(f->code, "%s\n", tm); Printf(f->code, "%s\n", tm);
@ -1532,10 +1517,20 @@ public:
Printv(f->code, cleanup, NIL); Printv(f->code, cleanup, NIL);
} }
if (constructor) if (constructor) {
Printf(f->code,"obj = Z_%(upper)s_OBJ_P(getThis());\nobj->%s_obj = result;\n\n", class_name, class_name); Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(getThis());\nobj->ptr = result;\n\n", class_name);
else if (retType_valid) Printf(f->code,"ht = Z_OBJ_HT_P(getThis())->get_properties(getThis());\n");
Printf(f->code,"obj = Z_%(upper)s_OBJ_P(return_value);\nobj->%s_obj = result;\n\n", retType_class, retType_class); 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) if (retType_valid)
Printf(f->code, "if (obj)\nobj->newobject = %d;\n", newobject ? 1 : 0); Printf(f->code, "if (obj)\nobj->newobject = %d;\n", newobject ? 1 : 0);
@ -2576,12 +2571,10 @@ done:
String *symname = Getattr(n, "sym:name"); String *symname = Getattr(n, "sym:name");
Setattr(n, "php:proxy", symname); 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, "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, "/* class object handlers for %s */\n",symname);
Printf(s_header, "zend_object_handlers %s_object_handlers;\n",symname); Printf(s_header, "zend_object_handlers %s_object_handlers;\n\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, "/* dtor Method for class %s */\n",symname); 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, "void %s_destroy_object(zend_object *object) {\n",symname);
@ -2591,10 +2584,10 @@ done:
Printf(s_header, "/* Garbage Collection Method for class %s */\n",symname); 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, "void %s_free_storage(zend_object *object) {\n",symname);
Printf(s_header, " if(!object)\n\t return;\n"); 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->newobject)\n\t return;\n");
Printf(s_header, " if(obj->%s_obj)\n",symname); Printf(s_header, " if(obj->ptr)\n");
Printf(s_header, " SWIG_remove(obj->%s_obj);\n",symname); Printf(s_header, " SWIG_remove((%s *)obj->ptr);\n",symname);
Printf(s_header, " if(obj->extras) {\n"); Printf(s_header, " if(obj->extras) {\n");
Printf(s_header, " zend_hash_destroy(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, " FREE_HASHTABLE(obj->extras);\n }\n\n");
@ -2603,10 +2596,9 @@ done:
Printf(s_header, "/* Object Creation Method for class %s */\n",symname); 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, "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, " 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",symname);
Printf(s_header, " %s_object_handlers.offset = XtOffsetOf(struct %s_object, std);\n",symname,symname);
Printf(s_header, " %s_object_handlers.free_obj = %s_free_storage;\n",symname,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, " %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, " obj->std.handlers = &%s_object_handlers;\n obj->newobject = 1;\n return &obj->std;\n}\n\n\n",symname);
@ -2983,32 +2975,34 @@ done:
Printf(f->def, "/* to typecast and do the actual destruction */\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->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); if (!class_name) {
Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL); Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) res->ptr", NIL);
Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", 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_parameter_variables(l, f);
emit_attach_parmmaps(l, f); emit_attach_parmmaps(l, f);
// Get type of first arg, thing to be destructed // Get type of first arg, thing to be destructed
// Skip ignored arguments // Skip ignored arguments
Parm *p = l; Parm *p = l;
//while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
while (checkAttribute(p, "tmap:in:numinputs", "0")) { while (checkAttribute(p, "tmap:in:numinputs", "0")) {
p = Getattr(p, "tmap:in:next"); 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"); Printf(f->code, "thrown:\n");
Append(f->code, "return;\n"); Append(f->code, "return;\n");