]> granicus.if.org Git - php/commitdiff
Implemented ext/com_dotnet support for phpng
authorDmitry Stogov <dmitry@zend.com>
Mon, 11 Aug 2014 14:37:26 +0000 (18:37 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 11 Aug 2014 14:37:26 +0000 (18:37 +0400)
13 files changed:
Zend/zend_ts_hash.c
Zend/zend_ts_hash.h
ext/com_dotnet/com_com.c [changed mode: 0644->0755]
ext/com_dotnet/com_dotnet.c [changed mode: 0644->0755]
ext/com_dotnet/com_handlers.c [changed mode: 0644->0755]
ext/com_dotnet/com_iterator.c [changed mode: 0644->0755]
ext/com_dotnet/com_misc.c [changed mode: 0644->0755]
ext/com_dotnet/com_persist.c [changed mode: 0644->0755]
ext/com_dotnet/com_saproxy.c [changed mode: 0644->0755]
ext/com_dotnet/com_typeinfo.c [changed mode: 0644->0755]
ext/com_dotnet/com_variant.c
ext/com_dotnet/com_wrapper.c [changed mode: 0644->0755]
ext/com_dotnet/php_com_dotnet_internal.h [changed mode: 0644->0755]

index 92cd62128e2842694aace51ad758036d746eef8a..f6523574aeb44b24a5433583a73b13c3ccf257f2 100644 (file)
@@ -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
index 4b0a507368cdb6a8fc35e3f885be91b4d906880e..fcf8c3cda1e1cb5eb31bfc3258721d92a3416a06 100644 (file)
@@ -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)                                                              \
old mode 100644 (file)
new mode 100755 (executable)
index 500cabd..6d3b158
@@ -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);
old mode 100644 (file)
new mode 100755 (executable)
index 0aa1a2a..c582309
@@ -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;
        }
 }
old mode 100644 (file)
new mode 100755 (executable)
index c889c9a..0d83a86
 #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, namelen, &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(namelen, 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;
 }
old mode 100644 (file)
new mode 100755 (executable)
index d6f22ef..7da10f1
@@ -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;
old mode 100644 (file)
new mode 100755 (executable)
index b65a6be..5cd6808
@@ -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
old mode 100644 (file)
new mode 100755 (executable)
index aaddf9c..66e3dec
@@ -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;
old mode 100644 (file)
new mode 100755 (executable)
index 0d557e6..9b3716f
@@ -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);
old mode 100644 (file)
new mode 100755 (executable)
index 4ec448e..46a3cbd
@@ -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);
index 3cc057127a962463dee4693a8a81dd2f9d9b136c..f7dbdd5efa630fcaad4cead4ad237f9307fa2ace 100644 (file)
@@ -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;
old mode 100644 (file)
new mode 100755 (executable)
index 54b6fb9..a55c767
@@ -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(&params[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), &params[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(&params[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(&params[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);
old mode 100644 (file)
new mode 100755 (executable)
index 5dabdfb..d093e3c
@@ -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);