]> granicus.if.org Git - php/commitdiff
Merged zend_array and HashTable into the single data structure.
authorDmitry Stogov <dmitry@zend.com>
Fri, 13 Feb 2015 19:20:39 +0000 (22:20 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 13 Feb 2015 19:20:39 +0000 (22:20 +0300)
Now each HashTable is also zend_array, so it's refcounted and may be a subject for Copy on Write
zend_array_dup() was changed to allocate and return HashTable, instead of taking preallocated HashTable as argument.

40 files changed:
Zend/zend.c
Zend/zend_builtin_functions.c
Zend/zend_closures.c
Zend/zend_compile.c
Zend/zend_execute.c
Zend/zend_execute_API.c
Zend/zend_gc.c
Zend/zend_hash.c
Zend/zend_hash.h
Zend/zend_object_handlers.c
Zend/zend_operators.c
Zend/zend_types.h
Zend/zend_variables.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/dom/php_dom.c
ext/gmp/gmp.c
ext/opcache/ZendAccelerator.c
ext/opcache/zend_accelerator_util_funcs.c
ext/readline/readline_cli.c
ext/session/session.c
ext/soap/soap.c
ext/spl/spl_array.c
ext/spl/spl_directory.c
ext/spl/spl_observer.c
ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/browscap.c
ext/standard/http_fopen_wrapper.c
ext/standard/info.c
ext/wddx/wddx.c
main/main.c
main/php_variables.c
sapi/cli/php_cli.c
sapi/fpm/fpm/fpm_php.c
sapi/phpdbg/phpdbg_info.c
sapi/phpdbg/phpdbg_prompt.c
sapi/phpdbg/phpdbg_wait.c
sapi/phpdbg/phpdbg_watch.c
sapi/phpdbg/phpdbg_webdata_transfer.c

index 1bd70ab292f5d81d888faaee172279d2171d2a59..d5618b490d91f7c8d7693ee1e52fe073dece73b6 100644 (file)
@@ -550,8 +550,9 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
        zval globals;
 
        ZVAL_ARR(&globals, &EG(symbol_table));
+       Z_TYPE_INFO_P(&globals) = IS_ARRAY | (IS_TYPE_SYMBOLTABLE << Z_TYPE_FLAGS_SHIFT);
        ZVAL_NEW_REF(&globals, &globals);
-       zend_hash_update(&EG(symbol_table).ht, name, &globals);
+       zend_hash_update(&EG(symbol_table), name, &globals);
        return 0;
 }
 /* }}} */
@@ -1129,8 +1130,7 @@ static void zend_error_va_list(int type, const char *format, va_list args)
                        if (!symbol_table) {
                                ZVAL_NULL(&params[4]);
                        } else {
-                               ZVAL_NEW_ARR(&params[4]);
-                               zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht);
+                               ZVAL_ARR(&params[4], zend_array_dup(symbol_table));
                        }
 
                        ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler));
index 582296a8df02d01a6f469d1ba42d5c936445f4f9..da90e4c98d94b477d901f02bde661bcf5208c7ca 100644 (file)
@@ -1140,8 +1140,7 @@ ZEND_FUNCTION(get_object_vars)
 
        if (!zobj->ce->default_properties_count && properties == zobj->properties) {
                /* fast copy */
-               ZVAL_NEW_ARR(return_value);
-               zend_array_dup(Z_ARRVAL_P(return_value), properties);
+               ZVAL_ARR(return_value, zend_array_dup(properties));
        } else {
                array_init_size(return_value, zend_hash_num_elements(properties));
 
@@ -1883,8 +1882,7 @@ ZEND_FUNCTION(get_defined_vars)
 {
        zend_array *symbol_table = zend_rebuild_symbol_table();
 
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), &symbol_table->ht);
+       ZVAL_ARR(return_value, zend_array_dup(symbol_table));
 }
 /* }}} */
 
index 3478ee6816d33b44ba87cb263fed58ea47a24e91..fb37bf2705a480ed4c0e4adddedcfb9c34173763 100644 (file)
@@ -349,8 +349,7 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
        if (closure->debug_info->u.v.nApplyCount == 0) {
                if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
                        HashTable *static_variables = closure->func.op_array.static_variables;
-                       ZVAL_NEW_ARR(&val);
-                       zend_array_dup(Z_ARRVAL(val), static_variables);
+                       ZVAL_ARR(&val, zend_array_dup(static_variables));
                        zend_hash_str_update(closure->debug_info, "static", sizeof("static")-1, &val);
                }
 
index ba5046f343687500be920da5f8ab95c54a2d1250..36055258f6f1695468a5f448b1c16130cc118437 100644 (file)
@@ -865,10 +865,7 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */
 
                (*op_array->refcount)++;
                if (op_array->static_variables) {
-                       HashTable *static_variables = op_array->static_variables;
-
-                       ALLOC_HASHTABLE(op_array->static_variables);
-                       zend_array_dup(op_array->static_variables, static_variables);
+                       op_array->static_variables = zend_array_dup(op_array->static_variables);
                }
                op_array->run_time_cache = NULL;
        } else if (function->type == ZEND_INTERNAL_FUNCTION) {
index 73c1d4d17cdc8d37d555d16b013d3434a83bb9a8..539b1e4dd7cefb4eb567928bbf41650131b07dd2 100644 (file)
@@ -1162,7 +1162,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
 
        if (EXPECTED(fetch_type == ZEND_FETCH_GLOBAL_LOCK) ||
            EXPECTED(fetch_type == ZEND_FETCH_GLOBAL)) {
-               ht = &EG(symbol_table).ht;
+               ht = &EG(symbol_table);
        } else if (EXPECTED(fetch_type == ZEND_FETCH_STATIC)) {
                ZEND_ASSERT(EX(func)->op_array.static_variables != NULL);
                ht = EX(func)->op_array.static_variables;
@@ -1171,7 +1171,7 @@ static zend_always_inline HashTable *zend_get_target_symbol_table(zend_execute_d
                if (!EX(symbol_table)) {
                        zend_rebuild_symbol_table();
                }
-               ht = &EX(symbol_table)->ht;
+               ht = EX(symbol_table);
        }
        return ht;
 }
@@ -1687,12 +1687,12 @@ ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_val
 ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table) /* {{{ */
 {
        if (EG(symtable_cache_ptr) >= EG(symtable_cache_limit)) {
-               zend_array_destroy(&symbol_table->ht);
+               zend_array_destroy(symbol_table);
                efree_size(symbol_table, sizeof(zend_array));
        } else {
                /* clean before putting into the cache, since clean
                   could call dtors, which could use cached hash */
-               zend_symtable_clean(&symbol_table->ht);
+               zend_symtable_clean(symbol_table);
                *(++EG(symtable_cache_ptr)) = symbol_table;
        }
 }
index 0554e31a5e02541cffc96bf57e2c3edc44b884ef..0d722e5820d34ade19441ffd77f08e9046f778e8 100644 (file)
@@ -152,9 +152,7 @@ void init_executor(void) /* {{{ */
 
        zend_vm_stack_init();
 
-       zend_hash_init(&EG(symbol_table).ht, 64, NULL, ZVAL_PTR_DTOR, 0);
-       GC_REFCOUNT(&EG(symbol_table)) = 1;
-       GC_TYPE_INFO(&EG(symbol_table)) = IS_ARRAY;
+       zend_hash_init(&EG(symbol_table), 64, NULL, ZVAL_PTR_DTOR, 0);
        EG(valid_symbol_table) = 1;
 
        zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_activator);
@@ -218,14 +216,14 @@ static void zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
 void shutdown_destructors(void) /* {{{ */
 {
        if (CG(unclean_shutdown)) {
-               EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
+               EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
        }
        zend_try {
                uint32_t symbols;
                do {
-                       symbols = zend_hash_num_elements(&EG(symbol_table).ht);
-                       zend_hash_reverse_apply(&EG(symbol_table).ht, (apply_func_t) zval_call_destructor);
-               } while (symbols != zend_hash_num_elements(&EG(symbol_table).ht));
+                       symbols = zend_hash_num_elements(&EG(symbol_table));
+                       zend_hash_reverse_apply(&EG(symbol_table), (apply_func_t) zval_call_destructor);
+               } while (symbols != zend_hash_num_elements(&EG(symbol_table)));
                zend_objects_store_call_destructors(&EG(objects_store));
        } zend_catch {
                /* if we couldn't destruct cleanly, mark all objects as destructed anyway */
@@ -259,9 +257,9 @@ void shutdown_executor(void) /* {{{ */
                zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator);
 
                if (CG(unclean_shutdown)) {
-                       EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
+                       EG(symbol_table).pDestructor = zend_unclean_zval_ptr_dtor;
                }
-               zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
+               zend_hash_graceful_reverse_destroy(&EG(symbol_table));
        } zend_end_try();
        EG(valid_symbol_table) = 0;
 
@@ -349,7 +347,7 @@ void shutdown_executor(void) /* {{{ */
                }
 
                while (EG(symtable_cache_ptr)>=EG(symtable_cache)) {
-                       zend_hash_destroy(&(*EG(symtable_cache_ptr))->ht);
+                       zend_hash_destroy(*EG(symtable_cache_ptr));
                        FREE_HASHTABLE(*EG(symtable_cache_ptr));
                        EG(symtable_cache_ptr)--;
                }
@@ -1417,7 +1415,7 @@ void zend_verify_abstract_class(zend_class_entry *ce) /* {{{ */
 
 ZEND_API int zend_delete_global_variable(zend_string *name) /* {{{ */
 {
-    return zend_hash_del_ind(&EG(symbol_table).ht, name);
+    return zend_hash_del_ind(&EG(symbol_table), name);
 }
 /* }}} */
 
@@ -1444,17 +1442,14 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */
                symbol_table = ex->symbol_table = *(EG(symtable_cache_ptr)--);
        } else {
                symbol_table = ex->symbol_table = emalloc(sizeof(zend_array));
-               GC_REFCOUNT(symbol_table) = 0;
-               GC_TYPE_INFO(symbol_table) = IS_ARRAY;
-               zend_hash_init(&symbol_table->ht, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
+               zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0);
                /*printf("Cache miss!  Initialized %x\n", EG(active_symbol_table));*/
        }
        for (i = 0; i < ex->func->op_array.last_var; i++) {
                zval zv;
 
                ZVAL_INDIRECT(&zv, ZEND_CALL_VAR_NUM(ex, i));
-               zend_hash_add_new(&symbol_table->ht,
-                       ex->func->op_array.vars[i], &zv);
+               zend_hash_add_new(symbol_table, ex->func->op_array.vars[i], &zv);
        }
        return symbol_table;
 }
