From e10e151e9b92313a7085272c85bebf6c82017fce Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 13 Feb 2015 22:20:39 +0300 Subject: [PATCH] Merged zend_array and HashTable into the single data structure. 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. --- Zend/zend.c | 6 +-- Zend/zend_builtin_functions.c | 6 +-- Zend/zend_closures.c | 3 +- Zend/zend_compile.c | 5 +-- Zend/zend_execute.c | 8 ++-- Zend/zend_execute_API.c | 39 ++++++++---------- Zend/zend_gc.c | 49 ++++++++--------------- Zend/zend_hash.c | 49 ++++++++++++++++++++++- Zend/zend_hash.h | 2 +- Zend/zend_object_handlers.c | 4 +- Zend/zend_operators.c | 3 +- Zend/zend_types.h | 24 +++++------ Zend/zend_variables.c | 44 ++++++++------------ Zend/zend_vm_def.h | 16 ++++---- Zend/zend_vm_execute.h | 32 +++++++-------- ext/dom/php_dom.c | 4 +- ext/gmp/gmp.c | 7 +--- ext/opcache/ZendAccelerator.c | 16 ++++---- ext/opcache/zend_accelerator_util_funcs.c | 4 +- ext/readline/readline_cli.c | 2 +- ext/session/session.c | 20 ++++----- ext/soap/soap.c | 12 ++---- ext/spl/spl_array.c | 41 +++++++++---------- ext/spl/spl_directory.c | 4 +- ext/spl/spl_observer.c | 3 +- ext/standard/array.c | 29 ++++++-------- ext/standard/basic_functions.c | 2 +- ext/standard/browscap.c | 3 +- ext/standard/http_fopen_wrapper.c | 2 +- ext/standard/info.c | 10 ++--- ext/wddx/wddx.c | 2 +- main/main.c | 4 +- main/php_variables.c | 26 ++++++------ sapi/cli/php_cli.c | 4 +- sapi/fpm/fpm/fpm_php.c | 2 +- sapi/phpdbg/phpdbg_info.c | 2 +- sapi/phpdbg/phpdbg_prompt.c | 4 +- sapi/phpdbg/phpdbg_wait.c | 4 +- sapi/phpdbg/phpdbg_watch.c | 6 +-- sapi/phpdbg/phpdbg_webdata_transfer.c | 2 +- 40 files changed, 244 insertions(+), 261 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 1bd70ab292..d5618b490d 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -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(¶ms[4]); } else { - ZVAL_NEW_ARR(¶ms[4]); - zend_array_dup(Z_ARRVAL(params[4]), &symbol_table->ht); + ZVAL_ARR(¶ms[4], zend_array_dup(symbol_table)); } ZVAL_COPY_VALUE(&orig_user_error_handler, &EG(user_error_handler)); diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 582296a8df..da90e4c98d 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -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)); } /* }}} */ diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 3478ee6816..fb37bf2705 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -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); } diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index ba5046f343..36055258f6 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -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) { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 73c1d4d17c..539b1e4dd7 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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; } } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 0554e31a5e..0d722e5820 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -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; diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 947ddc84eb..13d3ee7f01 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -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); } diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 25349c766e..96e8cb2788 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -23,6 +23,13 @@ #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; diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 602cd7a2e4..afa3602fae 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -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); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 9a376aa1a0..eba9cea43c 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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); diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 76a3d31a85..0a084036b8 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -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; diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 4c238f652b..0f6fabd3c4 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -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)); } diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 6e9834475f..de0fa1285b 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -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); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1aabbfa762..0285f77038 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -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): diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 40873ef693..1e1f62e16e 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -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)); diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index 04c7e3a40e..9e174fe997 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -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; diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 7d591e2383..a64da90745 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -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); diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c index ebe7942e7f..4823609ca1 100644 --- a/ext/opcache/ZendAccelerator.c +++ b/ext/opcache/ZendAccelerator.c @@ -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); diff --git a/ext/opcache/zend_accelerator_util_funcs.c b/ext/opcache/zend_accelerator_util_funcs.c index 457b78cfc8..dc717ca768 100644 --- a/ext/opcache/zend_accelerator_util_funcs.c +++ b/ext/opcache/zend_accelerator_util_funcs.c @@ -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); } } diff --git a/ext/readline/readline_cli.c b/ext/readline/readline_cli.c index a9b138bfb1..df3ba20c85 100644 --- a/ext/readline/readline_cli.c +++ b/ext/readline/readline_cli.c @@ -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] = '$'; diff --git a/ext/session/session.c b/ext/session/session.c index 4d03547172..782618dff7 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -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)) ) { diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 64c79c80d6..6d66ffdc8d 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -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); } diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 0ae066dbfb..5cdd333688 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -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 */ diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index a7d699b635..fd5e08ee66 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -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); diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 9c63b448c6..76457616ea 100644 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -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); diff --git a/ext/standard/array.c b/ext/standard/array.c index f0f7d7848b..701e10dff2 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -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; iht, 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) { diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index dcd054fadb..2b70414b12 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -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; diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 27856126c3..123a79ea12 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -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); diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 454cd04d5b..6e0ea812a4 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -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; diff --git a/ext/standard/info.c b/ext/standard/info.c index eb0a7ca131..943843508f 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -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(""); @@ -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")); diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 610e1e834f..99b7632119 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -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); } diff --git a/main/main.c b/main/main.c index d5d101ae55..944a61f86b 100644 --- a/main/main.c +++ b/main/main.c @@ -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); } } diff --git a/main/php_variables.c b/main/php_variables.c index 8180a42022..6b8a1726d5 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -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; } diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index 81eba9a83a..e92d95d694 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -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) { diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index 6dc99d04c9..7e703889b2 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -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; } diff --git a/sapi/phpdbg/phpdbg_info.c b/sapi/phpdbg/phpdbg_info.c index 0815ac3686..51baea08bf 100644 --- a/sapi/phpdbg/phpdbg_info.c +++ b/sapi/phpdbg/phpdbg_info.c @@ -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); } diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index cb03b1a287..6e492b7aaa 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -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(); diff --git a/sapi/phpdbg/phpdbg_wait.c b/sapi/phpdbg/phpdbg_wait.c index 821b848443..480c22c67b 100644 --- a/sapi/phpdbg/phpdbg_wait.c +++ b/sapi/phpdbg/phpdbg_wait.c @@ -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)) */ diff --git a/sapi/phpdbg/phpdbg_watch.c b/sapi/phpdbg/phpdbg_watch.c index 373b4481b3..c1d0762af6 100644 --- a/sapi/phpdbg/phpdbg_watch.c +++ b/sapi/phpdbg/phpdbg_watch.c @@ -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) /* {{{ */ diff --git a/sapi/phpdbg/phpdbg_webdata_transfer.c b/sapi/phpdbg/phpdbg_webdata_transfer.c index 10432c9fda..af5847c7f4 100644 --- a/sapi/phpdbg/phpdbg_webdata_transfer.c +++ b/sapi/phpdbg/phpdbg_webdata_transfer.c @@ -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]); -- 2.40.0