Refactor Code and Support phpinterfaces, factory dispatch

- rewire return of type SWIGTYPE
- {NULL, NULL, NULL} to ZEND_FE_END
- feature:warnfilter - 462 of missing setter
- refactor code of return type (replaced)
- support conversion_operator
This commit is contained in:
Nihal 2017-08-04 23:13:19 +05:30 committed by Olly Betts
commit ae71fc2266
4 changed files with 125 additions and 53 deletions

View file

@ -95,7 +95,15 @@ if (!dcast) {
Type *dobj = dynamic_cast<Type *>($1);
if (dobj) {
dcast = 1;
SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj),$descriptor(Type *), $owner);
zend_object *std = NULL;
if ($newobj) {
zend_class_entry *ce = zend_lookup_class(zend_string_init("Type", sizeof("Type")-1, 0));
std = ce->create_object(ce);
}
else {
std = $zend_obj;
}
SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr(dobj), $descriptor(Type *), std);
}
}%enddef
@ -104,6 +112,6 @@ if (!dcast) {
int dcast = 0;
%formacro(%_factory_dispatch, Types)
if (!dcast) {
SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1),$descriptor, $owner);
SWIG_SetZval(return_value, $newobj , $c_obj, SWIG_as_voidptr($1), $descriptor, $zend_obj);
}
}%enddef

View file

@ -421,13 +421,45 @@
#ifdef __cplusplus
{
$&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
SWIG_SetZval(return_value, $newobj , $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj);
swig_object_wrapper *obj = NULL;
HashTable * ht = NULL;
obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value);
obj->ptr = (void *)resultobj;
ht = Z_OBJ_HT_P(return_value)->get_properties(return_value);
if(ht) {
zval zv;
ZVAL_RES(&zv,zend_register_resource(resultobj,*(int *)($&1_descriptor->clientdata)));
zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv);
}
if ($newobj == 1)
obj->newobject = 1;
else
obj->newobject = 0;
}
#else
{
$&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type));
memcpy(resultobj, &$1, sizeof($1_type));
SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
SWIG_SetZval(return_value, $newobj , $c_obj, (void *)resultobj, $&1_descriptor, $zend_obj);
swig_object_wrapper *obj = NULL;
HashTable * ht = NULL;
obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value);
obj->ptr = (void *)resultobj;
ht = Z_OBJ_HT_P(return_value)->get_properties(return_value);
if(ht) {
zval zv;
ZVAL_RES(&zv,zend_register_resource(resultobj,*(int *)($&1_descriptor->clientdata)));
zend_hash_str_add(ht, "_cPtr", sizeof("_cPtr") - 1, &zv);
}
if ($newobj)
obj->newobject = 1;
else
obj->newobject = 0;
}
#endif

View file

@ -225,21 +225,6 @@ SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
return -1;
}
static char const_name[] = "swig_runtime_data_type_pointer";
static swig_module_info *SWIG_Php_GetModule() {
zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1);
if (pointer) {
if (Z_TYPE_P(pointer) == IS_LONG) {
return (swig_module_info *) pointer->value.lval;
}
}
return NULL;
}
static void SWIG_Php_SetModule(swig_module_info *pointer) {
REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, CONST_PERSISTENT | CONST_CS);
}
static void
SWIG_SetZval( zval *zv, int object, int class_obj ,void *ptr, swig_type_info *type, zend_object *std) {
@ -266,3 +251,19 @@ static inline
swig_object_wrapper * php_fetch_object(zend_object *obj) {
return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std));
}
static char const_name[] = "swig_runtime_data_type_pointer";
static swig_module_info *SWIG_Php_GetModule() {
zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1);
if (pointer) {
if (Z_TYPE_P(pointer) == IS_LONG) {
return (swig_module_info *) pointer->value.lval;
}
}
return NULL;
}
static void SWIG_Php_SetModule(swig_module_info *pointer) {
REGISTER_MAIN_LONG_CONSTANT(const_name, (long) pointer, CONST_PERSISTENT | CONST_CS);
}

View file