@@ -1464,7 +1459,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ *
 {
        int i;
        zend_op_array *op_array = &execute_data->func->op_array;
-       HashTable *ht = &execute_data->symbol_table->ht;
+       HashTable *ht = execute_data->symbol_table;
 
        /* copy real values from symbol table into CV slots and create
           INDIRECT references to CV in symbol table  */
@@ -1492,7 +1487,7 @@ ZEND_API void zend_detach_symbol_table(zend_execute_data *execute_data) /* {{{ *
 {
        int i;
        zend_op_array *op_array = &execute_data->func->op_array;
-       HashTable *ht = &execute_data->symbol_table->ht;
+       HashTable *ht = execute_data->symbol_table;
 
        /* copy real values from CV slots into symbol table */
        for (i = 0; i < op_array->last_var; i++) {
@@ -1531,11 +1526,11 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{
                        if (force) {
                                zend_array *symbol_table = zend_rebuild_symbol_table();
                                if (symbol_table) {
-                                       return zend_hash_update(&symbol_table->ht, name, value) ? SUCCESS : FAILURE;;
+                                       return zend_hash_update(symbol_table, name, value) ? SUCCESS : FAILURE;;
                                }
                        }
                } else {
-                       return (zend_hash_update_ind(&execute_data->symbol_table->ht, name, value) != NULL) ? SUCCESS : FAILURE;
+                       return (zend_hash_update_ind(execute_data->symbol_table, name, value) != NULL) ? SUCCESS : FAILURE;
                }
        }
        return FAILURE;
@@ -1569,11 +1564,11 @@ ZEND_API int zend_set_local_var_str(const char *name, size_t len, zval *value, i
                        if (force) {
                                zend_array *symbol_table = zend_rebuild_symbol_table();
                                if (symbol_table) {
-                                       return zend_hash_str_update(&symbol_table->ht, name, len, value) ? SUCCESS : FAILURE;;
+                                       return zend_hash_str_update(symbol_table, name, len, value) ? SUCCESS : FAILURE;;
                                }
                        }
                } else {
-                       return (zend_hash_str_update_ind(&execute_data->symbol_table->ht, name, len, value) != NULL) ? SUCCESS : FAILURE;
+                       return (zend_hash_str_update_ind(execute_data->symbol_table, name, len, value) != NULL) ? SUCCESS : FAILURE;
                }
        }
        return FAILURE;
index 947ddc84eb9bdb426cd5f70c793d1178892e5eb0..13d3ee7f0194cc0fc2853a4e500213bca966aa5a 100644 (file)
@@ -231,9 +231,7 @@ tail_call:
                        for (i = 0; i < n; i++) {
                                if (Z_REFCOUNTED(table[i])) {
                                        ref = Z_COUNTED(table[i]);
-                                       if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                                               GC_REFCOUNT(ref)++;
-                                       }
+                                       GC_REFCOUNT(ref)++;
                                        if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
                                                if (!props && i == n - 1) {
                                                        goto tail_call;
@@ -250,14 +248,12 @@ tail_call:
                }
        } else if (GC_TYPE(ref) == IS_ARRAY) {
                if ((zend_array*)ref != &EG(symbol_table)) {
-                       ht = &((zend_array*)ref)->ht;
+                       ht = (zend_array*)ref;
                }
        } else if (GC_TYPE(ref) == IS_REFERENCE) {
                if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
                        ref = Z_COUNTED(((zend_reference*)ref)->val);
-                       if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                               GC_REFCOUNT(ref)++;
-                       }
+                       GC_REFCOUNT(ref)++;
                        if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
                                goto tail_call;
                        }
@@ -269,9 +265,7 @@ tail_call:
                p = ht->arData + idx;
                if (!Z_REFCOUNTED(p->val)) continue;
                ref = Z_COUNTED(p->val);
-               if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                       GC_REFCOUNT(ref)++;
-               }
+               GC_REFCOUNT(ref)++;
                if (GC_GET_COLOR(GC_INFO(ref)) != GC_BLACK) {
                        if (idx == ht->nNumUsed-1) {
                                goto tail_call;
@@ -312,9 +306,7 @@ tail_call:
                                for (i = 0; i < n; i++) {
                                        if (Z_REFCOUNTED(table[i])) {
                                                ref = Z_COUNTED(table[i]);
-                                               if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
-                                                       GC_REFCOUNT(ref)--;
-                                               }
+                                               GC_REFCOUNT(ref)--;
                                                if (!props && i == n - 1) {
                                                        goto tail_call;
                                                } else {
@@ -331,7 +323,7 @@ tail_call:
                        if (((zend_array*)ref) == &EG(symbol_table)) {
                                GC_SET_BLACK(GC_INFO(ref));
                        } else {
-                               ht = &((zend_array*)ref)->ht;
+                               ht = (zend_array*)ref;
                        }
                } else if (GC_TYPE(ref) == IS_REFERENCE) {
                        if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
@@ -341,9 +333,7 @@ tail_call:
                                        return;
                                }
                                ref = Z_COUNTED(((zend_reference*)ref)->val);
-                               if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                                       GC_REFCOUNT(ref)--;
-                               }
+                               GC_REFCOUNT(ref)--;
                                goto tail_call;
                        }
                        return;
@@ -358,9 +348,7 @@ tail_call:
                                continue;
                        }
                        ref = Z_COUNTED(p->val);
-                       if (GC_TYPE(ref) != IS_ARRAY || ((zend_array*)ref) != &EG(symbol_table)) {
-                               GC_REFCOUNT(ref)--;
-                       }
+                       GC_REFCOUNT(ref)--;
                        if (idx == ht->nNumUsed-1) {
                                goto tail_call;
                        } else {
@@ -428,7 +416,7 @@ tail_call:
                                if ((zend_array*)ref == &EG(symbol_table)) {
                                        GC_SET_BLACK(GC_INFO(ref));
                                } else {
-                                       ht = &((zend_array*)ref)->ht;
+                                       ht = (zend_array*)ref;
                                }
                        } else if (GC_TYPE(ref) == IS_REFERENCE) {
                                if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
@@ -529,9 +517,7 @@ tail_call:
                                for (i = 0; i < n; i++) {
                                        if (Z_REFCOUNTED(table[i])) {
                                                ref = Z_COUNTED(table[i]);
-                                               if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                                                       GC_REFCOUNT(ref)++;
-                                               }
+                                               GC_REFCOUNT(ref)++;
                                                if (!props && i == n - 1) {
                                                        goto tail_call;
                                                } else {
@@ -548,13 +534,11 @@ tail_call:
                                ht = props;
                        }
                } else if (GC_TYPE(ref) == IS_ARRAY) {
-                       ht = &((zend_array*)ref)->ht;
+                       ht = (zend_array*)ref;
                } else if (GC_TYPE(ref) == IS_REFERENCE) {
                        if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
                                ref = Z_COUNTED(((zend_reference*)ref)->val);
-                               if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                                       GC_REFCOUNT(ref)++;
-                               }
+                               GC_REFCOUNT(ref)++;
                                goto tail_call;
                        }
                        return count;
@@ -571,9 +555,7 @@ tail_call:
                                continue;
                        }
                        ref = Z_COUNTED(p->val);
-                       if (GC_TYPE(ref) != IS_ARRAY || (zend_array*)ref != &EG(symbol_table)) {
-                               GC_REFCOUNT(ref)++;
-                       }
+                       GC_REFCOUNT(ref)++;
                        if (idx == ht->nNumUsed-1) {
                                goto tail_call;
                        } else {
@@ -681,7 +663,7 @@ tail_call:
                                ht = props;
                        }
                } else if (GC_TYPE(ref) == IS_ARRAY) {
-                       ht = &((zend_array*)ref)->ht;
+                       ht = (zend_array*)ref;
                } else if (GC_TYPE(ref) == IS_REFERENCE) {
                        if (Z_REFCOUNTED(((zend_reference*)ref)->val)) {
                                ref = Z_COUNTED(((zend_reference*)ref)->val);
@@ -802,8 +784,9 @@ ZEND_API int zend_gc_collect_cycles(void)
                        } else if (GC_TYPE(p) == IS_ARRAY) {
                                zend_array *arr = (zend_array*)p;
 
+                               GC_REFCOUNT(arr) = 0;
                                GC_TYPE(arr) = IS_NULL;
-                               zend_hash_destroy(&arr->ht);
+                               zend_hash_destroy(arr);
                        }
                        current = GC_G(next_to_free);
                }
index 25349c766e4444a3fb367777c4d9082704517eac..96e8cb2788ab377f067303f705a6cac22821b7d8 100644 (file)
 #include "zend_globals.h"
 #include "zend_variables.h"
 
