diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-08-11 18:37:26 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-08-11 18:37:26 +0400 |
commit | 8013a27ad9ae71d6eac451c183c8e2cee333f751 (patch) | |
tree | 48fa66b2d0032f0f59b45d2ad1bfd19d7673035f | |
parent | 4c716e8b516146f0a10b0b89078ccd096a8b4b7b (diff) | |
download | php-git-8013a27ad9ae71d6eac451c183c8e2cee333f751.tar.gz |
Implemented ext/com_dotnet support for phpng
-rw-r--r-- | Zend/zend_ts_hash.c | 33 | ||||
-rw-r--r-- | Zend/zend_ts_hash.h | 35 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_com.c | 102 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_dotnet.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_handlers.c | 147 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_iterator.c | 56 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_misc.c | 13 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_persist.c | 60 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_saproxy.c | 205 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_typeinfo.c | 40 | ||||
-rw-r--r-- | ext/com_dotnet/com_variant.c | 31 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/com_wrapper.c | 165 | ||||
-rwxr-xr-x[-rw-r--r--] | ext/com_dotnet/php_com_dotnet_internal.h | 24 |
13 files changed, 488 insertions, 429 deletions
diff --git a/Zend/zend_ts_hash.c b/Zend/zend_ts_hash.c index 92cd62128e..f6523574ae 100644 --- a/Zend/zend_ts_hash.c +++ b/Zend/zend_ts_hash.c @@ -333,6 +333,39 @@ ZEND_API int zend_ts_hash_rehash(TsHashTable *ht) return retval; } +ZEND_API zval *zend_ts_hash_str_find(TsHashTable *ht, const char *key, int len) +{ + zval *retval; + + begin_read(ht); + retval = zend_hash_str_find(TS_HASH(ht), key, len); + end_read(ht); + + return retval; +} + +ZEND_API zval *_zend_ts_hash_str_update(TsHashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zval *retval; + + begin_write(ht); + retval = zend_hash_str_update(TS_HASH(ht), key, len, pData); + end_write(ht); + + return retval; +} + +ZEND_API zval *_zend_ts_hash_str_add(TsHashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zval *retval; + + begin_write(ht); + retval = zend_hash_str_add(TS_HASH(ht), key, len, pData); + end_write(ht); + + return retval; +} + /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_ts_hash.h b/Zend/zend_ts_hash.h index 4b0a507368..fcf8c3cda1 100644 --- a/Zend/zend_ts_hash.h +++ b/Zend/zend_ts_hash.h @@ -102,6 +102,41 @@ void zend_ts_hash_display_pListTail(TsHashTable *ht); void zend_ts_hash_display(TsHashTable *ht); #endif +ZEND_API zval *zend_ts_hash_str_find(TsHashTable *ht, const char *key, int len); +ZEND_API zval *_zend_ts_hash_str_update(TsHashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_ts_hash_str_add(TsHashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); + +#define zend_ts_hash_str_update(ht, key, len, pData) \ + _zend_ts_hash_str_update(ht, key, len, pData ZEND_FILE_LINE_CC) +#define zend_ts_hash_str_add(ht, key, len, pData) \ + _zend_ts_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC) + +static inline void *zend_ts_hash_str_find_ptr(TsHashTable *ht, const char *str, int len) +{ + zval *zv; + + zv = zend_ts_hash_str_find(ht, str, len); + return zv ? Z_PTR_P(zv) : NULL; +} + +static inline void *zend_ts_hash_str_update_ptr(TsHashTable *ht, const char *str, int len, void *pData) +{ + zval tmp, *zv; + + ZVAL_PTR(&tmp, pData); + zv = zend_ts_hash_str_update(ht, str, len, &tmp); + return zv ? Z_PTR_P(zv) : NULL; +} + +static inline void *zend_ts_hash_str_add_ptr(TsHashTable *ht, const char *str, int len, void *pData) +{ + zval tmp, *zv; + + ZVAL_PTR(&tmp, pData); + zv = zend_ts_hash_str_add(ht, str, len, &tmp); + return zv ? Z_PTR_P(zv) : NULL; +} + END_EXTERN_C() #define ZEND_TS_INIT_SYMTABLE(ht) \ diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index 500cabd41c..6d3b15876f 100644..100755 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -66,50 +66,50 @@ PHP_FUNCTION(com_create_instance) &typelib_name, &typelib_name_len)) { php_com_throw_exception(E_INVALIDARG, "Could not create COM object - invalid arguments!" TSRMLS_CC); - ZVAL_NULL(object); + ZEND_CTOR_MAKE_NULL(); return; } if (server_name) { ctx = CLSCTX_REMOTE_SERVER; } else if (server_params) { - zval **tmp; + zval *tmp; /* decode the data from the array */ - if (SUCCESS == zend_hash_find(HASH_OF(server_params), - "Server", sizeof("Server"), (void**)&tmp)) { + if (NULL != (tmp = zend_hash_str_find(HASH_OF(server_params), + "Server", sizeof("Server")-1))) { convert_to_string_ex(tmp); - server_name = Z_STRVAL_PP(tmp); - server_name_len = Z_STRLEN_PP(tmp); + server_name = Z_STRVAL_P(tmp); + server_name_len = Z_STRLEN_P(tmp); ctx = CLSCTX_REMOTE_SERVER; } - if (SUCCESS == zend_hash_find(HASH_OF(server_params), - "Username", sizeof("Username"), (void**)&tmp)) { + if (NULL != (tmp = zend_hash_str_find(HASH_OF(server_params), + "Username", sizeof("Username")-1))) { convert_to_string_ex(tmp); - user_name = Z_STRVAL_PP(tmp); - user_name_len = Z_STRLEN_PP(tmp); + user_name = Z_STRVAL_P(tmp); + user_name_len = Z_STRLEN_P(tmp); } - if (SUCCESS == zend_hash_find(HASH_OF(server_params), - "Password", sizeof("Password"), (void**)&tmp)) { + if (NULL != (tmp = zend_hash_str_find(HASH_OF(server_params), + "Password", sizeof("Password")-1))) { convert_to_string_ex(tmp); - password = Z_STRVAL_PP(tmp); - password_len = Z_STRLEN_PP(tmp); + password = Z_STRVAL_P(tmp); + password_len = Z_STRLEN_P(tmp); } - if (SUCCESS == zend_hash_find(HASH_OF(server_params), - "Domain", sizeof("Domain"), (void**)&tmp)) { + if (NULL != (tmp = zend_hash_str_find(HASH_OF(server_params), + "Domain", sizeof("Domain")-1))) { convert_to_string_ex(tmp); - domain_name = Z_STRVAL_PP(tmp); - domain_name_len = Z_STRLEN_PP(tmp); + domain_name = Z_STRVAL_P(tmp); + domain_name_len = Z_STRLEN_P(tmp); } - if (SUCCESS == zend_hash_find(HASH_OF(server_params), - "Flags", sizeof("Flags"), (void**)&tmp)) { + if (NULL != (tmp = zend_hash_str_find(HASH_OF(server_params), + "Flags", sizeof("Flags")-1))) { convert_to_long_ex(tmp); - ctx = (CLSCTX)Z_LVAL_PP(tmp); + ctx = (CLSCTX)Z_LVAL_P(tmp); } } @@ -215,8 +215,8 @@ PHP_FUNCTION(com_create_instance) } if (server_name) { - STR_FREE((char*)info.pwszName); - STR_FREE((char*)authid.User); + if (info.pwszName) efree(info.pwszName); + if (authid.User) efree(authid.User); } efree(moniker); @@ -230,7 +230,7 @@ PHP_FUNCTION(com_create_instance) php_com_throw_exception(res, msg TSRMLS_CC); efree(msg); - ZVAL_NULL(object); + ZEND_CTOR_MAKE_NULL(); return; } @@ -263,7 +263,7 @@ PHP_FUNCTION(com_create_instance) if (SUCCEEDED(ITypeLib_GetDocumentation(TL, -1, &name, NULL, NULL, NULL))) { typelib_name = php_com_olestring_to_string(name, &typelib_name_len, obj->code_page TSRMLS_CC); - if (SUCCESS == zend_ts_hash_add(&php_com_typelibraries, typelib_name, typelib_name_len+1, (void*)&TL, sizeof(ITypeLib*), NULL)) { + if (NULL != zend_ts_hash_str_add_ptr(&php_com_typelibraries, typelib_name, typelib_name_len, TL)) { php_com_import_typelib(TL, mode, obj->code_page TSRMLS_CC); /* add a reference for the hash */ @@ -420,14 +420,14 @@ HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name, { OLECHAR *olename; HRESULT hr; - DISPID *dispid_ptr; + zval *tmp; if (namelen == -1) { namelen = strlen(name); } - if (obj->id_of_name_cache && SUCCESS == zend_hash_find(obj->id_of_name_cache, name, namelen, (void**)&dispid_ptr)) { - *dispid = *dispid_ptr; + if (obj->id_of_name_cache && NULL != (tmp = zend_hash_str_find(obj->id_of_name_cache, name, namelen))) { + *dispid = Z_LVAL_P(tmp); return S_OK; } @@ -449,12 +449,15 @@ HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name, efree(olename); if (SUCCEEDED(hr)) { + zval tmp; + /* cache the mapping */ if (!obj->id_of_name_cache) { ALLOC_HASHTABLE(obj->id_of_name_cache); zend_hash_init(obj->id_of_name_cache, 2, NULL, NULL, 0); } - zend_hash_update(obj->id_of_name_cache, name, namelen, dispid, sizeof(*dispid), NULL); + ZVAL_LONG(&tmp, *dispid); + zend_hash_str_update(obj->id_of_name_cache, name, namelen, &tmp); } return hr; @@ -462,14 +465,14 @@ HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name, /* the core of COM */ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, - WORD flags, VARIANT *v, int nargs, zval ***args TSRMLS_DC) + WORD flags, VARIANT *v, int nargs, zval *args TSRMLS_DC) { DISPID dispid, altdispid; DISPPARAMS disp_params; HRESULT hr; VARIANT *vargs = NULL, *byref_vals = NULL; int i, byref_count = 0, j; - zend_internal_function *f = (zend_internal_function*)EG(current_execute_data)->function_state.function; + zend_internal_function *f = (zend_internal_function*)EG(current_execute_data)->func; /* assumption: that the active function (f) is the function we generated for the engine */ if (!f || f->arg_info == NULL) { @@ -507,7 +510,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, for (j = 0, i = 0; i < nargs; i++) { if (f->arg_info[nargs - i - 1].pass_by_reference) { /* put the value into byref_vals instead */ - php_com_variant_from_zval(&byref_vals[j], *args[nargs - i - 1], obj->code_page TSRMLS_CC); + php_com_variant_from_zval(&byref_vals[j], &args[nargs - i - 1], obj->code_page TSRMLS_CC); /* if it is already byref, "move" it into the vargs array, otherwise * make vargs a reference to this value */ @@ -522,14 +525,14 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, } j++; } else { - php_com_variant_from_zval(&vargs[i], *args[nargs - i - 1], obj->code_page TSRMLS_CC); + php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page TSRMLS_CC); } } } else { /* Invoke'd args are in reverse order */ for (i = 0; i < nargs; i++) { - php_com_variant_from_zval(&vargs[i], *args[nargs - i - 1], obj->code_page TSRMLS_CC); + php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page TSRMLS_CC); } } @@ -552,7 +555,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, for (i = 0, j = 0; i < nargs; i++) { /* if this was byref, update the zval */ if (f && f->arg_info[nargs - i - 1].pass_by_reference) { - SEPARATE_ZVAL_IF_NOT_REF(args[nargs - i - 1]); + SEPARATE_ZVAL_IF_NOT_REF(&args[nargs - i - 1]); /* if the variant is pointing at the byref_vals, we need to map * the pointee value as a zval; otherwise, the value is pointing @@ -560,13 +563,13 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, if (V_VT(&vargs[i]) & VT_BYREF) { if (vargs[i].byref == &V_UINT(&byref_vals[j])) { /* copy that value */ - php_com_zval_from_variant(*args[nargs - i - 1], &byref_vals[j], + php_com_zval_from_variant(&args[nargs - i - 1], &byref_vals[j], obj->code_page TSRMLS_CC); } } else { /* not sure if this can ever happen; the variant we marked as BYREF * is no longer BYREF - copy its value */ - php_com_zval_from_variant(*args[nargs - i - 1], &vargs[i], + php_com_zval_from_variant(&args[nargs - i - 1], &vargs[i], obj->code_page TSRMLS_CC); } VariantClear(&byref_vals[j]); @@ -583,7 +586,7 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, int php_com_do_invoke_by_id(php_com_dotnet_object *obj, DISPID dispid, - WORD flags, VARIANT *v, int nargs, zval **args, int silent, int allow_noarg TSRMLS_DC) + WORD flags, VARIANT *v, int nargs, zval *args, int silent, int allow_noarg TSRMLS_DC) { DISPID altdispid; DISPPARAMS disp_params; @@ -597,7 +600,7 @@ int php_com_do_invoke_by_id(php_com_dotnet_object *obj, DISPID dispid, /* Invoke'd args are in reverse order */ for (i = 0; i < nargs; i++) { - php_com_variant_from_zval(&vargs[i], args[nargs - i - 1], obj->code_page TSRMLS_CC); + php_com_variant_from_zval(&vargs[i], &args[nargs - i - 1], obj->code_page TSRMLS_CC); } disp_params.cArgs = nargs; @@ -630,7 +633,7 @@ int php_com_do_invoke_by_id(php_com_dotnet_object *obj, DISPID dispid, } int php_com_do_invoke(php_com_dotnet_object *obj, char *name, int namelen, - WORD flags, VARIANT *v, int nargs, zval **args, int allow_noarg TSRMLS_DC) + WORD flags, VARIANT *v, int nargs, zval *args, int allow_noarg TSRMLS_DC) { DISPID dispid; HRESULT hr; @@ -664,8 +667,13 @@ PHP_FUNCTION(com_create_guid) php_com_initialize(TSRMLS_C); if (CoCreateGuid(&retval) == S_OK && StringFromCLSID(&retval, &guid_string) == S_OK) { - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = php_com_olestring_to_string(guid_string, &Z_STRLEN_P(return_value), CP_ACP TSRMLS_CC); + int len; + char *str; + + str = php_com_olestring_to_string(guid_string, &len, CP_ACP TSRMLS_CC); + RETVAL_STRINGL(str, len); + // TODO: avoid reallocation ??? + efree(str); CoTaskMemFree(guid_string); } else { @@ -696,12 +704,12 @@ PHP_FUNCTION(com_event_sink) if (sink && Z_TYPE_P(sink) == IS_ARRAY) { /* 0 => typelibname, 1 => dispname */ - zval **tmp; + zval *tmp; - if (zend_hash_index_find(Z_ARRVAL_P(sink), 0, (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) - typelibname = Z_STRVAL_PP(tmp); - if (zend_hash_index_find(Z_ARRVAL_P(sink), 1, (void**)&tmp) == SUCCESS && Z_TYPE_PP(tmp) == IS_STRING) - dispname = Z_STRVAL_PP(tmp); + if ((tmp = zend_hash_index_find(Z_ARRVAL_P(sink), 0)) != NULL && Z_TYPE_P(tmp) == IS_STRING) + typelibname = Z_STRVAL_P(tmp); + if ((tmp = zend_hash_index_find(Z_ARRVAL_P(sink), 1)) != NULL && Z_TYPE_P(tmp) == IS_STRING) + dispname = Z_STRVAL_P(tmp); } else if (sink != NULL) { convert_to_string(sink); dispname = Z_STRVAL_P(sink); diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index 0aa1a2a9c7..c582309c28 100644..100755 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -207,7 +207,7 @@ PHP_FUNCTION(com_dotnet_create_instance) if (err) LocalFree(err); php_com_throw_exception(hr, buf TSRMLS_CC); - ZVAL_NULL(object); + ZEND_CTOR_MAKE_NULL(); return; } } @@ -221,7 +221,7 @@ PHP_FUNCTION(com_dotnet_create_instance) &datatype_name, &datatype_name_len, &obj->code_page)) { php_com_throw_exception(E_INVALIDARG, "Could not create .Net object - invalid arguments!" TSRMLS_CC); - ZVAL_NULL(object); + ZEND_CTOR_MAKE_NULL(); return; } @@ -287,7 +287,7 @@ PHP_FUNCTION(com_dotnet_create_instance) LocalFree(err); } php_com_throw_exception(hr, buf TSRMLS_CC); - ZVAL_NULL(object); + ZEND_CTOR_MAKE_NULL(); return; } } diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index c889c9a06a..0d83a86648 100644..100755 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -29,42 +29,38 @@ #include "php_com_dotnet_internal.h" #include "Zend/zend_exceptions.h" -static zval *com_property_read(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +static zval *com_property_read(zval *object, zval *member, int type, void **cahce_slot, zval *rv TSRMLS_DC) { - zval *return_value; php_com_dotnet_object *obj; VARIANT v; HRESULT res; - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - Z_SET_REFCOUNT_P(return_value, 0); - Z_UNSET_ISREF_P(return_value); + ZVAL_NULL(rv); obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); - convert_to_string_ex(&member); + convert_to_string_ex(member); res = php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 0, NULL, 1 TSRMLS_CC); if (res == SUCCESS) { - php_com_zval_from_variant(return_value, &v, obj->code_page TSRMLS_CC); + php_com_zval_from_variant(rv, &v, obj->code_page TSRMLS_CC); VariantClear(&v); } else if (res == DISP_E_BADPARAMCOUNT) { - php_com_saproxy_create(object, return_value, member TSRMLS_CC); + php_com_saproxy_create(object, rv, member TSRMLS_CC); } } else { php_com_throw_exception(E_INVALIDARG, "this variant has no properties" TSRMLS_CC); } - return return_value; + return rv; } -static void com_property_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void com_property_write(zval *object, zval *member, zval *value, void **cache_slot TSRMLS_DC) { php_com_dotnet_object *obj; VARIANT v; @@ -74,9 +70,9 @@ static void com_property_write(zval *object, zval *member, zval *value, const ze if (V_VT(&obj->v) == VT_DISPATCH) { VariantInit(&v); - convert_to_string_ex(&member); + convert_to_string_ex(member); if (SUCCESS == php_com_do_invoke(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), - DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &v, 1, &value, 0 TSRMLS_CC)) { + DISPATCH_PROPERTYPUT|DISPATCH_PROPERTYPUTREF, &v, 1, value, 0 TSRMLS_CC)) { VariantClear(&v); } } else { @@ -84,16 +80,12 @@ static void com_property_write(zval *object, zval *member, zval *value, const ze } } -static zval *com_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) +static zval *com_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC) { - zval *return_value; php_com_dotnet_object *obj; VARIANT v; - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); - Z_SET_REFCOUNT_P(return_value, 0); - Z_UNSET_ISREF_P(return_value); + ZVAL_NULL(rv); obj = CDNO_FETCH(object); @@ -101,8 +93,8 @@ static zval *com_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) VariantInit(&v); if (SUCCESS == php_com_do_invoke_by_id(obj, DISPID_VALUE, - DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 1, &offset, 0, 0 TSRMLS_CC)) { - php_com_zval_from_variant(return_value, &v, obj->code_page TSRMLS_CC); + DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, 1, offset, 0, 0 TSRMLS_CC)) { + php_com_zval_from_variant(rv, &v, obj->code_page TSRMLS_CC); VariantClear(&v); } } else if (V_ISARRAY(&obj->v)) { @@ -110,32 +102,32 @@ static zval *com_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) if (SafeArrayGetDim(V_ARRAY(&obj->v)) == 1) { if (php_com_safearray_get_elem(&obj->v, &v, Z_LVAL_P(offset) TSRMLS_CC)) { - php_com_wrap_variant(return_value, &v, obj->code_page TSRMLS_CC); + php_com_wrap_variant(rv, &v, obj->code_page TSRMLS_CC); VariantClear(&v); } } else { - php_com_saproxy_create(object, return_value, offset TSRMLS_CC); + php_com_saproxy_create(object, rv, offset TSRMLS_CC); } } else { php_com_throw_exception(E_INVALIDARG, "this variant is not an array type" TSRMLS_CC); } - return return_value; + return rv; } static void com_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) { php_com_dotnet_object *obj; - zval *args[2]; + zval args[2]; VARIANT v; HRESULT res; obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { - args[0] = offset; - args[1] = value; + ZVAL_COPY_VALUE(&args[0], offset); + ZVAL_COPY_VALUE(&args[1], value); VariantInit(&v); @@ -196,7 +188,7 @@ static zval *com_object_get(zval *property TSRMLS_DC) } #endif -static int com_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +static int com_property_exists(zval *object, zval *member, int check_empty, void **cache_slot TSRMLS_DC) { DISPID dispid; php_com_dotnet_object *obj; @@ -204,7 +196,7 @@ static int com_property_exists(zval *object, zval *member, int check_empty, cons obj = CDNO_FETCH(object); if (V_VT(&obj->v) == VT_DISPATCH) { - convert_to_string_ex(&member); + convert_to_string_ex(member); if (SUCCEEDED(php_com_get_id_of_name(obj, Z_STRVAL_P(member), Z_STRLEN_P(member), &dispid TSRMLS_CC))) { /* TODO: distinguish between property and method! */ return 1; @@ -222,7 +214,7 @@ static int com_dimension_exists(zval *object, zval *member, int check_empty TSRM return 0; } -static void com_property_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) +static void com_property_delete(zval *object, zval *member, void **cache_slot TSRMLS_DC) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object"); } @@ -242,49 +234,50 @@ static HashTable *com_properties_get(zval *object TSRMLS_DC) return NULL; } -static void function_dtor(void *pDest) +static void function_dtor(zval *zv) { - zend_internal_function *f = (zend_internal_function*)pDest; + zend_internal_function *f = (zend_internal_function*)Z_PTR_P(zv); - efree((char*)f->function_name); + STR_RELEASE(f->function_name); if (f->arg_info) { efree(f->arg_info); } + efree(f); } static PHP_FUNCTION(com_method_handler) { - Z_OBJ_HANDLER_P(getThis(), call_method)( - ((zend_internal_function*)EG(current_execute_data)->function_state.function)->function_name, + zval *object = getThis(); + + Z_OBJ_HANDLER_P(object, call_method)( + ((zend_internal_function*)EG(current_execute_data)->func)->function_name, + Z_OBJ_P(object), INTERNAL_FUNCTION_PARAM_PASSTHRU); } -static union _zend_function *com_method_get(zval **object_ptr, char *name, int len, const zend_literal *key TSRMLS_DC) +static union _zend_function *com_method_get(zend_object **object_ptr, zend_string *name, const zval *key TSRMLS_DC) { zend_internal_function f, *fptr = NULL; - php_com_dotnet_object *obj; union _zend_function *func; DISPID dummy; - zval *object = *object_ptr; - - obj = CDNO_FETCH(object); + php_com_dotnet_object *obj = (php_com_dotnet_object*)*object_ptr; if (V_VT(&obj->v) != VT_DISPATCH) { return NULL; } - if (FAILED(php_com_get_id_of_name(obj, name, len, &dummy TSRMLS_CC))) { + if (FAILED(php_com_get_id_of_name(obj, name->val, name->len, &dummy TSRMLS_CC))) { return NULL; } /* check cache */ - if (obj->method_cache == NULL || FAILURE == zend_hash_find(obj->method_cache, name, len, (void**)&fptr)) { + if (obj->method_cache == NULL || NULL == (fptr = zend_hash_find_ptr(obj->method_cache, name))) { f.type = ZEND_OVERLOADED_FUNCTION; f.num_args = 0; f.arg_info = NULL; f.scope = obj->ce; f.fn_flags = ZEND_ACC_CALL_VIA_HANDLER; - f.function_name = estrndup(name, len); + f.function_name = STR_COPY(name); f.handler = PHP_FN(com_method_handler); fptr = &f; @@ -300,7 +293,7 @@ static union _zend_function *com_method_get(zval **object_ptr, char *name, int l int i; if (SUCCEEDED(ITypeInfo_GetTypeComp(obj->typeinfo, &comp))) { - olename = php_com_string_to_olestring(name, len, obj->code_page TSRMLS_CC); + olename = php_com_string_to_olestring(name->val, name->len, obj->code_page TSRMLS_CC); lhash = LHashValOfNameSys(SYS_WIN32, LOCALE_SYSTEM_DEFAULT, olename); if (SUCCEEDED(ITypeComp_Bind(comp, olename, lhash, INVOKE_FUNC, &TI, &kind, &bindptr))) { @@ -348,7 +341,7 @@ static union _zend_function *com_method_get(zval **object_ptr, char *name, int l zend_hash_init(obj->method_cache, 2, NULL, function_dtor, 0); } - zend_hash_update(obj->method_cache, name, len, &f, sizeof(f), (void**)&fptr); + zend_hash_update_mem(obj->method_cache, name, &f, sizeof(f)); } } @@ -364,15 +357,13 @@ static union _zend_function *com_method_get(zval **object_ptr, char *name, int l return NULL; } -static int com_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) +static int com_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) { - zval ***args = NULL; - php_com_dotnet_object *obj; + zval *args = NULL; + php_com_dotnet_object *obj = (php_com_dotnet_object*)object; int nargs; VARIANT v; int ret = FAILURE; - - obj = CDNO_FETCH(getThis()); if (V_VT(&obj->v) != VT_DISPATCH) { return FAILURE; @@ -381,13 +372,13 @@ static int com_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) nargs = ZEND_NUM_ARGS(); if (nargs) { - args = (zval ***)safe_emalloc(sizeof(zval *), nargs, 0); + 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, (char*)method, -1, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args TSRMLS_CC)) { + if (SUCCESS == php_com_do_invoke_byref(obj, method->val, method->len, DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, nargs, args TSRMLS_CC)) { php_com_zval_from_variant(return_value, &v, obj->code_page TSRMLS_CC); ret = SUCCESS; VariantClear(&v); @@ -400,16 +391,14 @@ static int com_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) return ret; } -static union _zend_function *com_constructor_get(zval *object TSRMLS_DC) +static union _zend_function *com_constructor_get(zend_object *object TSRMLS_DC) { - php_com_dotnet_object *obj; + php_com_dotnet_object *obj = (php_com_dotnet_object *) object; static zend_internal_function c, d, v; - obj = CDNO_FETCH(object); - #define POPULATE_CTOR(f, fn) \ f.type = ZEND_INTERNAL_FUNCTION; \ - f.function_name = (char *) obj->ce->name; \ + f.function_name = obj->ce->name; \ f.scope = obj->ce; \ f.arg_info = NULL; \ f.num_args = 0; \ @@ -417,7 +406,7 @@ static union _zend_function *com_constructor_get(zval *object TSRMLS_DC) f.handler = ZEND_FN(fn); \ return (union _zend_function*)&f; - switch (obj->ce->name[0]) { + switch (obj->ce->name->val[0]) { #if HAVE_MSCOREE_H case 'd': POPULATE_CTOR(d, com_dotnet_create_instance); @@ -434,23 +423,18 @@ static union _zend_function *com_constructor_get(zval *object TSRMLS_DC) } } -static zend_class_entry *com_class_entry_get(const zval *object TSRMLS_DC) +static zend_class_entry *com_class_entry_get(const zend_object *object TSRMLS_DC) { - php_com_dotnet_object *obj; - obj = CDNO_FETCH(object); + php_com_dotnet_object *obj = (php_com_dotnet_object *)object; return obj->ce; } -static int com_class_name_get(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) +static zend_string* com_class_name_get(const zend_object *object, int parent TSRMLS_DC) { - php_com_dotnet_object *obj; - obj = CDNO_FETCH(object); + php_com_dotnet_object *obj = (php_com_dotnet_object *)object; - *class_name = estrndup(obj->ce->name, obj->ce->name_length); - *class_name_len = obj->ce->name_length; - - return 0; + return STR_COPY(obj->ce->name); } /* This compares two variants for equality */ @@ -513,7 +497,8 @@ static int com_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC) case IS_DOUBLE: vt = VT_R8; break; - case IS_BOOL: + case IS_FALSE: + case IS_TRUE: vt = VT_BOOL; break; case IS_STRING: @@ -560,7 +545,10 @@ static int com_object_count(zval *object, long *count TSRMLS_DC) } zend_object_handlers php_com_object_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, + 0, + php_com_object_free_storage, + zend_objects_destroy_object, + php_com_object_clone, com_property_read, com_property_write, com_read_dimension, @@ -610,7 +598,7 @@ void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable TSR } } -void php_com_object_free_storage(void *object TSRMLS_DC) +void php_com_object_free_storage(zend_object *object TSRMLS_DC) { php_com_dotnet_object *obj = (php_com_dotnet_object*)object; @@ -635,14 +623,13 @@ void php_com_object_free_storage(void *object TSRMLS_DC) zend_hash_destroy(obj->id_of_name_cache); FREE_HASHTABLE(obj->id_of_name_cache); } - efree(obj); } -void php_com_object_clone(void *object, void **clone_ptr TSRMLS_DC) +zend_object* php_com_object_clone(zval *object TSRMLS_DC) { php_com_dotnet_object *cloneobj, *origobject; - origobject = (php_com_dotnet_object*)object; + origobject = (php_com_dotnet_object*)Z_OBJ_P(object); cloneobj = (php_com_dotnet_object*)emalloc(sizeof(php_com_dotnet_object)); memcpy(cloneobj, origobject, sizeof(*cloneobj)); @@ -659,13 +646,12 @@ void php_com_object_clone(void *object, void **clone_ptr TSRMLS_DC) ITypeInfo_AddRef(cloneobj->typeinfo); } - *clone_ptr = cloneobj; + return (zend_object*)cloneobj; } -zend_object_value php_com_object_new(zend_class_entry *ce TSRMLS_DC) +zend_object* php_com_object_new(zend_class_entry *ce TSRMLS_DC) { php_com_dotnet_object *obj; - zend_object_value retval; php_com_initialize(TSRMLS_C); obj = emalloc(sizeof(*obj)); @@ -674,10 +660,9 @@ zend_object_value php_com_object_new(zend_class_entry *ce TSRMLS_DC) VariantInit(&obj->v); obj->code_page = CP_ACP; obj->ce = ce; - obj->zo.ce = ce; - retval.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC); - retval.handlers = &php_com_object_handlers; + zend_object_std_init(&obj->zo, ce TSRMLS_CC); + obj->zo.handlers = &php_com_object_handlers; - return retval; + return (zend_object*)obj; } diff --git a/ext/com_dotnet/com_iterator.c b/ext/com_dotnet/com_iterator.c index d6f22efcdf..7da10f1b66 100644..100755 --- a/ext/com_dotnet/com_iterator.c +++ b/ext/com_dotnet/com_iterator.c @@ -38,45 +38,42 @@ struct php_com_iterator { VARIANT safe_array; VARTYPE sa_type; LONG sa_max; - zval *zdata; + zval zdata; }; static void com_iter_dtor(zend_object_iterator *iter TSRMLS_DC) { - struct php_com_iterator *I = (struct php_com_iterator*)iter->data; + struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data); if (I->ev) { IEnumVARIANT_Release(I->ev); } VariantClear(&I->v); VariantClear(&I->safe_array); - if (I->zdata) { - zval_ptr_dtor((zval**)&I->zdata); - } - efree(I); + zval_ptr_dtor(&I->zdata); } static int com_iter_valid(zend_object_iterator *iter TSRMLS_DC) { - struct php_com_iterator *I = (struct php_com_iterator*)iter->data; + struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data); - if (I->zdata) { + if (Z_TYPE(I->zdata) != IS_UNDEF) { return SUCCESS; } return FAILURE; } -static void com_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +static zval* com_iter_get_data(zend_object_iterator *iter TSRMLS_DC) { - struct php_com_iterator *I = (struct php_com_iterator*)iter->data; + struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data); - *data = &I->zdata; + return &I->zdata; } static void com_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC) { - struct php_com_iterator *I = (struct php_com_iterator*)iter->data; + struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data); if (I->key == (ulong)-1) { ZVAL_NULL(key); @@ -87,16 +84,16 @@ static void com_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC) static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC) { - struct php_com_iterator *I = (struct php_com_iterator*)iter->data; + struct php_com_iterator *I = (struct php_com_iterator*)Z_PTR(iter->data); unsigned long n_fetched; - zval *ptr; + zval ptr; /* release current cached element */ VariantClear(&I->v); - if (I->zdata) { - zval_ptr_dtor((zval**)&I->zdata); - I->zdata = NULL; + if (Z_TYPE(I->zdata) != IS_UNDEF) { + zval_ptr_dtor(&I->zdata); + ZVAL_UNDEF(&I->zdata); } if (I->ev) { @@ -121,10 +118,10 @@ static int com_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC) } } - MAKE_STD_ZVAL(ptr); - php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC); + ZVAL_NULL(&ptr); + php_com_zval_from_variant(&ptr, &I->v, I->code_page TSRMLS_CC); /* php_com_wrap_variant(ptr, &I->v, I->code_page TSRMLS_CC); */ - I->zdata = ptr; + ZVAL_COPY_VALUE(&I->zdata, &ptr); return SUCCESS; } @@ -146,7 +143,7 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int b DISPPARAMS dp; VARIANT v; unsigned long n_fetched; - zval *ptr; + zval ptr; if (by_ref) { zend_error(E_ERROR, "An iterator cannot be used with foreach by reference"); @@ -163,10 +160,11 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int b VariantInit(&v); I = (struct php_com_iterator*)ecalloc(1, sizeof(*I)); + zend_iterator_init(&I->iter TSRMLS_CC); I->iter.funcs = &com_iter_funcs; - I->iter.data = I; + Z_PTR(I->iter.data) = I; I->code_page = obj->code_page; - I->zdata = NULL; + ZVAL_UNDEF(&I->zdata); VariantInit(&I->safe_array); VariantInit(&I->v); @@ -193,9 +191,9 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int b /* pre-fetch the element */ if (php_com_safearray_get_elem(&I->safe_array, &I->v, bound TSRMLS_CC)) { I->key = bound; - MAKE_STD_ZVAL(ptr); - php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC); - I->zdata = ptr; + ZVAL_NULL(&ptr); + php_com_zval_from_variant(&ptr, &I->v, I->code_page TSRMLS_CC); + ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { I->key = (ulong)-1; } @@ -227,9 +225,9 @@ zend_object_iterator *php_com_iter_get(zend_class_entry *ce, zval *object, int b if (SUCCEEDED(IEnumVARIANT_Next(I->ev, 1, &I->v, &n_fetched)) && n_fetched > 0) { /* indicate that we have element 0 */ I->key = 0; - MAKE_STD_ZVAL(ptr); - php_com_zval_from_variant(ptr, &I->v, I->code_page TSRMLS_CC); - I->zdata = ptr; + ZVAL_NULL(&ptr); + php_com_zval_from_variant(&ptr, &I->v, I->code_page TSRMLS_CC); + ZVAL_COPY_VALUE(&I->zdata, &ptr); } else { /* indicate that there are no more items */ I->key = (ulong)-1; diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c index b65a6be85d..5cd6808b36 100644..100755 --- a/ext/com_dotnet/com_misc.c +++ b/ext/com_dotnet/com_misc.c @@ -60,9 +60,9 @@ PHP_COM_DOTNET_API void php_com_wrap_dispatch(zval *z, IDispatch *disp, IDispatch_AddRef(V_DISPATCH(&obj->v)); IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo); - Z_TYPE_P(z) = IS_OBJECT; - z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC); - z->value.obj.handlers = &php_com_object_handlers; + zend_object_std_init(&obj->zo, php_com_variant_class_entry TSRMLS_CC); + obj->zo.handlers = &php_com_object_handlers; + ZVAL_OBJ(z, &obj->zo); } PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v, @@ -84,10 +84,9 @@ PHP_COM_DOTNET_API void php_com_wrap_variant(zval *z, VARIANT *v, IDispatch_GetTypeInfo(V_DISPATCH(&obj->v), 0, LANG_NEUTRAL, &obj->typeinfo); } - Z_TYPE_P(z) = IS_OBJECT; - - z->value.obj.handle = zend_objects_store_put(obj, NULL, php_com_object_free_storage, php_com_object_clone TSRMLS_CC); - z->value.obj.handlers = &php_com_object_handlers; + zend_object_std_init(&obj->zo, php_com_variant_class_entry TSRMLS_CC); + obj->zo.handlers = &php_com_object_handlers; + ZVAL_OBJ(z, &obj->zo); } /* this is a convenience function for fetching a particular diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c index aaddf9ce9a..66e3dec640 100644..100755 --- a/ext/com_dotnet/com_persist.c +++ b/ext/com_dotnet/com_persist.c @@ -41,13 +41,13 @@ typedef struct { DWORD engine_thread; LONG refcount; php_stream *stream; - int id; + zend_resource *res; } php_istream; static int le_istream; static void istream_destructor(php_istream *stm TSRMLS_DC); -static void istream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void istream_dtor(zend_resource *rsrc TSRMLS_DC) { php_istream *stm = (php_istream *)rsrc->ptr; istream_destructor(stm TSRMLS_CC); @@ -97,8 +97,8 @@ static ULONG STDMETHODCALLTYPE stm_release(IStream *This) ret = InterlockedDecrement(&stm->refcount); if (ret == 0) { /* destroy it */ - if (stm->id) - zend_list_delete(stm->id); + if (stm->res) + zend_list_delete(stm->res); } return ret; } @@ -251,10 +251,10 @@ static struct IStreamVtbl php_istream_vtbl = { static void istream_destructor(php_istream *stm TSRMLS_DC) { - if (stm->id) { - int id = stm->id; - stm->id = 0; - zend_list_delete(id); + if (stm->res) { + zend_resource *res = stm->res; + stm->res = NULL; + zend_list_delete(res); return; } @@ -262,7 +262,7 @@ static void istream_destructor(php_istream *stm TSRMLS_DC) CoDisconnectObject((IUnknown*)stm, 0); } - zend_list_delete(stm->stream->rsrc_id); + zend_list_delete(stm->stream->res); CoTaskMemFree(stm); } @@ -271,6 +271,7 @@ static void istream_destructor(php_istream *stm TSRMLS_DC) PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSRMLS_DC) { php_istream *stm = (php_istream*)CoTaskMemAlloc(sizeof(*stm)); + zval *tmp; if (stm == NULL) return NULL; @@ -281,8 +282,9 @@ PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSR stm->refcount = 1; stm->stream = stream; - zend_list_addref(stream->rsrc_id); - stm->id = zend_list_insert(stm, le_istream TSRMLS_CC); + GC_REFCOUNT(stream->res)++; + tmp = zend_list_insert(stm, le_istream TSRMLS_CC); + stm->res = Z_RES_P(tmp); return (IStream*)stm; } @@ -291,7 +293,7 @@ PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream TSR #define CPH_SME(fname, arginfo) PHP_ME(com_persist, fname, arginfo, ZEND_ACC_ALLOW_STATIC|ZEND_ACC_PUBLIC) #define CPH_METHOD(fname) static PHP_METHOD(com_persist, fname) -#define CPH_FETCH() php_com_persist_helper *helper = (php_com_persist_helper*)zend_object_store_get_object(getThis() TSRMLS_CC); +#define CPH_FETCH() php_com_persist_helper *helper = (php_com_persist_helper*)Z_OBJ_P(getThis()); #define CPH_NO_OBJ() if (helper->unk == NULL) { php_com_throw_exception(E_INVALIDARG, "No COM object is associated with this helper instance" TSRMLS_CC); return; } @@ -347,9 +349,12 @@ CPH_METHOD(GetCurFileName) res = IPersistFile_GetCurFile(helper->ipf, &olename); if (res == S_OK) { - Z_TYPE_P(return_value) = IS_STRING; - Z_STRVAL_P(return_value) = php_com_olestring_to_string(olename, - &Z_STRLEN_P(return_value), helper->codepage TSRMLS_CC); + int len; + char *str = php_com_olestring_to_string(olename, + &len, helper->codepage TSRMLS_CC); + RETVAL_STRINGL(str, len); + // TODO: avoid reallocarion??? + efree(str); CoTaskMemFree(olename); return; } else if (res == S_FALSE) { @@ -545,7 +550,7 @@ CPH_METHOD(LoadFromStream) return; } - php_stream_from_zval_no_verify(stream, &zstm); + php_stream_from_zval_no_verify(stream, zstm); if (stream == NULL) { php_com_throw_exception(E_INVALIDARG, "expected a stream" TSRMLS_CC); @@ -607,7 +612,7 @@ CPH_METHOD(SaveToStream) return; } - php_stream_from_zval_no_verify(stream, &zstm); + php_stream_from_zval_no_verify(stream, zstm); if (stream == NULL) { php_com_throw_exception(E_INVALIDARG, "expected a stream" TSRMLS_CC); @@ -688,7 +693,7 @@ static const zend_function_entry com_persist_helper_methods[] = { PHP_FE_END }; -static void helper_free_storage(void *obj TSRMLS_DC) +static void helper_free_storage(zend_object *obj TSRMLS_DC) { php_com_persist_helper *object = (php_com_persist_helper*)obj; @@ -705,17 +710,15 @@ static void helper_free_storage(void *obj TSRMLS_DC) IUnknown_Release(object->unk); } zend_object_std_dtor(&object->std TSRMLS_CC); - efree(object); } -static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC) +static zend_object* helper_clone(zval *obj TSRMLS_DC) { - php_com_persist_helper *clone, *object = (php_com_persist_helper*)obj; + php_com_persist_helper *clone, *object = (php_com_persist_helper*)Z_OBJ_P(obj); clone = emalloc(sizeof(*object)); memcpy(clone, object, sizeof(*object)); - *clone_ptr = clone; zend_object_std_init(&clone->std, object->std.ce TSRMLS_CC); @@ -731,22 +734,20 @@ static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC) if (clone->unk) { IUnknown_AddRef(clone->unk); } + return (zend_object*)clone; } -static zend_object_value helper_new(zend_class_entry *ce TSRMLS_DC) +static zend_object* helper_new(zend_class_entry *ce TSRMLS_DC) { php_com_persist_helper *helper; - zend_object_value retval; helper = emalloc(sizeof(*helper)); memset(helper, 0, sizeof(*helper)); zend_object_std_init(&helper->std, helper_ce TSRMLS_CC); - - retval.handle = zend_objects_store_put(helper, NULL, helper_free_storage, helper_clone TSRMLS_CC); - retval.handlers = &helper_handlers; + helper->std.handlers = &helper_handlers; - return retval; + return &helper->std; } int php_com_persist_minit(INIT_FUNC_ARGS) @@ -754,7 +755,8 @@ int php_com_persist_minit(INIT_FUNC_ARGS) zend_class_entry ce; memcpy(&helper_handlers, zend_get_std_object_handlers(), sizeof(helper_handlers)); - helper_handlers.clone_obj = NULL; + helper_handlers.free_obj = helper_free_storage; + helper_handlers.clone_obj = helper_clone; INIT_CLASS_ENTRY(ce, "COMPersistHelper", com_persist_helper_methods); ce.create_object = helper_new; diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index 0d557e60ee..9b3716f43a 100644..100755 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -37,6 +37,7 @@ #include "Zend/zend_exceptions.h" typedef struct { + zend_object std; /* the object we a proxying for; we hold a refcount to it */ zval *zobj; php_com_dotnet_object *obj; @@ -45,95 +46,89 @@ typedef struct { LONG dimensions; /* this is an array whose size_is(dimensions) */ - zval **indices; + zval *indices; } php_com_saproxy; typedef struct { zend_object_iterator iter; - zval *proxy_obj; + zval proxy_obj; + zval data; php_com_saproxy *proxy; LONG key; LONG imin, imax; LONG *indices; } php_com_saproxy_iter; -#define SA_FETCH(zv) (php_com_saproxy*)zend_object_store_get_object(zv TSRMLS_CC) +#define SA_FETCH(zv) (php_com_saproxy*)Z_OBJ_P(zv) static inline void clone_indices(php_com_saproxy *dest, php_com_saproxy *src, int ndims) { int i; for (i = 0; i < ndims; i++) { - MAKE_STD_ZVAL(dest->indices[i]); - *dest->indices[i] = *src->indices[i]; - zval_copy_ctor(dest->indices[i]); + ZVAL_DUP(&dest->indices[i], &src->indices[i]); } } -static zval *saproxy_property_read(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) +static zval *saproxy_property_read(zval *object, zval *member, int type, void **cahce_slot, zval *rv TSRMLS_DC) { - zval *return_value; - - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); + ZVAL_NULL(rv); php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC); - return return_value; + return rv; } -static void saproxy_property_write(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) +static void saproxy_property_write(zval *object, zval *member, zval *value, void **cache_slot TSRMLS_DC) { php_com_throw_exception(E_INVALIDARG, "safearray has no properties" TSRMLS_CC); } -static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_DC) +static zval *saproxy_read_dimension(zval *object, zval *offset, int type, zval *rv TSRMLS_DC) { php_com_saproxy *proxy = SA_FETCH(object); - zval *return_value; UINT dims, i; SAFEARRAY *sa; LONG ubound, lbound; HRESULT res; - MAKE_STD_ZVAL(return_value); - ZVAL_NULL(return_value); + ZVAL_NULL(rv); if (V_VT(&proxy->obj->v) == VT_DISPATCH) { VARIANT v; - zval **args; + zval *args; /* prop-get using first dimension as the property name, * all subsequent dimensions and the offset as parameters */ - args = safe_emalloc(proxy->dimensions + 1, sizeof(zval *), 0); + args = safe_emalloc(proxy->dimensions + 1, sizeof(zval), 0); for (i = 1; i < (UINT) proxy->dimensions; i++) { args[i-1] = proxy->indices[i]; } - args[i-1] = offset; + ZVAL_COPY_VALUE(&args[i-1], offset); - convert_to_string(proxy->indices[0]); + convert_to_string(&proxy->indices[0]); VariantInit(&v); - res = php_com_do_invoke(proxy->obj, Z_STRVAL_P(proxy->indices[0]), - Z_STRLEN_P(proxy->indices[0]), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, + res = php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), + Z_STRLEN(proxy->indices[0]), DISPATCH_METHOD|DISPATCH_PROPERTYGET, &v, proxy->dimensions, args, 0 TSRMLS_CC); if (res == SUCCESS) { - php_com_zval_from_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC); + php_com_zval_from_variant(rv, &v, proxy->obj->code_page TSRMLS_CC); VariantClear(&v); } else if (res == DISP_E_BADPARAMCOUNT) { /* return another proxy */ - php_com_saproxy_create(object, return_value, offset TSRMLS_CC); + php_com_saproxy_create(object, rv, offset TSRMLS_CC); } - return return_value; + return rv; } else if (!V_ISARRAY(&proxy->obj->v)) { php_com_throw_exception(E_INVALIDARG, "invalid read from com proxy object" TSRMLS_CC); - return return_value; + return rv; } /* the SafeArray case */ @@ -147,7 +142,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ if ((UINT) proxy->dimensions >= dims) { /* too many dimensions */ php_com_throw_exception(E_INVALIDARG, "too many dimensions!" TSRMLS_CC); - return return_value; + return rv; } /* bounds check */ @@ -156,7 +151,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ if (Z_LVAL_P(offset) < lbound || Z_LVAL_P(offset) > ubound) { php_com_throw_exception(DISP_E_BADINDEX, "index out of bounds" TSRMLS_CC); - return return_value; + return rv; } if (dims - 1 == proxy->dimensions) { @@ -171,8 +166,8 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ /* copy indices from proxy */ for (i = 0; i < dims; i++) { - convert_to_long(proxy->indices[i]); - indices[i] = Z_LVAL_P(proxy->indices[i]); + convert_to_long(&proxy->indices[i]); + indices[i] = Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ @@ -193,7 +188,7 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ efree(indices); if (SUCCEEDED(res)) { - php_com_wrap_variant(return_value, &v, proxy->obj->code_page TSRMLS_CC); + php_com_wrap_variant(rv, &v, proxy->obj->code_page TSRMLS_CC); } else { php_com_throw_exception(res, NULL TSRMLS_CC); } @@ -202,10 +197,10 @@ static zval *saproxy_read_dimension(zval *object, zval *offset, int type TSRMLS_ } else { /* return another proxy */ - php_com_saproxy_create(object, return_value, offset TSRMLS_CC); + php_com_saproxy_create(object, rv, offset TSRMLS_CC); } - return return_value; + return rv; } static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRMLS_DC) @@ -219,18 +214,18 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM /* We do a prop-set using the first dimension as the property name, * all subsequent dimensions and offset as parameters, with value as * the final value */ - zval **args = safe_emalloc(proxy->dimensions + 2, sizeof(zval *), 0); + zval *args = safe_emalloc(proxy->dimensions + 2, sizeof(zval), 0); for (i = 1; i < (UINT) proxy->dimensions; i++) { - args[i-1] = proxy->indices[i]; + ZVAL_COPY_VALUE(&args[i-1], &proxy->indices[i]); } - args[i-1] = offset; - args[i] = value; + ZVAL_COPY_VALUE(&args[i-1], offset); + ZVAL_COPY_VALUE(&args[i], value); - convert_to_string(proxy->indices[0]); + convert_to_string(&proxy->indices[0]); VariantInit(&v); - if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL_P(proxy->indices[0]), - Z_STRLEN_P(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1, + if (SUCCESS == php_com_do_invoke(proxy->obj, Z_STRVAL(proxy->indices[0]), + Z_STRLEN(proxy->indices[0]), DISPATCH_PROPERTYPUT, &v, proxy->dimensions + 1, args, 0 TSRMLS_CC)) { VariantClear(&v); } @@ -245,8 +240,8 @@ static void saproxy_write_dimension(zval *object, zval *offset, zval *value TSRM indices = safe_emalloc(dims, sizeof(LONG), 0); /* copy indices from proxy */ for (i = 0; i < dims; i++) { - convert_to_long(proxy->indices[i]); - indices[i] = Z_LVAL_P(proxy->indices[i]); + convert_to_long(&proxy->indices[i]); + indices[i] = Z_LVAL(proxy->indices[i]); } /* add user-supplied index */ @@ -293,7 +288,7 @@ static zval *saproxy_object_get(zval *property TSRMLS_DC) } #endif -static int saproxy_property_exists(zval *object, zval *member, int check_empty, const zend_literal *key TSRMLS_DC) +static int saproxy_property_exists(zval *object, zval *member, int check_empty, void **cache_slot TSRMLS_DC) { /* no properties */ return 0; @@ -305,7 +300,7 @@ static int saproxy_dimension_exists(zval *object, zval *member, int check_empty return 0; } -static void saproxy_property_delete(zval *object, zval *member, const zend_literal *key TSRMLS_DC) +static void saproxy_property_delete(zval *object, zval *member, void **cache_slot TSRMLS_DC) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot delete properties from a COM object"); } @@ -321,33 +316,31 @@ static HashTable *saproxy_properties_get(zval *object TSRMLS_DC) return NULL; } -static union _zend_function *saproxy_method_get(zval **object, const char *name, int len, const zend_literal *key TSRMLS_DC) +static union _zend_function *saproxy_method_get(zend_object **object, zend_string *name, const zval *key TSRMLS_DC) { /* no methods */ return NULL; } -static int saproxy_call_method(const char *method, INTERNAL_FUNCTION_PARAMETERS) +static int saproxy_call_method(zend_string *method, zend_object *object, INTERNAL_FUNCTION_PARAMETERS) { return FAILURE; } -static union _zend_function *saproxy_constructor_get(zval *object TSRMLS_DC) +static union _zend_function *saproxy_constructor_get(zend_object *object TSRMLS_DC) { /* user cannot instantiate */ return NULL; } -static zend_class_entry *saproxy_class_entry_get(const zval *object TSRMLS_DC) +static zend_class_entry *saproxy_class_entry_get(const zend_object *object TSRMLS_DC) { return php_com_saproxy_class_entry; } -static int saproxy_class_name_get(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) +static zend_string* saproxy_class_name_get(const zend_object *object, int parent TSRMLS_DC) { - *class_name = estrndup(php_com_saproxy_class_entry->name, php_com_saproxy_class_entry->name_length); - *class_name_len = php_com_saproxy_class_entry->name_length; - return 0; + return STR_COPY(php_com_saproxy_class_entry->name); } static int saproxy_objects_compare(zval *object1, zval *object2 TSRMLS_DC) @@ -377,8 +370,41 @@ static int saproxy_count_elements(zval *object, long *count TSRMLS_DC) return SUCCESS; } +static void saproxy_free_storage(zend_object *object TSRMLS_DC) +{ + php_com_saproxy *proxy = (php_com_saproxy *)object; +//??? int i; +//??? +//??? for (i = 0; i < proxy->dimensions; i++) { +//??? if (proxy->indices) { +//??? FREE_ZVAL(proxy->indices[i]); +//??? } +//??? } + + zval_ptr_dtor(proxy->zobj); + efree(proxy->indices); +} + +static zend_object* saproxy_clone(zval *object TSRMLS_DC) +{ + php_com_saproxy *proxy = (php_com_saproxy *)Z_OBJ_P(object); + php_com_saproxy *cloneproxy; + + cloneproxy = emalloc(sizeof(*cloneproxy)); + memcpy(cloneproxy, proxy, sizeof(*cloneproxy)); + + Z_ADDREF_P(cloneproxy->zobj); + cloneproxy->indices = safe_emalloc(cloneproxy->dimensions, sizeof(zval *), 0); + clone_indices(cloneproxy, proxy, proxy->dimensions); + + return &cloneproxy->std; +} + zend_object_handlers php_com_saproxy_handlers = { - ZEND_OBJECTS_STORE_HANDLERS, + 0, + saproxy_free_storage, + zend_objects_destroy_object, + saproxy_clone, saproxy_property_read, saproxy_property_write, saproxy_read_dimension, @@ -401,37 +427,6 @@ zend_object_handlers php_com_saproxy_handlers = { saproxy_count_elements }; -static void saproxy_free_storage(void *object TSRMLS_DC) -{ - php_com_saproxy *proxy = (php_com_saproxy *)object; - int i; - - for (i = 0; i < proxy->dimensions; i++) { - if (proxy->indices) { - FREE_ZVAL(proxy->indices[i]); - } - } - - zval_ptr_dtor(&proxy->zobj); - efree(proxy->indices); - efree(proxy); -} - -static void saproxy_clone(void *object, void **clone_ptr TSRMLS_DC) -{ - php_com_saproxy *proxy = (php_com_saproxy *)object; - php_com_saproxy *cloneproxy; - - cloneproxy = emalloc(sizeof(*cloneproxy)); - memcpy(cloneproxy, proxy, sizeof(*cloneproxy)); - - Z_ADDREF_P(cloneproxy->zobj); - cloneproxy->indices = safe_emalloc(cloneproxy->dimensions, sizeof(zval *), 0); - clone_indices(cloneproxy, proxy, proxy->dimensions); - - *clone_ptr = cloneproxy; -} - int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS_DC) { php_com_saproxy *proxy, *rel = NULL; @@ -456,13 +451,11 @@ int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS clone_indices(proxy, rel, rel->dimensions); } - MAKE_STD_ZVAL(proxy->indices[proxy->dimensions-1]); - *proxy->indices[proxy->dimensions-1] = *index; - zval_copy_ctor(proxy->indices[proxy->dimensions-1]); + ZVAL_DUP(&proxy->indices[proxy->dimensions-1], index); - Z_TYPE_P(proxy_out) = IS_OBJECT; - Z_OBJ_HANDLE_P(proxy_out) = zend_objects_store_put(proxy, NULL, saproxy_free_storage, saproxy_clone TSRMLS_CC); - Z_OBJ_HT_P(proxy_out) = &php_com_saproxy_handlers; + zend_object_std_init(&proxy->std, php_com_saproxy_class_entry TSRMLS_CC); + proxy->std.handlers = &php_com_saproxy_handlers; + ZVAL_OBJ(proxy_out, &proxy->std); return 1; } @@ -471,7 +464,7 @@ int php_com_saproxy_create(zval *com_object, zval *proxy_out, zval *index TSRMLS static void saproxy_iter_dtor(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); zval_ptr_dtor(&I->proxy_obj); @@ -481,17 +474,16 @@ static void saproxy_iter_dtor(zend_object_iterator *iter TSRMLS_DC) static int saproxy_iter_valid(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); return (I->key < I->imax) ? SUCCESS : FAILURE; } -static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRMLS_DC) +static zval* saproxy_iter_get_data(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); VARIANT v; VARTYPE vt; - zval *return_value, **ptr_ptr; SAFEARRAY *sa; I->indices[I->proxy->dimensions-1] = I->key; @@ -510,18 +502,16 @@ static void saproxy_iter_get_data(zend_object_iterator *iter, zval ***data TSRML SafeArrayGetElement(sa, I->indices, &v.lVal); } - MAKE_STD_ZVAL(return_value); - php_com_wrap_variant(return_value, &v, I->proxy->obj->code_page TSRMLS_CC); + ZVAL_NULL(&I->data); + php_com_wrap_variant(&I->data, &v, I->proxy->obj->code_page TSRMLS_CC); VariantClear(&v); - ptr_ptr = emalloc(sizeof(*ptr_ptr)); - *ptr_ptr = return_value; - *data = ptr_ptr; + return &I->data; } static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); if (I->key == -1) { ZVAL_NULL(key); @@ -532,7 +522,7 @@ static void saproxy_iter_get_key(zend_object_iterator *iter, zval *key TSRMLS_DC static int saproxy_iter_move_forwards(zend_object_iterator *iter TSRMLS_DC) { - php_com_saproxy_iter *I = (php_com_saproxy_iter*)iter->data; + php_com_saproxy_iter *I = (php_com_saproxy_iter*)Z_PTR(iter->data); if (++I->key >= I->imax) { I->key = -1; @@ -563,16 +553,15 @@ zend_object_iterator *php_com_saproxy_iter_get(zend_class_entry *ce, zval *objec I = ecalloc(1, sizeof(*I)); I->iter.funcs = &saproxy_iter_funcs; - I->iter.data = I; + Z_PTR(I->iter.data) = I; I->proxy = proxy; - I->proxy_obj = object; - Z_ADDREF_P(I->proxy_obj); + ZVAL_COPY(&I->proxy_obj, object); I->indices = safe_emalloc(proxy->dimensions + 1, sizeof(LONG), 0); for (i = 0; i < proxy->dimensions; i++) { - convert_to_long(proxy->indices[i]); - I->indices[i] = Z_LVAL_P(proxy->indices[i]); + convert_to_long(&proxy->indices[i]); + I->indices[i] = Z_LVAL(proxy->indices[i]); } SafeArrayGetLBound(V_ARRAY(&proxy->obj->v), proxy->dimensions, &I->imin); diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index 4ec448e2e3..46a3cbd5a1 100644..100755 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -162,8 +162,9 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa UINT NameCount; BSTR bstr_ids; zend_constant c; - zval exists, results, value; + zval *exists, results, value; char *const_name; + int len; if (TL == NULL) { return FAILURE; @@ -184,22 +185,23 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa continue; } - const_name = php_com_olestring_to_string(bstr_ids, &c.name_len, codepage TSRMLS_CC); - c.name = zend_strndup(const_name, c.name_len); + const_name = php_com_olestring_to_string(bstr_ids, &len, codepage TSRMLS_CC); + c.name = STR_INIT(const_name, len, 1); + // TODO: avoid reallocation??? efree(const_name); if(c.name == NULL) { ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } - c.name_len++; /* include NUL */ +//??? c.name_len++; /* include NUL */ SysFreeString(bstr_ids); /* sanity check for the case where the constant is already defined */ - if (zend_get_constant(c.name, c.name_len - 1, &exists TSRMLS_CC)) { - if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, &exists TSRMLS_CC)) { + if ((exists = zend_get_constant(c.name TSRMLS_CC)) != NULL) { + if (COMG(autoreg_verbose) && !compare_function(&results, &c.value, exists TSRMLS_CC)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type library constant %s is already defined", c.name); } - free(c.name); + STR_RELEASE(c.name); ITypeInfo_ReleaseVarDesc(TypeInfo, pVarDesc); continue; } @@ -208,8 +210,7 @@ PHP_COM_DOTNET_API int php_com_import_typelib(ITypeLib *TL, int mode, int codepa php_com_zval_from_variant(&value, pVarDesc->lpvarValue, codepage TSRMLS_CC); if (Z_TYPE(value) == IS_LONG) { c.flags = mode; - c.value.type = IS_LONG; - c.value.value.lval = Z_LVAL(value); + ZVAL_LONG(&c.value, Z_LVAL(value)); c.module_number = 0; zend_register_constant(&c TSRMLS_CC); } @@ -231,19 +232,17 @@ void php_com_typelibrary_dtor(void *pDest) PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string, int codepage, int *cached TSRMLS_DC) { - ITypeLib **TLp; ITypeLib *TL; char *name_dup; int l; l = strlen(search_string); - if (zend_ts_hash_find(&php_com_typelibraries, search_string, l+1, - (void**)&TLp) == SUCCESS) { + if ((TL = zend_ts_hash_str_find_ptr(&php_com_typelibraries, search_string, l)) != NULL) { *cached = 1; /* add a reference for the caller */ - ITypeLib_AddRef(*TLp); - return *TLp; + ITypeLib_AddRef(TL); + return TL; } *cached = 0; @@ -252,8 +251,8 @@ PHP_COM_DOTNET_API ITypeLib *php_com_load_typelib_via_cache(char *search_string, efree(name_dup); if (TL) { - if (SUCCESS == zend_ts_hash_update(&php_com_typelibraries, - search_string, l+1, (void*)&TL, sizeof(ITypeLib*), NULL)) { + if (NULL != zend_ts_hash_str_update_ptr(&php_com_typelibraries, + search_string, l, TL)) { /* add a reference for the hash table */ ITypeLib_AddRef(TL); } @@ -472,7 +471,7 @@ int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int pri /* So we've got the dispatch interface; lets list the event methods */ for (i = 0; i < attr->cFuncs; i++) { - zval *tmp; + zval tmp; DISPID lastid = 0; /* for props */ int isprop; @@ -582,9 +581,10 @@ int php_com_process_typeinfo(ITypeInfo *typeinfo, HashTable *id_to_name, int pri if (id_to_name) { zend_str_tolower(ansiname, ansinamelen); - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, ansiname, ansinamelen, 0); - zend_hash_index_update(id_to_name, func->memid, (void*)&tmp, sizeof(zval *), NULL); + ZVAL_STRINGL(&tmp, ansiname, ansinamelen); + zend_hash_index_update(id_to_name, func->memid, &tmp); + // TODO: avoid reallocation??? + efree(ansiname); } } ITypeInfo_ReleaseFuncDesc(typeinfo, func); diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 3cc057127a..f7dbdd5efa 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -38,18 +38,17 @@ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC) SAFEARRAYBOUND bound; HashPosition pos; int keytype; - char *strindex; - int strindexlen; + zend_string *strindex; long intindex = -1; long max_index = 0; VARIANT *va; - zval **item; + zval *item; /* find the largest array index, and assert that all keys are integers */ zend_hash_internal_pointer_reset_ex(HASH_OF(z), &pos); for (;; zend_hash_move_forward_ex(HASH_OF(z), &pos)) { - keytype = zend_hash_get_current_key_ex(HASH_OF(z), &strindex, &strindexlen, &intindex, 0, &pos); + keytype = zend_hash_get_current_key_ex(HASH_OF(z), &strindex, &intindex, 0, &pos); if (HASH_KEY_IS_STRING == keytype) { goto bogus; @@ -73,11 +72,11 @@ static void safe_array_from_zval(VARIANT *v, zval *z, int codepage TSRMLS_DC) /* now fill it in */ zend_hash_internal_pointer_reset_ex(HASH_OF(z), &pos); for (;; zend_hash_move_forward_ex(HASH_OF(z), &pos)) { - if (FAILURE == zend_hash_get_current_data_ex(HASH_OF(z), (void**)&item, &pos)) { + if (NULL == (item = zend_hash_get_current_data_ex(HASH_OF(z), &pos))) { break; } - zend_hash_get_current_key_ex(HASH_OF(z), &strindex, &strindexlen, &intindex, 0, &pos); - php_com_variant_from_zval(&va[intindex], *item, codepage TSRMLS_CC); + zend_hash_get_current_key_ex(HASH_OF(z), &strindex, &intindex, 0, &pos); + php_com_variant_from_zval(&va[intindex], item, codepage TSRMLS_CC); } /* Unlock it and stuff it into our variant */ @@ -109,9 +108,14 @@ PHP_COM_DOTNET_API void php_com_variant_from_zval(VARIANT *v, zval *z, int codep V_VT(v) = VT_NULL; break; - case IS_BOOL: + case IS_FALSE: V_VT(v) = VT_BOOL; - V_BOOL(v) = Z_BVAL_P(z) ? VARIANT_TRUE : VARIANT_FALSE; + V_BOOL(v) = VARIANT_FALSE; + break; + + case IS_TRUE: + V_VT(v) = VT_BOOL; + V_BOOL(v) = VARIANT_TRUE; break; case IS_OBJECT: @@ -218,9 +222,12 @@ PHP_COM_DOTNET_API int php_com_zval_from_variant(zval *z, VARIANT *v, int codepa case VT_BSTR: olestring = V_BSTR(v); if (olestring) { - Z_TYPE_P(z) = IS_STRING; - Z_STRVAL_P(z) = php_com_olestring_to_string(olestring, - &Z_STRLEN_P(z), codepage TSRMLS_CC); + int len; + char *str = php_com_olestring_to_string(olestring, + &len, codepage TSRMLS_CC); + ZVAL_STRINGL(z, str, len); + // TODO: avoid reallocation??? + efree(str); olestring = NULL; } break; diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index 54b6fb9ae7..a55c767423 100644..100755 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -39,7 +39,7 @@ typedef struct { /* now the PHP stuff */ DWORD engine_thread; /* for sanity checking */ - zval *object; /* the object exported */ + zval object; /* the object exported */ LONG refcount; /* COM reference count */ HashTable *dispid_to_name; /* keep track of dispid -> name mappings */ @@ -47,14 +47,14 @@ typedef struct { GUID sinkid; /* iid that we "implement" for event sinking */ - int id; + zend_resource *res; } php_dispatchex; static int le_dispatch; static void disp_destructor(php_dispatchex *disp TSRMLS_DC); -static void dispatch_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) +static void dispatch_dtor(zend_resource *rsrc TSRMLS_DC) { php_dispatchex *disp = (php_dispatchex *)rsrc->ptr; disp_destructor(disp TSRMLS_CC); @@ -90,9 +90,9 @@ static inline void trace(char *fmt, ...) php_dispatchex *disp = (php_dispatchex*)This; \ TSRMLS_FETCH(); \ if (COMG(rshutdown_started)) { \ - trace(" PHP Object:%p (name:unknown) %s\n", disp->object, methname); \ + trace(" PHP Object:%p (name:unknown) %s\n", Z_OBJ(disp->object), methname); \ } else { \ - trace(" PHP Object:%p (name:%s) %s\n", disp->object, Z_OBJCE_P(disp->object)->name, methname); \ + trace(" PHP Object:%p (name:%s) %s\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val, methname); \ } \ if (GetCurrentThreadId() != disp->engine_thread) { \ return RPC_E_WRONG_THREAD; \ @@ -134,8 +134,8 @@ static ULONG STDMETHODCALLTYPE disp_release(IDispatchEx *This) trace("-- refcount now %d\n", ret); if (ret == 0) { /* destroy it */ - if (disp->id) - zend_list_delete(disp->id); + if (disp->res) + zend_list_delete(disp->res); } return ret; } @@ -177,16 +177,16 @@ static HRESULT STDMETHODCALLTYPE disp_getidsofnames( for (i = 0; i < cNames; i++) { char *name; unsigned int namelen; - zval **tmp; + zval *tmp; name = php_com_olestring_to_string(rgszNames[i], &namelen, COMG(code_page) TSRMLS_CC); /* Lookup the name in the hash */ - if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == FAILURE) { + if ((tmp = zend_hash_str_find(disp->name_to_dispid, name, namelen)) == NULL) { ret = DISP_E_UNKNOWNNAME; rgDispId[i] = 0; } else { - rgDispId[i] = Z_LVAL_PP(tmp); + rgDispId[i] = Z_LVAL_P(tmp); } efree(name); @@ -221,7 +221,7 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( HRESULT ret = DISP_E_UNKNOWNNAME; char *name; unsigned int namelen; - zval **tmp; + zval *tmp; FETCH_DISP("GetDispID"); name = php_com_olestring_to_string(bstrName, &namelen, COMG(code_page) TSRMLS_CC); @@ -229,9 +229,9 @@ static HRESULT STDMETHODCALLTYPE disp_getdispid( trace("Looking for %s, namelen=%d in %p\n", name, namelen, disp->name_to_dispid); /* Lookup the name in the hash */ - if (zend_hash_find(disp->name_to_dispid, name, namelen+1, (void**)&tmp) == SUCCESS) { + if ((tmp = zend_hash_str_find(disp->name_to_dispid, name, namelen)) != NULL) { trace("found it\n"); - *pid = Z_LVAL_PP(tmp); + *pid = Z_LVAL_P(tmp); ret = S_OK; } @@ -250,34 +250,30 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( /* [out] */ EXCEPINFO *pei, /* [unique][in] */ IServiceProvider *pspCaller) { - zval **name; + zval *name; UINT i; - zval *retval = NULL; - zval ***params = NULL; + zval rv, *retval = NULL; + zval *params = NULL; HRESULT ret = DISP_E_MEMBERNOTFOUND; FETCH_DISP("InvokeEx"); - if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) { + if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { /* TODO: add support for overloaded objects */ - trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_PP(name), Z_STRLEN_PP(name), wFlags, pdp->cArgs); + trace("-- Invoke: %d %20s [%d] flags=%08x args=%d\n", id, Z_STRVAL_P(name), Z_STRLEN_P(name), wFlags, pdp->cArgs); /* convert args into zvals. * Args are in reverse order */ if (pdp->cArgs) { - params = (zval ***)safe_emalloc(sizeof(zval **), pdp->cArgs, 0); + params = (zval *)safe_emalloc(sizeof(zval), pdp->cArgs, 0); for (i = 0; i < pdp->cArgs; i++) { VARIANT *arg; - zval *zarg; arg = &pdp->rgvarg[ pdp->cArgs - 1 - i]; trace("alloc zval for arg %d VT=%08x\n", i, V_VT(arg)); - ALLOC_INIT_ZVAL(zarg); - php_com_wrap_variant(zarg, arg, COMG(code_page) TSRMLS_CC); - params[i] = (zval**)emalloc(sizeof(zval**)); - *params[i] = zarg; + php_com_wrap_variant(¶ms[i], arg, COMG(code_page) TSRMLS_CC); } } @@ -287,19 +283,20 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( * and expose it as a COM exception */ if (wFlags & DISPATCH_PROPERTYGET) { - retval = zend_read_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, 1 TSRMLS_CC); + retval = zend_read_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name)+1, 1 TSRMLS_CC); } else if (wFlags & DISPATCH_PROPERTYPUT) { - zend_update_property(Z_OBJCE_P(disp->object), disp->object, Z_STRVAL_PP(name), Z_STRLEN_PP(name)+1, *params[0] TSRMLS_CC); + zend_update_property(Z_OBJCE(disp->object), &disp->object, Z_STRVAL_P(name), Z_STRLEN_P(name), ¶ms[0] TSRMLS_CC); } else if (wFlags & DISPATCH_METHOD) { zend_try { - if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, *name, - &retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) { + retval = &rv; + if (SUCCESS == call_user_function_ex(EG(function_table), &disp->object, name, + retval, pdp->cArgs, params, 1, NULL TSRMLS_CC)) { ret = S_OK; trace("function called ok\n"); /* Copy any modified values to callers copy of variant*/ for (i = 0; i < pdp->cArgs; i++) { - php_com_dotnet_object *obj = CDNO_FETCH(*params[i]); + php_com_dotnet_object *obj = CDNO_FETCH(¶ms[i]); VARIANT *srcvar = &obj->v; VARIANT *dstvar = &pdp->rgvarg[ pdp->cArgs - 1 - i]; if ((V_VT(dstvar) & VT_BYREF) && obj->modified ) { @@ -322,8 +319,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( /* release arguments */ if (params) { for (i = 0; i < pdp->cArgs; i++) { - zval_ptr_dtor(params[i]); - efree(params[i]); + zval_ptr_dtor(¶ms[i]); } efree(params); } @@ -334,7 +330,7 @@ static HRESULT STDMETHODCALLTYPE disp_invokeex( VariantInit(pvarRes); php_com_variant_from_zval(pvarRes, retval, COMG(code_page) TSRMLS_CC); } - zval_ptr_dtor(&retval); + zval_ptr_dtor(retval); } else if (pvarRes) { VariantInit(pvarRes); } @@ -388,7 +384,7 @@ static HRESULT STDMETHODCALLTYPE disp_getmembername( zval *name; FETCH_DISP("GetMemberName"); - if (SUCCESS == zend_hash_index_find(disp->dispid_to_name, id, (void**)&name)) { + if (NULL != (name = zend_hash_index_find(disp->dispid_to_name, id))) { OLECHAR *olestr = php_com_string_to_olestring(Z_STRVAL_P(name), Z_STRLEN_P(name), COMG(code_page) TSRMLS_CC); *pbstrName = SysAllocString(olestr); efree(olestr); @@ -451,9 +447,8 @@ static struct IDispatchExVtbl php_dispatch_vtbl = { static void generate_dispids(php_dispatchex *disp TSRMLS_DC) { HashPosition pos; - char *name = NULL; - zval *tmp; - int namelen; + zend_string *name = NULL; + zval *tmp, tmp2; int keytype; ulong pid; @@ -465,65 +460,71 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC) } /* properties */ - if (Z_OBJPROP_P(disp->object)) { - zend_hash_internal_pointer_reset_ex(Z_OBJPROP_P(disp->object), &pos); + if (Z_OBJPROP(disp->object)) { + zend_hash_internal_pointer_reset_ex(Z_OBJPROP(disp->object), &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(Z_OBJPROP_P(disp->object), &name, - &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(Z_OBJPROP(disp->object), &name, + &pid, 0, &pos))) { char namebuf[32]; if (keytype == HASH_KEY_IS_LONG) { snprintf(namebuf, sizeof(namebuf), "%d", pid); - name = namebuf; - namelen = strlen(namebuf)+1; + name = STR_INIT(namebuf, strlen(namebuf), 0); + } else { + STR_ADDREF(name); } - zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos); + zend_hash_move_forward_ex(Z_OBJPROP(disp->object), &pos); /* Find the existing id */ - if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS) + if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { + STR_RELEASE(name); continue; + } /* add the mappings */ - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, name, namelen-1, 1); + ZVAL_STR(&tmp2, STR_COPY(name)); pid = zend_hash_next_free_element(disp->dispid_to_name); - zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL); + zend_hash_index_update(disp->dispid_to_name, pid, &tmp2); + + ZVAL_LONG(&tmp2, pid); + zend_hash_update(disp->name_to_dispid, name, &tmp2); - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, pid); - zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL); + STR_RELEASE(name); } } /* functions */ - if (Z_OBJCE_P(disp->object)) { - zend_hash_internal_pointer_reset_ex(&Z_OBJCE_P(disp->object)->function_table, &pos); + if (Z_OBJCE(disp->object)) { + zend_hash_internal_pointer_reset_ex(&Z_OBJCE(disp->object)->function_table, &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(&Z_OBJCE_P(disp->object)->function_table, - &name, &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(&Z_OBJCE(disp->object)->function_table, + &name, &pid, 0, &pos))) { char namebuf[32]; if (keytype == HASH_KEY_IS_LONG) { snprintf(namebuf, sizeof(namebuf), "%d", pid); - name = namebuf; - namelen = strlen(namebuf) + 1; + name = STR_INIT(namebuf, strlen(namebuf), 0); + } else { + STR_ADDREF(name); } - zend_hash_move_forward_ex(Z_OBJPROP_P(disp->object), &pos); + zend_hash_move_forward_ex(&Z_OBJCE(disp->object)->function_table, &pos); /* Find the existing id */ - if (zend_hash_find(disp->name_to_dispid, name, namelen, (void**)&tmp) == SUCCESS) + if ((tmp = zend_hash_find(disp->name_to_dispid, name)) != NULL) { + STR_RELEASE(name); continue; + } /* add the mappings */ - MAKE_STD_ZVAL(tmp); - ZVAL_STRINGL(tmp, name, namelen-1, 1); + ZVAL_STR(&tmp2, STR_COPY(name)); pid = zend_hash_next_free_element(disp->dispid_to_name); - zend_hash_index_update(disp->dispid_to_name, pid, (void*)&tmp, sizeof(zval *), NULL); + zend_hash_index_update(disp->dispid_to_name, pid, &tmp2); + + ZVAL_LONG(&tmp2, pid); + zend_hash_update(disp->name_to_dispid, name, &tmp2); - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, pid); - zend_hash_update(disp->name_to_dispid, name, namelen, (void*)&tmp, sizeof(zval *), NULL); + STR_RELEASE(name); } } } @@ -531,6 +532,7 @@ static void generate_dispids(php_dispatchex *disp TSRMLS_DC) static php_dispatchex *disp_constructor(zval *object TSRMLS_DC) { php_dispatchex *disp = (php_dispatchex*)CoTaskMemAlloc(sizeof(php_dispatchex)); + zval *tmp; trace("constructing a COM wrapper for PHP object %p (%s)\n", object, Z_OBJCE_P(object)->name); @@ -544,11 +546,14 @@ static php_dispatchex *disp_constructor(zval *object TSRMLS_DC) disp->refcount = 1; - if (object) - Z_ADDREF_P(object); - disp->object = object; + if (object) { + ZVAL_COPY(&disp->object, object); + } else { + ZVAL_UNDEF(&disp->object); + } - disp->id = zend_list_insert(disp, le_dispatch TSRMLS_CC); + tmp = zend_list_insert(disp, le_dispatch TSRMLS_CC); + disp->res = Z_RES_P(tmp); return disp; } @@ -557,12 +562,12 @@ static void disp_destructor(php_dispatchex *disp TSRMLS_DC) { /* Object store not available during request shutdown */ if (COMG(rshutdown_started)) { - trace("destroying COM wrapper for PHP object %p (name:unknown)\n", disp->object); + trace("destroying COM wrapper for PHP object %p (name:unknown)\n", Z_OBJ(disp->object)); } else { - trace("destroying COM wrapper for PHP object %p (name:%s)\n", disp->object, Z_OBJCE_P(disp->object)->name); + trace("destroying COM wrapper for PHP object %p (name:%s)\n", Z_OBJ(disp->object), Z_OBJCE(disp->object)->name->val); } - disp->id = 0; + disp->res = NULL; if (disp->refcount > 0) CoDisconnectObject((IUnknown*)disp, 0); @@ -572,8 +577,7 @@ static void disp_destructor(php_dispatchex *disp TSRMLS_DC) FREE_HASHTABLE(disp->dispid_to_name); FREE_HASHTABLE(disp->name_to_dispid); - if (disp->object) - zval_ptr_dtor(&disp->object); + zval_ptr_dtor(&disp->object); CoTaskMemFree(disp); } @@ -583,9 +587,8 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si { php_dispatchex *disp = disp_constructor(val TSRMLS_CC); HashPosition pos; - char *name = NULL; - zval *tmp, **ntmp; - int namelen; + zend_string *name = NULL; + zval tmp, *ntmp; int keytype; ulong pid; @@ -599,16 +602,14 @@ PHP_COM_DOTNET_API IDispatch *php_com_wrapper_export_as_sink(zval *val, GUID *si zend_hash_internal_pointer_reset_ex(id_to_name, &pos); while (HASH_KEY_NON_EXISTENT != (keytype = - zend_hash_get_current_key_ex(id_to_name, &name, &namelen, &pid, 0, &pos))) { + zend_hash_get_current_key_ex(id_to_name, &name, &pid, 0, &pos))) { if (keytype == HASH_KEY_IS_LONG) { - zend_hash_get_current_data_ex(id_to_name, (void**)&ntmp, &pos); + ntmp = zend_hash_get_current_data_ex(id_to_name, &pos); - MAKE_STD_ZVAL(tmp); - ZVAL_LONG(tmp, pid); - zend_hash_update(disp->name_to_dispid, Z_STRVAL_PP(ntmp), - Z_STRLEN_PP(ntmp)+1, (void*)&tmp, sizeof(zval *), NULL); + ZVAL_LONG(&tmp, pid); + zend_hash_update(disp->name_to_dispid, Z_STR_P(ntmp), &tmp); } zend_hash_move_forward_ex(id_to_name, &pos); diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index 5dabdfb213..d093e3c37b 100644..100755 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -29,6 +29,8 @@ #include <dispex.h> #include "win32/winutil.h" +#include "zend_ts_hash.h" + typedef struct _php_com_dotnet_object { zend_object zo; @@ -54,18 +56,18 @@ typedef struct _php_com_dotnet_object { static inline int php_com_is_valid_object(zval *zv TSRMLS_DC) { zend_class_entry *ce = Z_OBJCE_P(zv); - return strcmp("com", ce->name) == 0 || - strcmp("dotnet", ce->name) == 0 || - strcmp("variant", ce->name) == 0; + return strcmp("com", ce->name->val) == 0 || + strcmp("dotnet", ce->name->val) == 0 || + strcmp("variant", ce->name->val) == 0; } -#define CDNO_FETCH(zv) (php_com_dotnet_object*)zend_object_store_get_object(zv TSRMLS_CC) +#define CDNO_FETCH(zv) (php_com_dotnet_object*)Z_OBJ_P(zv) #define CDNO_FETCH_VERIFY(obj, zv) do { \ if (!php_com_is_valid_object(zv TSRMLS_CC)) { \ php_com_throw_exception(E_UNEXPECTED, "expected a variant object" TSRMLS_CC); \ return; \ } \ - obj = (php_com_dotnet_object*)zend_object_store_get_object(zv TSRMLS_CC); \ + obj = (php_com_dotnet_object*)Z_OBJ_P(zv); \ } while(0) /* com_extension.c */ @@ -73,9 +75,9 @@ TsHashTable php_com_typelibraries; zend_class_entry *php_com_variant_class_entry, *php_com_exception_class_entry, *php_com_saproxy_class_entry; /* com_handlers.c */ -zend_object_value php_com_object_new(zend_class_entry *ce TSRMLS_DC); -void php_com_object_clone(void *object, void **clone_ptr TSRMLS_DC); -void php_com_object_free_storage(void *object TSRMLS_DC); +zend_object* php_com_object_new(zend_class_entry *ce TSRMLS_DC); +zend_object* php_com_object_clone(zval *object TSRMLS_DC); +void php_com_object_free_storage(zend_object *object TSRMLS_DC); zend_object_handlers php_com_object_handlers; void php_com_object_enable_event_sink(php_com_dotnet_object *obj, int enable TSRMLS_DC); @@ -104,11 +106,11 @@ HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, HRESULT php_com_get_id_of_name(php_com_dotnet_object *obj, char *name, int namelen, DISPID *dispid TSRMLS_DC); int php_com_do_invoke_by_id(php_com_dotnet_object *obj, DISPID dispid, - WORD flags, VARIANT *v, int nargs, zval **args, int silent, int allow_noarg TSRMLS_DC); + WORD flags, VARIANT *v, int nargs, zval *args, int silent, int allow_noarg TSRMLS_DC); int php_com_do_invoke(php_com_dotnet_object *obj, char *name, int namelen, - WORD flags, VARIANT *v, int nargs, zval **args, int allow_noarg TSRMLS_DC); + WORD flags, VARIANT *v, int nargs, zval *args, int allow_noarg TSRMLS_DC); int php_com_do_invoke_byref(php_com_dotnet_object *obj, char *name, int namelen, - WORD flags, VARIANT *v, int nargs, zval ***args TSRMLS_DC); + WORD flags, VARIANT *v, int nargs, zval *args TSRMLS_DC); /* com_wrapper.c */ int php_com_wrapper_minit(INIT_FUNC_ARGS); |