@ -555,7 +555,7 @@ public:
Language::top(n);
if (Len(classes) > 0)
Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n");
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
SwigPHP_emit_resource_registrations();
SwigPHP_emit_all_creation_free_wrapper();
@ -727,7 +727,7 @@ public:
Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry,
" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
" { NULL, NULL, NULL }\n};\n\n", NIL);
" ZEND_FE_END\n};\n\n", NIL);
Printv(f_begin, s_init, NIL);
Delete(s_header);
Delete(s_wrappers);
@ -1288,8 +1288,11 @@ public:
*/
if (Cmp(strrchr(GetChar(n, "sym:name"),'_'),"_set") == 0)
static_setter = true;
else
static_getter = true;
else if (Cmp(strrchr(GetChar(n, "sym:name"),'_'),"_get") == 0) {
// This is to overcome types that can't be set and hence no setter.
if (Cmp(Getattr(n, "feature:warnfilter"),"462") != 0)
static_getter = true;
}
}
else if (wrapperType == staticmemberfn) {
char *ptr = Char(iname);
@ -1303,6 +1306,7 @@ public:
String *intermediate_method_name = NewString(iname);
Replace(intermediate_method_name, intermediate_name, "", DOH_REPLACE_FIRST);
wname = intermediate_method_name;
//Printf(s_oinit, "ASd %s %s %s\n", iname, name ,wname);
Delete(intermediate_name);
}
else
@ -1405,16 +1409,6 @@ public:
if (wrapperType == directorconstructor)
Printf(f->code, "zval * arg0 = getThis();\n \n");
String *retType_class = NULL;
bool retType_valid = is_class(d);
if (retType_valid) {
retType_class = get_class_name(d);
Chop(retType_class);
Printf(f->code, "\nswig_object_wrapper *obj = NULL;\n");
Printf(f->code, "\nHashTable * ht = NULL;\n");
}
/* Now convert from PHP to C variables */
// At this point, argcount if used is the number of deliberately passed args
// not including this_ptr even if it is used.
@ -1572,6 +1566,16 @@ public:
Setattr(n, "wrap:name", wname);
}
String *retType_class = NULL;
bool retType_valid = is_class(d);
bool retType_operator = false;
if (retType_valid) {
retType_class = get_class_name(d);
Chop(retType_class);
retType_operator = Getattr(n, "conversion_operator") ? true : false;
}
/* emit function call */
String *actioncode = emit_action(n);
@ -1587,7 +1591,7 @@ public:
Printf(retZend_obj, "%s_object_new(%s_ce)", retType_class, retType_class);
String *ret_other_Zend_obj = NewStringEmpty();
Printf(ret_other_Zend_obj, "zend_objects_new(%s_ce)", retType_class);
Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (newobject ? retZend_obj : ret_other_Zend_obj)) : "NULL");
Replaceall(tm, "$zend_obj", retType_valid ? (constructor ? "NULL" : (newobject ? retZend_obj : (retType_operator ? retZend_obj : ret_other_Zend_obj))) : "NULL");
}
Replaceall(tm, "$zend_obj", "NULL");
Replaceall(tm, "$newobj", retType_valid ? "1" : "2");
@ -1606,23 +1610,20 @@ public:
Printv(f->code, cleanup, NIL);
}
if (constructor) {
Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(getThis());\nobj->ptr = (void *)result;\n\n");
Printf(f->code,"ht = Z_OBJ_HT_P(getThis())->get_properties(getThis());\n");
Printf(f->code,"if(ht) {\nzval zv;\n");
Printf(f->code,"ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d));
Printf(f->code,"zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n");
}
else if (retType_valid) {
Printf(f->code,"obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(return_value);\nobj->ptr = (void *)result;\n\n");
Printf(f->code,"ht = Z_OBJ_HT_P(return_value)->get_properties(return_value);\n");
Printf(f->code,"if(ht) {\nzval zv;\n");
Printf(f->code,"ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d));
Printf(f->code,"zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n");
String *zval_ret_obj = constructor ? NewString("getThis()") : NewString("return_value");
if (retType_valid && !SwigType_issimple(d)) {
Printf(f->code, "\n{\nswig_object_wrapper *obj = NULL;\n");
Printf(f->code, "\nHashTable * ht = NULL;\n\n");
Printf(f->code, "obj = (swig_object_wrapper *) Z_FETCH_OBJ_P(%s);\n", zval_ret_obj);
Printf(f->code, "obj->ptr = (void *)result;\n");
Printf(f->code, "ht = Z_OBJ_HT_P(%s)->get_properties(%s);\n", zval_ret_obj, zval_ret_obj);
Printf(f->code, "if(ht) {\nzval zv;\n");
Printf(f->code, "ZVAL_RES(&zv,zend_register_resource(result,*(int *)(SWIGTYPE%s->clientdata)));\n", SwigType_manglestr(d));
Printf(f->code, "zend_hash_str_add(ht, \"_cPtr\", sizeof(\"_cPtr\") - 1, &zv);\n}\n\n");
Printf(f->code, "if (obj)\nobj->newobject = %d;\n}\n\n", newobject ? 1 : 0);
}
if (retType_valid)
Printf(f->code, "if (obj)\nobj->newobject = %d;\n", newobject ? 1 : 0);
/* Look to see if there is any newfree cleanup code */
if (GetFlag(n, "feature:new")) {
if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
@ -2670,7 +2671,7 @@ done:
class_name = className;
if (Len(classes) != 0)
Printf(all_cs_entry, " { NULL, NULL, NULL }\n};\n\n");
Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
Printf(all_cs_entry, "static zend_function_entry class_%s_functions[] = {\n", class_name);
@ -2735,7 +2736,32 @@ done:
}
if (Cmp(symname,className) != 0) {
Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",class_name, class_name, class_name);
Printf(s_oinit, "zend_register_class_alias_ex(\"%s\",sizeof(\"%s\"),%s_ce);\n\n",symname, symname, symname);
}
{
Node *node = NewHash();
Setattr(node, "type", Getattr(n, "name"));
Setfile(node, Getfile(n));
Setline(node, Getline(n));
String *interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0);
Replaceall(interfaces, " ", "");
if (interfaces) {
List *interface_list = Split(interfaces, ',', -1);
int num_interfaces = Len(interface_list);
String *append_interface = NewStringEmpty();
for(int Iterator = 1; Iterator <= num_interfaces; Iterator++) {
String *interface = Getitem(interface_list, Iterator-1);
String *interface_ce = NewStringEmpty();
Printf(interface_ce, "php_interface_ce_%d" , Iterator);
Printf(s_oinit, "zend_class_entry *%s = zend_lookup_class(zend_string_init(\"%s\", sizeof(\"%s\") - 1, 0));\n", interface_ce , interface, interface);
Append(append_interface, interface_ce);
Append(append_interface, " ");
}
Chop(append_interface);
Replaceall(append_interface, " ", ",");
Printf(s_oinit, "zend_class_implements(%s_ce, %d, %s);\n", class_name, num_interfaces, append_interface);
}
}
Printf(s_oinit, "%s_ce->create_object = %s_object_new;\n", class_name, class_name);
@ -3038,17 +3064,22 @@ done:
String *iname = GetChar(n, "sym:name");
ParmList *l = Getattr(n, "parms");
String *name_prefix = NewString("delete_");
String *intermediate_name = NewString(iname);
Replace(intermediate_name, name_prefix, "", DOH_REPLACE_FIRST);
String *destructorname = NewStringEmpty();
Printf(destructorname, "_%s", Swig_name_wrapper(iname));
Setattr(classnode, "destructor", destructorname);
Wrapper *f = NewWrapper();
Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n");
Printf(f->def, "/* to typecast and do the actual destruction */\n");
Printf(f->def, "static void %s(zend_resource *res, const char *type_name) {\n", destructorname);
Printf(f->code, "if(zend_lookup_class(zend_string_init(\"%s\",sizeof(\"%s\")-1,0))) {\n", name, name);
Printf(f->code, "return;\n}\n\n");
Printf(f->def, "\n\nif(zend_lookup_class(zend_string_init(\"%s\",sizeof(\"%s\")-1,0))) {\n", intermediate_name, intermediate_name);
Printf(f->def, "return;\n}\n");
Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) res->ptr", NIL);
Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);