+#define HT_DEBUG 0
+#if HT_DEBUG
+# define HT_ASSERT(c) ZEND_ASSERT(c)
+#else
+# define HT_ASSERT(c)
+#endif 
+
 #if ZEND_DEBUG
 /*
 #define HASH_MASK_CONSISTENCY  0x60
@@ -115,6 +122,7 @@ static uint32_t zend_always_inline zend_hash_check_size(uint32_t nSize)
 
 static void zend_always_inline zend_hash_check_init(HashTable *ht, int packed)
 {
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
        if (UNEXPECTED(!((ht)->u.flags & HASH_FLAG_INITIALIZED))) {
                if (packed) {
                        (ht)->u.flags |= HASH_FLAG_INITIALIZED | HASH_FLAG_PACKED;
@@ -136,6 +144,8 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX};
 
 ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC)
 {
+       GC_REFCOUNT(ht) = 1;
+       GC_TYPE_INFO(ht) = IS_ARRAY;
        ht->nTableSize = zend_hash_check_size(nSize);
        ht->nTableMask = 0;
        ht->nNumUsed = 0;
@@ -150,6 +160,7 @@ ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestru
 
 static void zend_hash_packed_grow(HashTable *ht)
 {
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
        if (ht->nTableSize >= HT_MAX_SIZE) {
                zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%zu * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
        }
@@ -163,11 +174,13 @@ ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed)
 {
        IS_CONSISTENT(ht);
 
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
        CHECK_INIT(ht, packed);
 }
 
 ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
 {
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
        HANDLE_BLOCK_INTERRUPTIONS();
        ht->u.flags &= ~HASH_FLAG_PACKED;
        ht->nTableMask = ht->nTableSize - 1;
@@ -179,6 +192,7 @@ ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
 
 ZEND_API void zend_hash_to_packed(HashTable *ht)
 {
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
        HANDLE_BLOCK_INTERRUPTIONS();
        ht->u.flags |= HASH_FLAG_PACKED;
        ht->nTableMask = 0;
@@ -411,6 +425,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s
        Bucket *p;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
                CHECK_INIT(ht, 0);
@@ -563,6 +578,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht,
        Bucket *p;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
                CHECK_INIT(ht, h < ht->nTableSize);
@@ -711,6 +727,7 @@ static void zend_hash_do_resize(HashTable *ht)
 {
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (ht->nNumUsed > ht->nNumOfElements) {
                HANDLE_BLOCK_INTERRUPTIONS();
@@ -861,6 +878,7 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
        Bucket *prev = NULL;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        h = zend_string_hash_val(key);
        nIndex = h & ht->nTableMask;
@@ -891,6 +909,7 @@ ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
        Bucket *prev = NULL;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        h = zend_string_hash_val(key);
        nIndex = h & ht->nTableMask;
@@ -934,6 +953,7 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, size_t len)
        Bucket *prev = NULL;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        h = zend_inline_hash_func(str, len);
        nIndex = h & ht->nTableMask;
@@ -976,6 +996,7 @@ ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, size_t len)
        Bucket *prev = NULL;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        h = zend_inline_hash_func(str, len);
        nIndex = h & ht->nTableMask;
@@ -1004,6 +1025,7 @@ ZEND_API int zend_hash_index_del(HashTable *ht, zend_ulong h)
        Bucket *prev = NULL;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (ht->u.flags & HASH_FLAG_PACKED) {
                if (h < ht->nNumUsed) {
@@ -1035,6 +1057,7 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
        Bucket *p, *end;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) <= 1);
 
        if (ht->nNumUsed) {
                p = ht->arData;
@@ -1083,6 +1106,7 @@ ZEND_API void zend_array_destroy(HashTable *ht)
        Bucket *p, *end;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) <= 1);
 
        if (ht->nNumUsed) {
 
@@ -1125,6 +1149,7 @@ ZEND_API void zend_hash_clean(HashTable *ht)
        Bucket *p, *end;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (ht->nNumUsed) {
                p = ht->arData;
@@ -1172,6 +1197,7 @@ ZEND_API void zend_symtable_clean(HashTable *ht)
        Bucket *p, *end;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (ht->nNumUsed) {
                p = ht->arData;
@@ -1200,6 +1226,7 @@ ZEND_API void zend_hash_graceful_destroy(HashTable *ht)
        Bucket *p;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        for (idx = 0; idx < ht->nNumUsed; idx++) {
                p = ht->arData + idx;
@@ -1219,6 +1246,7 @@ ZEND_API void zend_hash_graceful_reverse_destroy(HashTable *ht)
        Bucket *p;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        idx = ht->nNumUsed;
        while (idx > 0) {
@@ -1251,6 +1279,7 @@ ZEND_API void zend_hash_apply(HashTable *ht, apply_func_t apply_func)
        int result;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        HASH_PROTECT_RECURSION(ht);
        for (idx = 0; idx < ht->nNumUsed; idx++) {
@@ -1277,6 +1306,7 @@ ZEND_API void zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t appl
        int result;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        HASH_PROTECT_RECURSION(ht);
        for (idx = 0; idx < ht->nNumUsed; idx++) {
@@ -1305,6 +1335,7 @@ ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t ap
        int result;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        HASH_PROTECT_RECURSION(ht);
 
@@ -1338,6 +1369,7 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func)
        int result;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        HASH_PROTECT_RECURSION(ht);
        idx = ht->nNumUsed;
@@ -1368,6 +1400,7 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
 
        IS_CONSISTENT(source);
        IS_CONSISTENT(target);
+       HT_ASSERT(GC_REFCOUNT(target) == 1);
 
        setTargetPointer = (target->nInternalPointer == INVALID_IDX);
        for (idx = 0; idx < source->nNumUsed; idx++) {
@@ -1404,15 +1437,20 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
 }
 
 
-ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
+ZEND_API HashTable *zend_array_dup(HashTable *source)
 {
     uint32_t idx, target_idx;
        uint32_t nIndex;
        Bucket *p, *q;
        zval *data;
+       HashTable *target;
 
        IS_CONSISTENT(source);
 
+       ALLOC_HASHTABLE(target);
+       GC_REFCOUNT(target) = 1;
+       GC_TYPE_INFO(target) = IS_ARRAY;
+
        target->nTableMask = source->nTableMask;
        target->nTableSize = source->nTableSize;
        target->pDestructor = source->pDestructor;
@@ -1522,6 +1560,7 @@ ZEND_API void zend_array_dup(HashTable *target, HashTable *source)
                target->arData = NULL;
                target->arHash = (uint32_t*)&uninitialized_bucket;
        }
+       return target;
 }
 
 
@@ -1534,6 +1573,7 @@ ZEND_API void _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_f
 
        IS_CONSISTENT(source);
        IS_CONSISTENT(target);
+       HT_ASSERT(GC_REFCOUNT(target) == 1);
 
        for (idx = 0; idx < source->nNumUsed; idx++) {
                p = source->arData + idx;
@@ -1580,6 +1620,7 @@ ZEND_API void zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor
 
        IS_CONSISTENT(source);
        IS_CONSISTENT(target);
+       HT_ASSERT(GC_REFCOUNT(target) == 1);
 
        for (idx = 0; idx < source->nNumUsed; idx++) {
                p = source->arData + idx;
@@ -1695,6 +1736,8 @@ ZEND_API void zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *p
     uint32_t idx;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
+
        for (idx = 0; idx < ht->nNumUsed; idx++) {
                if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
                        *pos = idx;
@@ -1713,6 +1756,7 @@ ZEND_API void zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos
        uint32_t idx;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
 
        idx = ht->nNumUsed;
        while (idx > 0) {
@@ -1731,6 +1775,7 @@ ZEND_API int zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
        uint32_t idx = *pos;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
 
        if (idx != INVALID_IDX) {
                while (1) {
@@ -1754,6 +1799,7 @@ ZEND_API int zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
        uint32_t idx = *pos;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
 
        if (idx != INVALID_IDX) {
                while (idx > 0) {
@@ -1887,6 +1933,7 @@ ZEND_API int zend_hash_sort_ex(HashTable *ht, sort_func_t sort, compare_func_t c
        uint32_t i, j;
 
        IS_CONSISTENT(ht);
+       HT_ASSERT(GC_REFCOUNT(ht) == 1);
 
        if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
                return SUCCESS;
index 602cd7a2e457593613f7a2fe0c0191b90a2f1532..afa3602fae1bbbfdc274bc18d1c9b26a51c061de 100644 (file)
@@ -213,7 +213,7 @@ ZEND_API zval *zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint
 
 ZEND_API int zend_hash_rehash(HashTable *ht);
 
-ZEND_API void zend_array_dup(HashTable *target, HashTable *source);
+ZEND_API HashTable *zend_array_dup(HashTable *source);
 ZEND_API void zend_array_destroy(HashTable *ht);
 ZEND_API void zend_symtable_clean(HashTable *ht);
 
index 9a376aa1a00bd488c45e6a8f2029dbade40a9766..eba9cea43cd436b008774ae460d8a5cea37ec2c6 100644 (file)
@@ -150,9 +150,7 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
        if (Z_TYPE(retval) == IS_ARRAY) {
                if (Z_IMMUTABLE(retval)) {
                        *is_temp = 1;
-                       ALLOC_HASHTABLE(ht);
-                       zend_array_dup(ht, Z_ARRVAL(retval));
-                       return ht;
+                       return zend_array_dup(Z_ARRVAL(retval));
                } else if (Z_REFCOUNT(retval) <= 1) {
                        *is_temp = 1;
                        ALLOC_HASHTABLE(ht);
index 76a3d31a8528542bb844760f9c93781f0d7904e6..0a084036b8c94c698a32b023fc09c49ce874266b 100644 (file)
@@ -566,8 +566,7 @@ ZEND_API void convert_to_array(zval *op) /* {{{ */
                                        HashTable *obj_ht = Z_OBJ_HT_P(op)->get_properties(op);
                                        if (obj_ht) {
                                                zval arr;
-                                               ZVAL_NEW_ARR(&arr);
-                                               zend_array_dup(Z_ARRVAL(arr), obj_ht);
+                                               ZVAL_ARR(&arr, zend_array_dup(obj_ht));
                                                zval_dtor(op);
                                                ZVAL_COPY_VALUE(op, &arr);
                                                return;
index 4c238f652bf14ac71a41287c93dadc1fe69d7453..0f6fabd3c4a7620129da76b235aa1ac474d76056 100644 (file)
@@ -159,7 +159,10 @@ typedef struct _Bucket {
        zend_string      *key;              /* string key or NULL for numerics */
 } Bucket;
 
-typedef struct _HashTable {
+typedef struct _zend_array HashTable;
+
+struct _zend_array {
+       zend_refcounted   gc;
        union {
                struct {
                        ZEND_ENDIAN_LOHI_4(
@@ -179,7 +182,7 @@ typedef struct _HashTable {
        Bucket           *arData;
        uint32_t         *arHash;
        dtor_func_t       pDestructor;
-} HashTable;
+};
 
 #define HT_MIN_SIZE 8
 
@@ -198,11 +201,6 @@ typedef struct _HashTableIterator {
        HashPosition  pos;
 } HashTableIterator;
 
-struct _zend_array {
-       zend_refcounted   gc;
-       HashTable         ht;
-};
-
 struct _zend_object {
        zend_refcounted   gc;
        uint32_t          handle; // TODO: may be removed ???
@@ -316,6 +314,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define IS_TYPE_REFCOUNTED                     (1<<2)
 #define IS_TYPE_COLLECTABLE                    (1<<3)
 #define IS_TYPE_COPYABLE                       (1<<4)
+#define IS_TYPE_SYMBOLTABLE                    (1<<5)
 
 /* extended types */
 #define IS_INTERNED_STRING_EX          IS_STRING
@@ -388,6 +387,9 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_IMMUTABLE(zval)                      ((Z_TYPE_FLAGS(zval) & IS_TYPE_IMMUTABLE) != 0)
 #define Z_IMMUTABLE_P(zval_p)          Z_IMMUTABLE(*(zval_p))
 
+#define Z_SYMBOLTABLE(zval)                    ((Z_TYPE_FLAGS(zval) & IS_TYPE_SYMBOLTABLE) != 0)
+#define Z_SYMBOLTABLE_P(zval_p)                Z_SYMBOLTABLE(*(zval_p))
+
 /* the following Z_OPT_* macros make better code when Z_TYPE_INFO accessed before */
 #define Z_OPT_TYPE(zval)                       (Z_TYPE_INFO(zval) & 0xff)
 #define Z_OPT_TYPE_P(zval_p)           Z_OPT_TYPE(*(zval_p))
@@ -437,7 +439,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_ARR(zval)                                    (zval).value.arr
 #define Z_ARR_P(zval_p)                                Z_ARR(*(zval_p))
 
-#define Z_ARRVAL(zval)                         (&Z_ARR(zval)->ht)
+#define Z_ARRVAL(zval)                         Z_ARR(zval)
 #define Z_ARRVAL_P(zval_p)                     Z_ARRVAL(*(zval_p))
 
 #define Z_OBJ(zval)                                    (zval).value.obj
@@ -576,8 +578,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define ZVAL_NEW_ARR(z) do {                                                                   \
                zval *__z = (z);                                                                                \
                zend_array *_arr = emalloc(sizeof(zend_array));                 \
-               GC_REFCOUNT(_arr) = 1;                                                                  \
-               GC_TYPE_INFO(_arr) = IS_ARRAY;                                                  \
                Z_ARR_P(__z) = _arr;                                                                    \
                Z_TYPE_INFO_P(__z) = IS_ARRAY_EX;                                               \
        } while (0)
@@ -585,8 +585,6 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define ZVAL_NEW_PERSISTENT_ARR(z) do {                                                        \
                zval *__z = (z);                                                                                \
                zend_array *_arr = malloc(sizeof(zend_array));                  \
-               GC_REFCOUNT(_arr) = 1;                                                                  \
-               GC_TYPE_INFO(_arr) = IS_ARRAY;                                                  \
                Z_ARR_P(__z) = _arr;                                                                    \
                Z_TYPE_INFO_P(__z) = IS_ARRAY_EX;                                               \
        } while (0)
@@ -709,7 +707,7 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 #define Z_TRY_DELREF(z)                                Z_TRY_DELREF_P(&(z))
 
 static zend_always_inline uint32_t zval_refcount_p(zval* pz) {
-       ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz));
+       ZEND_ASSERT(Z_REFCOUNTED_P(pz) || Z_IMMUTABLE_P(pz) || Z_SYMBOLTABLE_P(pz));
        return GC_REFCOUNT(Z_COUNTED_P(pz));
 }
 
index 6e9834475faa2375ded25943cd8c8f32844628eb..de0fa1285b8bd8e923d048caabe655237ee1ebbb 100644 (file)
@@ -40,15 +40,13 @@ ZEND_API void _zval_dtor_func(zend_refcounted *p ZEND_FILE_LINE_DC)
                case IS_ARRAY: {
                                zend_array *arr = (zend_array*)p;
 
-                               if (arr != &EG(symbol_table)) {
-                                       ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
-
-                                       /* break possible cycles */
-                                       GC_TYPE(arr) = IS_NULL;
-                                       GC_REMOVE_FROM_BUFFER(arr);
-                                       zend_array_destroy(&arr->ht);
-                                       efree_size(arr, sizeof(zend_array));
-                               }
+                               ZEND_ASSERT(GC_REFCOUNT(arr) <= 1);
+
+                               /* break possible cycles */
+                               GC_TYPE(arr) = IS_NULL;
+                               GC_REMOVE_FROM_BUFFER(arr);
+                               zend_array_destroy(arr);
+                               efree_size(arr, sizeof(zend_array));
                                break;
                        }
                case IS_CONSTANT_AST: {
@@ -100,13 +98,11 @@ ZEND_API void _zval_dtor_func_for_ptr(zend_refcounted *p ZEND_FILE_LINE_DC)
                case IS_ARRAY: {
                                zend_array *arr = (zend_array*)p;
 
-                               if (arr != &EG(symbol_table)) {
-                                       /* break possible cycles */
-                                       GC_TYPE(arr) = IS_NULL;
-                                       GC_REMOVE_FROM_BUFFER(arr);
-                                       zend_array_destroy(&arr->ht);
-                                       efree_size(arr, sizeof(zend_array));
-                               }
+                               /* break possible cycles */
+                               GC_TYPE(arr) = IS_NULL;
+                               GC_REMOVE_FROM_BUFFER(arr);
+                               zend_array_destroy(arr);
+                               efree_size(arr, sizeof(zend_array));
                                break;
                        }
                case IS_CONSTANT_AST: {
@@ -237,16 +233,8 @@ ZEND_API void _zval_copy_ctor_func(zval *zvalue ZEND_FILE_LINE_DC)
                        CHECK_ZVAL_STRING_REL(Z_STR_P(zvalue));
                        Z_STR_P(zvalue) = zend_string_dup(Z_STR_P(zvalue), 0);
                        break;
-               case IS_ARRAY: {
-                               HashTable *ht;
-
-                               if (Z_ARR_P(zvalue) == &EG(symbol_table)) {
-                                       return; /* do nothing */
-                               }
-                               ht = Z_ARRVAL_P(zvalue);
-                               ZVAL_NEW_ARR(zvalue);
-                               zend_array_dup(Z_ARRVAL_P(zvalue), ht);
-                       }
+               case IS_ARRAY:
+                       ZVAL_ARR(zvalue, zend_array_dup(Z_ARRVAL_P(zvalue)));
                        break;
                case IS_CONSTANT_AST: {
                                zend_ast_ref *ast = emalloc(sizeof(zend_ast_ref));
@@ -315,13 +303,13 @@ ZEND_API int zval_copy_static_var(zval *p, int num_args, va_list args, zend_hash
                is_ref = Z_CONST_FLAGS_P(p) & IS_LEXICAL_REF;
 
                symbol_table = zend_rebuild_symbol_table();
-               p = zend_hash_find(&symbol_table->ht, key->key);
+               p = zend_hash_find(symbol_table, key->key);
                if (!p) {
                        p = &tmp;
                        ZVAL_NULL(&tmp);
                        if (is_ref) {
                                ZVAL_NEW_REF(&tmp, &tmp);
-                               zend_hash_add_new(&symbol_table->ht, key->key, &tmp);
+                               zend_hash_add_new(symbol_table, key->key, &tmp);
                                Z_ADDREF_P(p);
                        } else {
                                zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
index 1aabbfa762d2f0effa367b775dee61cb8ce04015..0285f770387142ecfa9430e7f530d3079dc9110d 100644 (file)
@@ -4562,7 +4562,7 @@ ZEND_VM_C_LABEL(num_index_dim):
                                                ZEND_VM_C_GOTO(num_index_dim);
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -6442,8 +6442,8 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
 
        /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
        idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1;
-       if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) {
-               Bucket *p = EG(symbol_table).ht.arData + idx;
+       if (EXPECTED(idx < EG(symbol_table).nNumUsed)) {
+               Bucket *p = EG(symbol_table).arData + idx;
 
                if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
                (EXPECTED(p->key == Z_STR_P(varname)) ||
@@ -6452,19 +6452,19 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
                  EXPECTED(p->key->len == Z_STRLEN_P(varname)) &&
                  EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
 
-                       value = &EG(symbol_table).ht.arData[idx].val;
+                       value = &EG(symbol_table).arData[idx].val;
                        ZEND_VM_C_GOTO(check_indirect);
                }
        }
 
-       value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname));
+       value = zend_hash_find(&EG(symbol_table), Z_STR_P(varname));
        if (UNEXPECTED(value == NULL)) {
-               value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval));
-               idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+               value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval));
+               idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
                /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
                CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
        } else {
-               idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+               idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
                /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
                CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
 ZEND_VM_C_LABEL(check_indirect):
index 40873ef693d729047f1d85b250734cab480a287d..1e1f62e16e86e2bf4dcae2ef2186e9bd13bf235b 100644 (file)
@@ -14076,7 +14076,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -16913,7 +16913,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -18350,7 +18350,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -19646,7 +19646,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -21754,7 +21754,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -23145,7 +23145,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -26797,7 +26797,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -27346,8 +27346,8 @@ static int ZEND_FASTCALL  ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
 
        /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
        idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1;
-       if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) {
-               Bucket *p = EG(symbol_table).ht.arData + idx;
+       if (EXPECTED(idx < EG(symbol_table).nNumUsed)) {
+               Bucket *p = EG(symbol_table).arData + idx;
 
                if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) &&
                (EXPECTED(p->key == Z_STR_P(varname)) ||
@@ -27356,19 +27356,19 @@ static int ZEND_FASTCALL  ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN
                  EXPECTED(p->key->len == Z_STRLEN_P(varname)) &&
                  EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) {
 
-                       value = &EG(symbol_table).ht.arData[idx].val;
+                       value = &EG(symbol_table).arData[idx].val;
                        goto check_indirect;
                }
        }
 
-       value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname));
+       value = zend_hash_find(&EG(symbol_table), Z_STR_P(varname));
        if (UNEXPECTED(value == NULL)) {
-               value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval));
-               idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+               value = zend_hash_add_new(&EG(symbol_table), Z_STR_P(varname), &EG(uninitialized_zval));
+               idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
                /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
                CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
        } else {
-               idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket);
+               idx = ((char*)value - (char*)EG(symbol_table).arData) / sizeof(Bucket);
                /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */
                CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1));
 check_indirect:
