diff options
Diffstat (limited to 'ext/com_dotnet/com_handlers.c')
| -rw-r--r-- | ext/com_dotnet/com_handlers.c | 133 |
1 files changed, 65 insertions, 68 deletions
diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 0a4693fec5..d00cb14f14 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -27,7 +27,7 @@ #include "php_com_dotnet_internal.h" #include "Zend/zend_exceptions.h" -static zval *com_property_read(zval *object, zval *member, int type, void **cahce_slot, zval *rv) +static zval *com_property_read(zend_object *object, zend_string *member, int type, void **cahce_slot, zval *rv) { php_com_dotnet_object *obj; VARIANT v; @@ -35,21 +35,22 @@ static zval *com_property_read(zval *object, zval *member, int type, void **cahc ZVAL_NULL(rv); - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); - convert_to_string_ex(member); - - res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), + res = php_com_do_invoke(obj, ZSTR_VAL(member), ZSTR_LEN(member), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1); if (res == SUCCESS) { php_com_zval_from_variant(rv, &v, obj->code_page); VariantClear(&v); } else if (res == DISP_E_BADPARAMCOUNT) { - php_com_saproxy_create(object, rv, member); + zval zv; + + ZVAL_STR(&zv, member); + php_com_saproxy_create(object, rv, &zv); } } else { php_com_throw_exception(E_INVALIDARG, "this variant has no properties"); @@ -58,18 +59,17 @@ static zval *com_property_read(zval *object, zval *member, int type, void **cahc return rv; } -static zval *com_property_write(zval *object, zval *member, zval *value, void **cache_slot) +static zval *com_property_write(zend_object *object, zend_string *member, zval *value, void **cache_slot) { php_com_dotnet_object *obj; VARIANT v; - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); - convert_to_string_ex(member); - if (SUCCESS == php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), + if (SUCCESS == php_com_do_invoke(obj, ZSTR_VAL(member), ZSTR_LEN(member), DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &v, 1, value, 0)) { VariantClear(&v); } @@ -79,14 +79,14 @@ static zval *com_property_write(zval *object, zval *member, zval *value, void ** return value; } -static zval *com_read_dimension(zval *object, zval *offset, int type, zval *rv) +static zval *com_read_dimension(zend_object *object, zval *offset, int type, zval *rv) { php_com_dotnet_object *obj; VARIANT v; ZVAL_NULL(rv); - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); @@ -115,14 +115,14 @@ static zval *com_read_dimension(zval *object, zval *offset, int type, zval *rv) return rv; } -static void com_write_dimension(zval *object, zval *offset, zval *value) +static void com_write_dimension(zend_object *object, zval *offset, zval *value) { php_com_dotnet_object *obj; zval args[2]; VARIANT v; HRESULT res; - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (V_VT(&obj->v) == VT_DISPATCH) { ZVAL_COPY_VALUE(&args[0], offset); @@ -187,16 +187,15 @@ static zval *com_object_get(zval *property) } #endif -static int com_property_exists(zval *object, zval *member, int check_empty, void **cache_slot) +static int com_property_exists(zend_object *object, zend_string *member, int check_empty, void **cache_slot) { DISPID dispid; php_com_dotnet_object *obj; - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (V_VT(&obj->v) == VT_DISPATCH) { - convert_to_string_ex(member); - if (SUCCEEDED(php_com_get_id_of_name(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), &dispid))) { + if (SUCCEEDED(php_com_get_id_of_name(obj, ZSTR_VAL(member), ZSTR_LEN(member), &dispid))) { /* TODO: distinguish between property and method! */ return 1; } @@ -207,23 +206,23 @@ static int com_property_exists(zval *object, zval *member, int check_empty, void return 0; } -static int com_dimension_exists(zval *object, zval *member, int check_empty) +static int com_dimension_exists(zend_object *object, zval *member, int check_empty) { php_error_docref(NULL, E_WARNING, "Operation not yet supported on a COM object"); return 0; } -static void com_property_delete(zval *object, zval *member, void **cache_slot) +static void com_property_delete(zend_object *object, zend_string *member, void **cache_slot) { php_error_docref(NULL, E_WARNING, "Cannot delete properties from a COM object"); } -static void com_dimension_delete(zval *object, zval *offset) +static void com_dimension_delete(zend_object *object, zval *offset) { php_error_docref(NULL, E_WARNING, "Cannot delete properties from a COM object"); } -static HashTable *com_properties_get(zval *object) +static HashTable *com_properties_get(zend_object *object) { /* TODO: use type-info to get all the names and values ? * DANGER: if we do that, there is a strong possibility for @@ -247,11 +246,42 @@ static void function_dtor(zval *zv) static PHP_FUNCTION(com_method_handler) { zval *object = getThis(); + zend_string *method = EX(func)->common.function_name; + zval *args = NULL; + php_com_dotnet_object *obj = CDNO_FETCH(object); + int nargs; + VARIANT v; + int ret = FAILURE; + + if (V_VT(&obj->v) != VT_DISPATCH) { + goto exit; + } + + nargs = ZEND_NUM_ARGS(); + + if (nargs) { + args = (zval *)safe_emalloc(sizeof(zval), nargs, 0); + zend_get_parameters_array_ex(nargs, args); + } - Z_OBJ_HANDLER_P(object, call_method)( - ((zend_internal_function*)EX(func))->function_name, - Z_OBJ_P(object), - INTERNAL_FUNCTION_PARAM_PASSTHRU); + VariantInit(&v); + + if (SUCCESS == php_com_do_invoke_byref(obj, (zend_internal_function*)EX(func), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args)) { + php_com_zval_from_variant(return_value, &v, obj->code_page); + ret = SUCCESS; + VariantClear(&v); + } + + if (args) { + efree(args); + } + +exit: + /* Cleanup trampoline */ + ZEND_ASSERT(EX(func)->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE); + zend_string_release(EX(func)->common.function_name); + zend_free_trampoline(EX(func)); + EX(func) = NULL; } static zend_function *com_method_get(zend_object **object_ptr, zend_string *name, const zval *key) @@ -271,7 +301,8 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name /* check cache */ if (obj->method_cache == NULL || NULL == (fptr = zend_hash_find_ptr(obj->method_cache, name))) { - f.type = ZEND_OVERLOADED_FUNCTION; + memset(&f, 0, sizeof(zend_internal_function)); + f.type = ZEND_INTERNAL_FUNCTION; f.num_args = 0; f.arg_info = NULL; f.scope = obj->ce; @@ -346,6 +377,7 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name if (fptr) { /* duplicate this into a new chunk of emalloc'd memory, * since the engine will efree it */ + zend_string_addref(fptr->function_name); func = emalloc(sizeof(*fptr)); memcpy(func, fptr, sizeof(*fptr)); @@ -355,40 +387,6 @@ static zend_function *com_method_get(zend_object **object_ptr, zend_string *name return NULL; } -static int com_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) -{ - zval *args = NULL; - php_com_dotnet_object *obj = (php_com_dotnet_object*)object; - int nargs; - VARIANT v; - int ret = FAILURE; - - if (V_VT(&obj->v) != VT_DISPATCH) { - return FAILURE; - } - - nargs = ZEND_NUM_ARGS(); - - if (nargs) { - args = (zval *)safe_emalloc(sizeof(zval), nargs, 0); - zend_get_parameters_array_ex(nargs, args); - } - - VariantInit(&v); - - if (SUCCESS == php_com_do_invoke_byref(obj, (zend_internal_function*)EX(func), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args)) { - php_com_zval_from_variant(return_value, &v, obj->code_page); - ret = SUCCESS; - VariantClear(&v); - } - - if (args) { - efree(args); - } - - return ret; -} - static zend_function *com_constructor_get(zend_object *object) { php_com_dotnet_object *obj = (php_com_dotnet_object *) object; @@ -461,14 +459,14 @@ static int com_objects_compare(zval *object1, zval *object2) return ret; } -static int com_object_cast(zval *readobj, zval *writeobj, int type) +static int com_object_cast(zend_object *readobj, zval *writeobj, int type) { php_com_dotnet_object *obj; VARIANT v; VARTYPE vt = VT_EMPTY; HRESULT res = S_OK; - obj = CDNO_FETCH(readobj); + obj = (php_com_dotnet_object*) readobj; ZVAL_NULL(writeobj); VariantInit(&v); @@ -518,12 +516,12 @@ static int com_object_cast(zval *readobj, zval *writeobj, int type) return zend_std_cast_object_tostring(readobj, writeobj, type); } -static int com_object_count(zval *object, zend_long *count) +static int com_object_count(zend_object *object, zend_long *count) { php_com_dotnet_object *obj; LONG ubound = 0, lbound = 0; - obj = CDNO_FETCH(object); + obj = (php_com_dotnet_object*) object; if (!V_ISARRAY(&obj->v)) { return FAILURE; @@ -555,7 +553,6 @@ zend_object_handlers php_com_object_handlers = { com_dimension_delete, com_properties_get, com_method_get, - com_call_method, com_constructor_get, com_class_name_get, com_objects_compare, @@ -619,11 +616,11 @@ void php_com_object_free_storage(zend_object *object) zend_object_std_dtor(object); } -zend_object* php_com_object_clone(zval *object) +zend_object* php_com_object_clone(zend_object *object) { php_com_dotnet_object *cloneobj, *origobject; - origobject = (php_com_dotnet_object*)Z_OBJ_P(object); + origobject = (php_com_dotnet_object*) object; cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object)); memcpy(cloneobj, origobject, sizeof(*cloneobj)); |