@@ -30934,7 +30934,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
@@ -32889,7 +32889,7 @@ num_index_dim:
                                                goto num_index_dim;
                                        }
                                }
-                               if (ht == &EG(symbol_table).ht) {
+                               if (ht == &EG(symbol_table)) {
                                        zend_delete_global_variable(Z_STR_P(offset));
                                } else {
                                        zend_hash_del(ht, Z_STR_P(offset));
index 04c7e3a40eedae969b37282b3bb4793633d56e14..9e174fe99728baa08e883f62e0a2e5c8778f1ff6 100644 (file)
@@ -424,10 +424,8 @@ static HashTable* dom_get_debug_info_helper(zval *object, int *is_temp) /* {{{ *
 
        *is_temp = 1;
 
-       ALLOC_HASHTABLE(debug_info);
-
        std_props = zend_std_get_properties(object);
-       zend_array_dup(debug_info, std_props);
+       debug_info = zend_array_dup(std_props);
 
        if (!prop_handlers) {
                return debug_info;
index 7d591e2383fb1d7bc82dd0ca2e8207d782fafdd0..a64da9074569a78d92fd8dded6191d196df3742e 100644 (file)
@@ -433,8 +433,7 @@ static HashTable *gmp_get_debug_info(zval *obj, int *is_temp) /* {{{ */
        zval zv;
 
        *is_temp = 1;
-       ALLOC_HASHTABLE(ht);
-       zend_array_dup(ht, props);
+       ht = zend_array_dup(props);
 
        gmp_strval(&zv, gmpnum, 10);
        zend_hash_str_update(ht, "num", sizeof("num")-1, &zv);
@@ -560,7 +559,6 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
        smart_str buf = {0};
        zval zv;
        php_serialize_data_t serialize_data = (php_serialize_data_t) data;
-       zend_array tmp_arr;
 
        PHP_VAR_SERIALIZE_INIT(serialize_data);
 
@@ -568,8 +566,7 @@ static int gmp_serialize(zval *object, unsigned char **buffer, size_t *buf_len,
        php_var_serialize(&buf, &zv, &serialize_data);
        zval_dtor(&zv);
 
-       ZVAL_ARR(&zv, &tmp_arr);
-       tmp_arr.ht = *zend_std_get_properties(object);
+       ZVAL_ARR(&zv, zend_std_get_properties(object));
        php_var_serialize(&buf, &zv, &serialize_data);
 
        PHP_VAR_SERIALIZE_DESTROY(serialize_data);
index ebe7942e7f7fcc6260dd27bb055d9e67387ec852..4823609ca1dc747928a2e885c1e9badf1bb5b1ca 100644 (file)
@@ -1239,7 +1239,7 @@ static int zend_accel_get_auto_globals(void)
        int mask = 0;
 
        for (i = 0; i < ag_size ; i++) {
-               if (zend_hash_exists(&EG(symbol_table).ht, jit_auto_globals_str[i])) {
+               if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_str[i])) {
                        mask |= n;
                }
                n += n;
@@ -1249,7 +1249,7 @@ static int zend_accel_get_auto_globals(void)
 
 static int zend_accel_get_auto_globals_no_jit(void)
 {
-       if (zend_hash_exists(&EG(symbol_table).ht, jit_auto_globals_str[3])) {
+       if (zend_hash_exists(&EG(symbol_table), jit_auto_globals_str[3])) {
                return 8;
        }
        return 0;
@@ -2002,21 +2002,21 @@ static inline void zend_accel_fast_del_bucket(HashTable *ht, uint32_t idx, Bucke
 static void zend_accel_fast_shutdown(void)
 {
        if (EG(full_tables_cleanup)) {
-               EG(symbol_table).ht.pDestructor = accel_fast_zval_dtor;
+               EG(symbol_table).pDestructor = accel_fast_zval_dtor;
        } else {
                dtor_func_t old_destructor;
 
                if (EG(objects_store).top > 1 || zend_hash_num_elements(&EG(regular_list)) > 0) {
                        /* We don't have to destroy all zvals if they cannot call any destructors */
 
-                   old_destructor = EG(symbol_table).ht.pDestructor;
-                       EG(symbol_table).ht.pDestructor = accel_fast_zval_dtor;
+                   old_destructor = EG(symbol_table).pDestructor;
+                       EG(symbol_table).pDestructor = accel_fast_zval_dtor;
                        zend_try {
-                               zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
+                               zend_hash_graceful_reverse_destroy(&EG(symbol_table));
                        } zend_end_try();
-                       EG(symbol_table).ht.pDestructor = old_destructor;
+                       EG(symbol_table).pDestructor = old_destructor;
                }
-               zend_hash_init(&EG(symbol_table).ht, 8, NULL, NULL, 0);
+               zend_hash_init(&EG(symbol_table), 8, NULL, NULL, 0);
 
                ZEND_HASH_REVERSE_FOREACH(EG(function_table), 0) {
                        zend_function *func = Z_PTR(_p->val);
index 457b78cfc8c48addeeb6941ab09a050ed180ceb5..dc717ca768b1ca580bca2ae3c8b49bdb5cca3ac0 100644 (file)
@@ -212,7 +212,7 @@ static inline void zend_clone_zval(zval *src, int bind)
                                if (bind && Z_REFCOUNT_P(src) > 1) {
                                                accel_xlat_set(old, Z_ARR_P(src));
                                        }
-                                       zend_hash_clone_zval(Z_ARRVAL_P(src), &old->ht, 0);
+                                       zend_hash_clone_zval(Z_ARRVAL_P(src), old, 0);
                                }
                        }
                        break;
@@ -378,6 +378,8 @@ static zend_always_inline void zend_prepare_function_for_execution(zend_op_array
                HashTable *shared_statics = op_array->static_variables;
 
                ALLOC_HASHTABLE(op_array->static_variables);
+               GC_REFCOUNT(op_array->static_variables) = 1;
+               GC_TYPE(op_array->static_variables) = IS_ARRAY;
                zend_hash_clone_zval(op_array->static_variables, shared_statics, 0);
        }
 }
index a9b138bfb1906f867d5cb4b258ef11dd7f005ef3..df3ba20c85221389feb3a4ecd960624adce90fbd 100644 (file)
@@ -430,7 +430,7 @@ static char *cli_completion_generator_var(const char *text, int textlen, int *st
        char *retval, *tmp;
        zend_array *symbol_table = &EG(symbol_table);
 
-       tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, symbol_table ? &symbol_table->ht : NULL, NULL);
+       tmp = retval = cli_completion_generator_ht(text + 1, textlen - 1, state, symbol_table, NULL);
        if (retval) {
                retval = malloc(strlen(tmp) + 2);
                retval[0] = '$';
index 4d0354717295e458ffe25d3d708435d92b4cb453..782618dff7ea89a637a93123b053bf7d84ff755c 100644 (file)
@@ -205,7 +205,7 @@ static void php_session_track_init(void) /* {{{ */
        array_init(&session_vars);
        ZVAL_NEW_REF(&PS(http_session_vars), &session_vars);
        Z_ADDREF_P(&PS(http_session_vars));
-       zend_hash_update_ind(&EG(symbol_table).ht, var_name, &PS(http_session_vars));
+       zend_hash_update_ind(&EG(symbol_table), var_name, &PS(http_session_vars));
        zend_string_release(var_name);
 }
 /* }}} */
@@ -311,7 +311,7 @@ PHPAPI zend_string *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */
 
        gettimeofday(&tv, NULL);
 
-       if ((array = zend_hash_str_find(&EG(symbol_table).ht, "_SERVER", sizeof("_SERVER") - 1)) &&
+       if ((array = zend_hash_str_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER") - 1)) &&
                Z_TYPE_P(array) == IS_ARRAY &&
                (token = zend_hash_str_find(Z_ARRVAL_P(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR") - 1)) &&
                Z_TYPE_P(token) == IS_STRING
@@ -874,7 +874,7 @@ PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
        }
        ZVAL_NEW_REF(&PS(http_session_vars), &session_vars);
        Z_ADDREF_P(&PS(http_session_vars));
-       zend_hash_update_ind(&EG(symbol_table).ht, var_name, &PS(http_session_vars));
+       zend_hash_update_ind(&EG(symbol_table), var_name, &PS(http_session_vars));
        zend_string_release(var_name);
        return SUCCESS;
 }
@@ -936,8 +936,8 @@ PS_SERIALIZER_DECODE_FUNC(php_binary) /* {{{ */
 
                p += namelen + 1;
 
-               if ((tmp = zend_hash_find(&EG(symbol_table).ht, name))) {
-                       if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table).ht) || tmp == &PS(http_session_vars)) {
+               if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
+                       if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
                                efree(name);
                                continue;
                        }
@@ -1027,8 +1027,8 @@ PS_SERIALIZER_DECODE_FUNC(php) /* {{{ */
                name = zend_string_init(p, namelen, 0);
                q++;
 
-               if ((tmp = zend_hash_find(&EG(symbol_table).ht, name))) {
-                       if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table).ht) || tmp == &PS(http_session_vars)) {
+               if ((tmp = zend_hash_find(&EG(symbol_table), name))) {
+                       if ((Z_TYPE_P(tmp) == IS_ARRAY && Z_ARRVAL_P(tmp) == &EG(symbol_table)) || tmp == &PS(http_session_vars)) {
                                goto skip;
                        }
                }
@@ -1545,7 +1545,7 @@ PHPAPI void php_session_start(void) /* {{{ */
         */
 
        if (!PS(id)) {
-               if (PS(use_cookies) && (data = zend_hash_str_find(&EG(symbol_table).ht, "_COOKIE", sizeof("_COOKIE") - 1)) &&
+               if (PS(use_cookies) && (data = zend_hash_str_find(&EG(symbol_table), "_COOKIE", sizeof("_COOKIE") - 1)) &&
                                Z_TYPE_P(data) == IS_ARRAY &&
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
                ) {
@@ -1554,7 +1554,7 @@ PHPAPI void php_session_start(void) /* {{{ */
                }
 
                if (PS(define_sid) && !PS(id) &&
-                               (data = zend_hash_str_find(&EG(symbol_table).ht, "_GET", sizeof("_GET") - 1)) &&
+                               (data = zend_hash_str_find(&EG(symbol_table), "_GET", sizeof("_GET") - 1)) &&
                                Z_TYPE_P(data) == IS_ARRAY &&
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
                ) {
@@ -1562,7 +1562,7 @@ PHPAPI void php_session_start(void) /* {{{ */
                }
 
                if (PS(define_sid) && !PS(id) &&
-                               (data = zend_hash_str_find(&EG(symbol_table).ht, "_POST", sizeof("_POST") - 1)) &&
+                               (data = zend_hash_str_find(&EG(symbol_table), "_POST", sizeof("_POST") - 1)) &&
                                Z_TYPE_P(data) == IS_ARRAY &&
                                (ppid = zend_hash_str_find(Z_ARRVAL_P(data), PS(session_name), lensess))
                ) {
index 64c79c80d6730bb0a93994fdd21ccf4cd7af03ed..6d66ffdc8d1e3f48f2add73dc192db6c5a93827f 100644 (file)
@@ -1189,8 +1189,7 @@ PHP_METHOD(SoapServer, SoapServer)
 
                if ((tmp = zend_hash_str_find(ht, "classmap", sizeof("classmap")-1)) != NULL &&
                        Z_TYPE_P(tmp) == IS_ARRAY) {
-                       ALLOC_HASHTABLE(service->class_map);
-                       zend_array_dup(service->class_map, Z_ARRVAL_P(tmp));
+                       service->class_map = zend_array_dup(Z_ARRVAL_P(tmp));
                }
 
                if ((tmp = zend_hash_str_find(ht, "typemap", sizeof("typemap")-1)) != NULL &&
@@ -1571,7 +1570,7 @@ PHP_METHOD(SoapServer, handle)
                        zend_string *server = zend_string_init("_SERVER", sizeof("_SERVER") - 1, 0);
 
                        zend_is_auto_global(server);
-                       if ((server_vars = zend_hash_find(&EG(symbol_table).ht, server)) != NULL &&
+                       if ((server_vars = zend_hash_find(&EG(symbol_table), server)) != NULL &&
                            Z_TYPE_P(server_vars) == IS_ARRAY &&
                            (encoding = zend_hash_str_find(Z_ARRVAL_P(server_vars), "HTTP_CONTENT_ENCODING", sizeof("HTTP_CONTENT_ENCODING")-1)) != NULL &&
                            Z_TYPE_P(encoding) == IS_STRING) {
@@ -2914,9 +2913,7 @@ PHP_METHOD(SoapClient, __call)
                HashTable *default_headers = Z_ARRVAL_P(tmp);
                if (soap_headers) {
                        if (!free_soap_headers) {
-                               HashTable *t =  emalloc(sizeof(HashTable));
-                               zend_array_dup(t, soap_headers);
-                               soap_headers = t;
+                               soap_headers = zend_array_dup(soap_headers);
                                free_soap_headers = 1;
                        }
                        ZEND_HASH_FOREACH_VAL(default_headers, tmp) {
@@ -3164,8 +3161,7 @@ PHP_METHOD(SoapClient, __getCookies)
 
 
        if ((cookies = zend_hash_str_find(Z_OBJPROP_P(getThis()), "_cookies", sizeof("_cookies")-1)) != NULL) {
-               ZVAL_NEW_ARR(return_value);
-               zend_array_dup(Z_ARRVAL_P(return_value), Z_ARRVAL_P(cookies));
+               ZVAL_ARR(return_value, zend_array_dup(Z_ARRVAL_P(cookies)));
        } else {
                array_init(return_value);
        }
index 0ae066dbfbf5273dbe48c9167eb8b33df02ed128..5cdd333688912c2b2ab2dcba3ae73b6ec98ae517 100644 (file)
@@ -198,8 +198,7 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zval *
                if (clone_orig) {
                        intern->array = other->array;
                        if (Z_OBJ_HT_P(orig) == &spl_handler_ArrayObject) {
-                               ZVAL_NEW_ARR(&intern->array);
-                               zend_array_dup(Z_ARRVAL(intern->array), HASH_OF(&other->array));
+                               ZVAL_ARR(&intern->array, zend_array_dup(HASH_OF(&other->array)));
                        }
                        if (Z_OBJ_HT_P(orig) == &spl_handler_ArrayIterator) {
                                Z_ADDREF_P(&other->array);
@@ -553,7 +552,7 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
                        zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
                        return;
                }
-               if (ht == &EG(symbol_table).ht) {
+               if (ht == &EG(symbol_table)) {
                        if (zend_delete_global_variable(Z_STR_P(offset))) {
                                zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
                        }
@@ -824,8 +823,7 @@ SPL_METHOD(Array, getArrayCopy)
        zval *object = getThis();
        spl_array_object *intern = Z_SPLARRAY_P(object);
 
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), spl_array_get_hash_table(intern, 0));
+       ZVAL_ARR(return_value, zend_array_dup(spl_array_get_hash_table(intern, 0)));
 } /* }}} */
 
 static HashTable *spl_array_get_properties(zval *object) /* {{{ */
@@ -1141,10 +1139,6 @@ static void spl_array_it_rewind(zend_object_iterator *iter) /* {{{ */
 /* {{{ spl_array_set_array */
 static void spl_array_set_array(zval *object, spl_array_object *intern, zval *array, zend_long ar_flags, int just_array) {
 
-       if (Z_TYPE_P(array) == IS_ARRAY) {
-               SEPARATE_ARRAY(array);
-       }
-
        if (Z_TYPE_P(array) == IS_OBJECT && (Z_OBJ_HT_P(array) == &spl_handler_ArrayObject || Z_OBJ_HT_P(array) == &spl_handler_ArrayIterator)) {
                zval_ptr_dtor(&intern->array);
                if (just_array) {
@@ -1152,14 +1146,12 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
                        ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
                }
                ar_flags |= SPL_ARRAY_USE_OTHER;
-               ZVAL_COPY_VALUE(&intern->array, array);
        } else {
                if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) {
                        zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0);
                        return;
                }
                zval_ptr_dtor(&intern->array);
-               ZVAL_COPY_VALUE(&intern->array, array);
        }
        if (Z_TYPE_P(array) == IS_OBJECT && Z_OBJ_P(object) == Z_OBJ_P(array)) {
                intern->ar_flags |= SPL_ARRAY_IS_SELF;
@@ -1168,8 +1160,11 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
                intern->ar_flags &= ~SPL_ARRAY_IS_SELF;
        }
        intern->ar_flags |= ar_flags;
-       Z_ADDREF_P(&intern->array);
-       if (Z_TYPE_P(array) == IS_OBJECT) {
+       if (Z_TYPE_P(array) == IS_ARRAY) {
+               //??? TODO: try to avoid array duplication
+               ZVAL_DUP(&intern->array, array);
+       } else {
+               ZVAL_COPY(&intern->array, array);
                zend_object_get_properties_t handler = Z_OBJ_HANDLER_P(array, get_properties);
                if ((handler != std_object_handlers.get_properties && handler != spl_array_get_properties)
                || !spl_array_get_hash_table(intern, 0)) {
@@ -1327,8 +1322,7 @@ SPL_METHOD(Array, exchangeArray)
        zval *object = getThis(), *array;
        spl_array_object *intern = Z_SPLARRAY_P(object);
 
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), spl_array_get_hash_table(intern, 0));
+       ZVAL_ARR(return_value, zend_array_dup(spl_array_get_hash_table(intern, 0)));
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &array) == FAILURE) {
                return;
        }
@@ -1480,11 +1474,13 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
        HashTable *aht = spl_array_get_hash_table(intern, 0);
        zval tmp, *arg = NULL;
        zval retval;
+       uint32_t old_refcount;
 
-       /* A tricky way to pass "aht" by reference, copy HashTable */
+       /* A tricky way to pass "aht" by reference, reset refcount */
        //??? It may be not safe, if user comparison handler accesses "aht"
-       ZVAL_NEW_ARR(&tmp);
-       *Z_ARRVAL(tmp) = *aht;
+       old_refcount = GC_REFCOUNT(aht);
+       GC_REFCOUNT(aht) = 1;
+       ZVAL_ARR(&tmp, aht);
 
        if (!use_arg) {
                aht->u.v.nApplyCount++;
@@ -1492,7 +1488,7 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
                aht->u.v.nApplyCount--;
        } else if (use_arg == SPL_ARRAY_METHOD_MAY_USER_ARG) {
                if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "|z", &arg) == FAILURE) {
-                       zval_ptr_dtor(&tmp);
+                       GC_REFCOUNT(aht) = old_refcount;
                        zend_throw_exception(spl_ce_BadMethodCallException, "Function expects one argument at most", 0);
                        return;
                }
@@ -1501,7 +1497,7 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
                aht->u.v.nApplyCount--;
        } else {
                if (ZEND_NUM_ARGS() != 1 || zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {
-                       zval_ptr_dtor(&tmp);
+                       GC_REFCOUNT(aht) = old_refcount;
                        zend_throw_exception(spl_ce_BadMethodCallException, "Function expects exactly one argument", 0);
                        return;
                }
@@ -1513,9 +1509,9 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam
        if (Z_ISREF(tmp) && Z_TYPE_P(Z_REFVAL(tmp))) {
                *aht = *Z_ARRVAL_P(Z_REFVAL(tmp));
                GC_REMOVE_FROM_BUFFER(Z_ARR_P(Z_REFVAL(tmp)));
-               efree(Z_ARR_P(Z_REFVAL(tmp)));
                efree(Z_REF(tmp));
        }
+       GC_REFCOUNT(aht) = old_refcount;
        if (!Z_ISUNDEF(retval)) {
                ZVAL_COPY_VALUE(return_value, &retval);
        }
@@ -1749,8 +1745,7 @@ SPL_METHOD(Array, serialize)
                rebuild_object_properties(&intern->std);
        }
 
-       ZVAL_NEW_ARR(&members);
-       zend_array_dup(Z_ARRVAL(members), intern->std.properties);
+       ZVAL_ARR(&members, zend_array_dup(intern->std.properties));
 
        php_var_serialize(&buf, &members, &var_hash); /* finishes the string */
 
index a7d699b635c70d900f2d0912048b68e86d2b9935..fd5e08ee6648eb3941427e8c25b0ff04d992f237 100644 (file)
@@ -588,9 +588,7 @@ static HashTable *spl_filesystem_object_get_debug_info(zval *object, int *is_tem
                rebuild_object_properties(&intern->std);
        }
 
-       ALLOC_HASHTABLE(rv);
-
-       zend_array_dup(rv, intern->std.properties);
+       rv = zend_array_dup(intern->std.properties);
 
        pnstr = spl_gen_private_prop_name(spl_ce_SplFileInfo, "pathName", sizeof("pathName")-1);
        path = spl_filesystem_object_get_pathname(intern, &path_len);
index 9c63b448c6406e20e86a1559d3686834df57026d..76457616eadeda1e7aa9985fd8561210f26f862a 100644 (file)
@@ -769,8 +769,7 @@ SPL_METHOD(SplObjectStorage, serialize)
 
        /* members */
        smart_str_appendl(&buf, "m:", 2);
-       ZVAL_NEW_ARR(&members);
-       zend_array_dup(Z_ARRVAL(members), zend_std_get_properties(getThis()));
+       ZVAL_ARR(&members, zend_array_dup(zend_std_get_properties(getThis())));
        php_var_serialize(&buf, &members, &var_hash); /* finishes the string */
        zval_ptr_dtor(&members);
 
index f0f7d7848ba8845b6faace1544ef1f0f0c47ccd5..701e10dff2a66049417768ad40e9bf8d237b6dae 100644 (file)
@@ -1459,7 +1459,7 @@ PHP_FUNCTION(extract)
                var_exists = 0;
 
                if (var_name) {
-                       var_exists = zend_hash_exists_ind(&symbol_table->ht, var_name);
+                       var_exists = zend_hash_exists_ind(symbol_table, var_name);
                } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) {
                        zval num;
 
@@ -1529,18 +1529,18 @@ PHP_FUNCTION(extract)
                                ZVAL_MAKE_REF(entry);
                                Z_ADDREF_P(entry);
 
-                               if ((orig_var = zend_hash_find(&symbol_table->ht, Z_STR(final_name))) != NULL) {
+                               if ((orig_var = zend_hash_find(symbol_table, Z_STR(final_name))) != NULL) {
                                        if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
                                                orig_var = Z_INDIRECT_P(orig_var);
                                        }
                                        zval_ptr_dtor(orig_var);
                                        ZVAL_COPY_VALUE(orig_var, entry);
                                } else {
-                                       zend_hash_update(&symbol_table->ht, Z_STR(final_name), entry);
+                                       zend_hash_update(symbol_table, Z_STR(final_name), entry);
                                }
                        } else {
                                if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry);
-                               zend_hash_update_ind(&symbol_table->ht, Z_STR(final_name), entry);
+                               zend_hash_update_ind(symbol_table, Z_STR(final_name), entry);
                        }
                        count++;
                }
@@ -1604,7 +1604,7 @@ PHP_FUNCTION(compact)
        }
 
        for (i=0; i<ZEND_NUM_ARGS(); i++) {
-               php_compact_var(&symbol_table->ht, return_value, &args[i]);
+               php_compact_var(symbol_table, return_value, &args[i]);
        }
 }
 /* }}} */
@@ -2028,7 +2028,7 @@ static void php_splice(HashTable *in_hash, int offset, int length, HashTable *re
                                zend_hash_index_del(in_hash, p->h);
                        } else {
                                zend_hash_add_new(removed, p->key, entry);
-                               if (in_hash == &EG(symbol_table).ht) {
+                               if (in_hash == &EG(symbol_table)) {
                                        zend_delete_global_variable(p->key);
                                } else {
                                        zend_hash_del(in_hash, p->key);
@@ -2045,7 +2045,7 @@ static void php_splice(HashTable *in_hash, int offset, int length, HashTable *re
                        if (p->key == NULL) {
                                zend_hash_index_del(in_hash, p->h);
                        } else {
-                               if (in_hash == &EG(symbol_table).ht) {
+                               if (in_hash == &EG(symbol_table)) {
                                        zend_delete_global_variable(p->key);
                                } else {
                                        zend_hash_del(in_hash, p->key);
@@ -2181,7 +2181,7 @@ PHP_FUNCTION(array_pop)
 
        /* Delete the last value */
        if (p->key) {
-               if (Z_ARRVAL_P(stack) == &EG(symbol_table).ht) {
+               if (Z_ARRVAL_P(stack) == &EG(symbol_table)) {
                        zend_delete_global_variable(p->key);
                } else {
                        zend_hash_del(Z_ARRVAL_P(stack), p->key);
@@ -2238,7 +2238,7 @@ PHP_FUNCTION(array_shift)
 
        /* Delete the first value */
        if (p->key) {
-               if (Z_ARRVAL_P(stack) == &EG(symbol_table).ht) {
+               if (Z_ARRVAL_P(stack) == &EG(symbol_table)) {
                        zend_delete_global_variable(p->key);
                } else {
                        zend_hash_del(Z_ARRVAL_P(stack), p->key);
@@ -3305,8 +3305,7 @@ PHP_FUNCTION(array_unique)
 
        php_set_compare_func(sort_type);
 
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), Z_ARRVAL_P(array));
+       ZVAL_ARR(return_value, zend_array_dup(Z_ARRVAL_P(array)));
 
        if (Z_ARRVAL_P(array)->nNumOfElements <= 1) {   /* nothing to do */
                return;
@@ -3344,7 +3343,7 @@ PHP_FUNCTION(array_unique)
                        if (p->key == NULL) {
                                zend_hash_index_del(Z_ARRVAL_P(return_value), p->h);
                        } else {
-                               if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {
+                               if (Z_ARRVAL_P(return_value) == &EG(symbol_table)) {
                                        zend_delete_global_variable(p->key);
                                } else {
                                        zend_hash_del(Z_ARRVAL_P(return_value), p->key);
@@ -3661,8 +3660,7 @@ static void php_array_intersect(INTERNAL_FUNCTION_PARAMETERS, int behavior, int
        }
 
        /* copy the argument array */
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), Z_ARRVAL(args[0]));
+       ZVAL_ARR(return_value, zend_array_dup(Z_ARRVAL(args[0])));
 
        /* go through the lists and look for common values */
        while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {
@@ -4081,8 +4079,7 @@ static void php_array_diff(INTERNAL_FUNCTION_PARAMETERS, int behavior, int data_
        }
 
        /* copy the argument array */
-       ZVAL_NEW_ARR(return_value);
-       zend_array_dup(Z_ARRVAL_P(return_value), Z_ARRVAL(args[0]));
+       ZVAL_ARR(return_value, zend_array_dup(Z_ARRVAL(args[0])));
 
        /* go through the lists and look for values of ptr[0] that are not in the others */
        while (Z_TYPE(ptrs[0]->val) != IS_UNDEF) {
index dcd054fadb569cef078e2bf5521cb68ce6ea4d46..2b70414b1298c9d5e3fe8332c4c82374de78ed69 100644 (file)
@@ -4231,7 +4231,7 @@ PHP_FUNCTION(getopt)
         * from the symbol table. */
        if ((Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY || zend_is_auto_global_str(ZEND_STRL("_SERVER"))) &&
                ((args = zend_hash_str_find_ind(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL ||
-               (args = zend_hash_str_find_ind(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL)
+               (args = zend_hash_str_find_ind(&EG(symbol_table), "argv", sizeof("argv")-1)) != NULL)
        ) {
                int pos = 0;
                zval *entry;
index 27856126c3f05ed82538fc4961ad7e0e934e99e7..123a79ea123c7d406a6f3f786a88e05164e92ba8 100644 (file)
@@ -489,8 +489,7 @@ PHP_FUNCTION(get_browser)
        }
 
        if (return_array) {
-               ZVAL_NEW_ARR(return_value);
-               zend_array_dup(Z_ARRVAL_P(return_value), Z_ARRVAL_P(agent));
+               ZVAL_ARR(return_value, zend_array_dup(Z_ARRVAL_P(agent)));
        }
        else {
                object_init(return_value);
index 454cd04d5b90b05fe022821f92504a41ae149961..6e0ea812a4f991e8e3e7fd1bb1fc93dfceddb74a 100644 (file)
@@ -669,7 +669,7 @@ finish:
                zend_set_local_var_str("http_response_header", sizeof("http_response_header")-1, &ztmp, 0);
        }
 
-       response_header = zend_hash_str_find_ind(&symbol_table->ht, "http_response_header", sizeof("http_response_header")-1);
+       response_header = zend_hash_str_find_ind(symbol_table, "http_response_header", sizeof("http_response_header")-1);
 
        if (!php_stream_eof(stream)) {
                size_t tmp_line_len;
index eb0a7ca13188272662dd05ae371184eacececce4..943843508f7310806420806604e61e6d4b05b798 100644 (file)
@@ -204,7 +204,7 @@ static void php_print_gpcse_array(char *name, uint name_length)
        key = zend_string_init(name, name_length, 0);
        zend_is_auto_global(key);
 
-       if ((data = zend_hash_find(&EG(symbol_table).ht, key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
+       if ((data = zend_hash_find(&EG(symbol_table), key)) != NULL && (Z_TYPE_P(data) == IS_ARRAY)) {
                ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(data), num_key, string_key, tmp) {
                        if (!sapi_module.phpinfo_as_text) {
                                php_info_print("<tr>");
@@ -899,16 +899,16 @@ PHPAPI void php_print_info(int flag)
 
                php_info_print_table_start();
                php_info_print_table_header(2, "Variable", "Value");
-               if ((data = zend_hash_str_find(&EG(symbol_table).ht, "PHP_SELF", sizeof("PHP_SELF")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
+               if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_SELF", sizeof("PHP_SELF")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
                        php_info_print_table_row(2, "PHP_SELF", Z_STRVAL_P(data));
                }
-               if ((data = zend_hash_str_find(&EG(symbol_table).ht, "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
+               if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_TYPE", sizeof("PHP_AUTH_TYPE")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
                        php_info_print_table_row(2, "PHP_AUTH_TYPE", Z_STRVAL_P(data));
                }
-               if ((data = zend_hash_str_find(&EG(symbol_table).ht, "PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
+               if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_USER", sizeof("PHP_AUTH_USER")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
                        php_info_print_table_row(2, "PHP_AUTH_USER", Z_STRVAL_P(data));
                }
-               if ((data = zend_hash_str_find(&EG(symbol_table).ht, "PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
+               if ((data = zend_hash_str_find(&EG(symbol_table), "PHP_AUTH_PW", sizeof("PHP_AUTH_PW")-1)) != NULL && Z_TYPE_P(data) == IS_STRING) {
                        php_info_print_table_row(2, "PHP_AUTH_PW", Z_STRVAL_P(data));
                }
                php_print_gpcse_array(ZEND_STRL("_REQUEST"));
index 610e1e834f44cfa05a9a570b76925b4917ec1628..99b7632119c78a0871597aeaca063919a25f25fa 100644 (file)
@@ -667,7 +667,7 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var)
 
        if (Z_TYPE_P(name_var) == IS_STRING) {
                zend_array *symbol_table = zend_rebuild_symbol_table();
-               if ((val = zend_hash_find(&symbol_table->ht, Z_STR_P(name_var))) != NULL) {
+               if ((val = zend_hash_find(symbol_table, Z_STR_P(name_var))) != NULL) {
                        if (Z_TYPE_P(val) == IS_INDIRECT) {
                                val = Z_INDIRECT_P(val);
                        }
index d5d101ae55bd6a0adafcdfd1afe5524041f5f626..944a61f86bbdbeb9289f36b977bd76859683a049 100644 (file)
@@ -905,7 +905,7 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c
                                zval_ptr_dtor(&tmp);
                        }
                } else {
-                       zend_hash_str_update_ind(&EG(symbol_table).ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
+                       zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
                }
        }
        if (replace_buffer) {
@@ -1247,7 +1247,7 @@ static void php_error_cb(int type, const char *error_filename, const uint error_
                                zval_ptr_dtor(&tmp);
                        }
                } else {
-                       zend_hash_str_update_ind(&EG(symbol_table).ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
+                       zend_hash_str_update_ind(&EG(symbol_table), "php_errormsg", sizeof("php_errormsg")-1, &tmp);
                }
        }
 
index 8180a42022257da111b79ef2e5f18b5c8f0d0941..6b8a1726d534f2882d09ed0ee411bd1e97766af9 100644 (file)
@@ -110,7 +110,7 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
        }
 
        /* GLOBALS hijack attempt, reject parameter */
-       if (symtable1 == &EG(symbol_table).ht &&
+       if (symtable1 == &EG(symbol_table) &&
                var_len == sizeof("GLOBALS")-1 &&
                !memcmp(var, "GLOBALS", sizeof("GLOBALS")-1)) {
                zval_dtor(val);
@@ -571,8 +571,8 @@ static void php_build_argv(char *s, zval *track_vars_array)
 
        if (SG(request_info).argc) {
                Z_ADDREF(arr);
-               zend_hash_str_update(&EG(symbol_table).ht, "argv", sizeof("argv")-1, &arr);
-               zend_hash_str_add(&EG(symbol_table).ht, "argc", sizeof("argc")-1, &argc);
+               zend_hash_str_update(&EG(symbol_table), "argv", sizeof("argv")-1, &arr);
+               zend_hash_str_add(&EG(symbol_table), "argc", sizeof("argc")-1, &argc);
        }
        if (track_vars_array && Z_TYPE_P(track_vars_array) == IS_ARRAY) {
                Z_ADDREF(arr);
@@ -624,7 +624,7 @@ static void php_autoglobal_merge(HashTable *dest, HashTable *src)
        zval *src_entry, *dest_entry;
        zend_string *string_key;
        zend_ulong num_key;
-       int globals_check = (dest == (&EG(symbol_table).ht));
+       int globals_check = (dest == (&EG(symbol_table)));
 
        ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) {
                if (Z_TYPE_P(src_entry) != IS_ARRAY
@@ -674,7 +674,7 @@ static zend_bool php_auto_globals_create_get(zend_string *name)
                array_init(&PG(http_globals)[TRACK_VARS_GET]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_GET]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_GET]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_GET]);
 
        return 0; /* don't rearm */
@@ -693,7 +693,7 @@ static zend_bool php_auto_globals_create_post(zend_string *name)
                array_init(&PG(http_globals)[TRACK_VARS_POST]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_POST]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_POST]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_POST]);
 
        return 0; /* don't rearm */
@@ -708,7 +708,7 @@ static zend_bool php_auto_globals_create_cookie(zend_string *name)
                array_init(&PG(http_globals)[TRACK_VARS_COOKIE]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_COOKIE]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_COOKIE]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_COOKIE]);
 
        return 0; /* don't rearm */
@@ -720,7 +720,7 @@ static zend_bool php_auto_globals_create_files(zend_string *name)
                array_init(&PG(http_globals)[TRACK_VARS_FILES]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_FILES]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_FILES]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_FILES]);
 
        return 0; /* don't rearm */
@@ -735,8 +735,8 @@ static zend_bool php_auto_globals_create_server(zend_string *name)
                        if (SG(request_info).argc) {
                                zval *argc, *argv;
 
-                               if ((argc = zend_hash_str_find(&EG(symbol_table).ht, "argc", sizeof("argc")-1)) != NULL &&
-                                       (argv = zend_hash_str_find(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL) {
+                               if ((argc = zend_hash_str_find(&EG(symbol_table), "argc", sizeof("argc")-1)) != NULL &&
+                                       (argv = zend_hash_str_find(&EG(symbol_table), "argv", sizeof("argv")-1)) != NULL) {
                                        Z_ADDREF_P(argv);
                                        zend_hash_str_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1, argv);
                                        zend_hash_str_update(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), "argc", sizeof("argc")-1, argc);
@@ -751,7 +751,7 @@ static zend_bool php_auto_globals_create_server(zend_string *name)
                array_init(&PG(http_globals)[TRACK_VARS_SERVER]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_SERVER]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_SERVER]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_SERVER]);
 
        return 0; /* don't rearm */
@@ -766,7 +766,7 @@ static zend_bool php_auto_globals_create_env(zend_string *name)
                php_import_environment_variables(&PG(http_globals)[TRACK_VARS_ENV]);
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &PG(http_globals)[TRACK_VARS_ENV]);
+       zend_hash_update(&EG(symbol_table), name, &PG(http_globals)[TRACK_VARS_ENV]);
        Z_ADDREF(PG(http_globals)[TRACK_VARS_ENV]);
 
        return 0; /* don't rearm */
@@ -812,7 +812,7 @@ static zend_bool php_auto_globals_create_request(zend_string *name)
                }
        }
 
-       zend_hash_update(&EG(symbol_table).ht, name, &form_variables);
+       zend_hash_update(&EG(symbol_table), name, &form_variables);
        return 0;
 }
 
index 81eba9a83a98d172579d174b2ef9c1ff13ce6dbf..e92d95d6941982f725c8038d78e03017bb2d3d8c 100644 (file)
@@ -1033,14 +1033,14 @@ static int do_cli(int argc, char **argv) /* {{{ */
                                        exit_status=254;
                                }
                                ZVAL_LONG(&argi, index);
-                               zend_hash_str_update(&EG(symbol_table).ht, "argi", sizeof("argi")-1, &argi);
+                               zend_hash_str_update(&EG(symbol_table), "argi", sizeof("argi")-1, &argi);
                                while (exit_status == SUCCESS && (input=php_stream_gets(s_in_process, NULL, 0)) != NULL) {
                                        len = strlen(input);
                                        while (len > 0 && len-- && (input[len]=='\n' || input[len]=='\r')) {
                                                input[len] = '\0';
                                        }
                                        ZVAL_STRINGL(&argn, input, len);
-                                       zend_hash_str_update(&EG(symbol_table).ht, "argn", sizeof("argn")-1, &argn);
+                                       zend_hash_str_update(&EG(symbol_table), "argn", sizeof("argn")-1, &argn);
                                        Z_LVAL(argi) = ++index;
                                        if (exec_run) {
                                                if (zend_eval_string_ex(exec_run, NULL, "Command line run code", 1) == FAILURE) {
index 6dc99d04c98ebfb19821e21cdc00b6df355e11c0..7e703889b22e210d42aea78b811be51541e59c4e 100644 (file)
@@ -269,7 +269,7 @@ char* fpm_php_get_string_from_table(zend_string *table, char *key) /* {{{ */
        zend_is_auto_global(table);
 
        /* find the table and ensure it's an array */
-       data = zend_hash_find(&EG(symbol_table).ht, table);
+       data = zend_hash_find(&EG(symbol_table), table);
        if (!data || Z_TYPE_P(data) != IS_ARRAY) {
                return NULL;
        }
index 0815ac3686c881eec640c8ae6503d74ce61b9b66..51baea08bfd5e3bceda8816df086d52e243e52ad 100644 (file)
@@ -188,7 +188,7 @@ static int phpdbg_print_symbols(zend_bool show_globals) {
        zend_hash_init(&vars, 8, NULL, NULL, 0);
 
        phpdbg_try_access {
-               ZEND_HASH_FOREACH_STR_KEY_VAL(&symtable->ht, var, data) {
+               ZEND_HASH_FOREACH_STR_KEY_VAL(symtable, var, data) {
                        if (zend_is_auto_global(var) ^ !show_globals) {
                                zend_hash_update(&vars, var, data);
                        }
index cb03b1a287915edf1b44feeae61264d58932be8b..6e492b7aaa4a3343222dfd4080570430895454eb 100644 (file)
@@ -599,7 +599,7 @@ PHPDBG_COMMAND(run) /* {{{ */
 
                /* clean up from last execution */
                if (ex && ex->symbol_table) {
-                       zend_hash_clean(&ex->symbol_table->ht);
+                       zend_hash_clean(ex->symbol_table);
                } else {
                        zend_rebuild_symbol_table();
                }
@@ -705,7 +705,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
 
        if (PHPDBG_G(flags) & PHPDBG_IN_SIGNAL_HANDLER) {
                phpdbg_try_access {
-                       phpdbg_parse_variable(param->str, param->len, &EG(symbol_table).ht, 0, phpdbg_output_ev_variable, 0);
+                       phpdbg_parse_variable(param->str, param->len, &EG(symbol_table), 0, phpdbg_output_ev_variable, 0);
                } phpdbg_catch_access {
                        phpdbg_error("signalsegv", "", "Could not fetch data, invalid data source");
                } phpdbg_end_try_access();
index 821b848443a44d39c09064d745908fd4d0142bcf..480c22c67b16a580c729962791a4cf36d7040706 100644 (file)
@@ -28,7 +28,7 @@ static void phpdbg_rebuild_http_globals_array(int type, const char *name) {
        if (Z_TYPE(PG(http_globals)[type]) != IS_UNDEF) {
                zval_dtor(&PG(http_globals)[type]);
        }
-       if ((zvp = zend_hash_str_find(&EG(symbol_table).ht, name, strlen(name)))) {
+       if ((zvp = zend_hash_str_find(&EG(symbol_table), name, strlen(name)))) {
                Z_ADDREF_P(zvp);
                PG(http_globals)[type] = *zvp;
        }
@@ -157,7 +157,7 @@ void phpdbg_webdata_decompress(char *msg, int len) {
                PG(auto_globals_jit) = 0;
                zend_hash_apply(CG(auto_globals), (apply_func_t) phpdbg_dearm_autoglobals);
 
-               zend_hash_clean(&EG(symbol_table).ht);
+               zend_hash_clean(&EG(symbol_table));
                EG(symbol_table) = *Z_ARR_P(zvp);
 
                /* Rebuild cookies, env vars etc. from GLOBALS (PG(http_globals)) */
index 373b4481b3e0f824d79515dd2273f1a196cf3c16..c1d0762af602ddf07cac6bd1fe26790270e3ea29 100644 (file)
@@ -407,14 +407,14 @@ PHPDBG_API int phpdbg_watchpoint_parse_input(char *input, size_t len, HashTable
 
 static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t *)) {
        if (EG(scope) && len >= 5 && !memcmp("$this", input, 5)) {
-               zend_hash_str_add(&EG(current_execute_data)->symbol_table->ht, ZEND_STRL("this"), &EG(current_execute_data)->This);
+               zend_hash_str_add(EG(current_execute_data)->symbol_table, ZEND_STRL("this"), &EG(current_execute_data)->This);
        }
 
-       if (phpdbg_is_auto_global(input, len) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table).ht, 0, callback, 1) != FAILURE) {
+       if (phpdbg_is_auto_global(input, len) && phpdbg_watchpoint_parse_input(input, len, &EG(symbol_table), 0, callback, 1) != FAILURE) {
                return SUCCESS;
        }
 
-       return phpdbg_watchpoint_parse_input(input, len, &EG(current_execute_data)->symbol_table->ht, 0, callback, 0);
+       return phpdbg_watchpoint_parse_input(input, len, EG(current_execute_data)->symbol_table, 0, callback, 0);
 }
 
 PHPDBG_WATCH(delete) /* {{{ */
index 10432c9fda18bd01e261b7ebc4e484e121fbd78f..af5847c7f44c8aef5bcb50e31ec0a7fba21c9571 100644 (file)
@@ -43,7 +43,7 @@ PHPDBG_API void phpdbg_webdata_compress(char **msg, int *len) {
                phpdbg_is_auto_global(ZEND_STRL("_SERVER"));
                phpdbg_is_auto_global(ZEND_STRL("_REQUEST"));
                array_init(&zv[1]);
-               zend_hash_copy(Z_ARRVAL(zv[1]), &EG(symbol_table).ht, NULL);
+               zend_hash_copy(Z_ARRVAL(zv[1]), &EG(symbol_table), NULL);
                Z_ARRVAL(zv[1])->pDestructor = NULL; /* we're operating on a copy! Don't double free zvals */
                zend_hash_str_del(Z_ARRVAL(zv[1]), ZEND_STRL("GLOBALS")); /* do not use the reference to itself in json */
                zend_hash_str_add(ht, ZEND_STRL("GLOBALS"), &zv[1]);