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.
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;
}
/* }}} */
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));
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));
{
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));
}
/* }}} */
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);
}
(*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) {
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;
if (!EX(symbol_table)) {
zend_rebuild_symbol_table();
}
- ht = &EX(symbol_table)->ht;
+ ht = EX(symbol_table);
}
return ht;
}
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;
}
}
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);
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 */
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;
}
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)--;
}
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);
}
/* }}} */
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;
}
{
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 */
{
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++) {
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;
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;
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;
}
} 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;
}
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;
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 {
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)) {
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;
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 {
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)) {
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 {
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;
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 {
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);
} 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);
}
#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
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;
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;
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));
}
{
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;
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;
Bucket *p;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (UNEXPECTED(!(ht->u.flags & HASH_FLAG_INITIALIZED))) {
CHECK_INIT(ht, 0);
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);
{
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed > ht->nNumOfElements) {
HANDLE_BLOCK_INTERRUPTIONS();
Bucket *prev = NULL;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_string_hash_val(key);
nIndex = h & ht->nTableMask;
Bucket *prev = NULL;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_string_hash_val(key);
nIndex = h & ht->nTableMask;
Bucket *prev = NULL;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_inline_hash_func(str, len);
nIndex = h & ht->nTableMask;
Bucket *prev = NULL;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
h = zend_inline_hash_func(str, len);
nIndex = h & ht->nTableMask;
Bucket *prev = NULL;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->u.flags & HASH_FLAG_PACKED) {
if (h < ht->nNumUsed) {
Bucket *p, *end;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) <= 1);
if (ht->nNumUsed) {
p = ht->arData;
Bucket *p, *end;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) <= 1);
if (ht->nNumUsed) {
Bucket *p, *end;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed) {
p = ht->arData;
Bucket *p, *end;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
if (ht->nNumUsed) {
p = ht->arData;
Bucket *p;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
for (idx = 0; idx < ht->nNumUsed; idx++) {
p = ht->arData + idx;
Bucket *p;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
idx = ht->nNumUsed;
while (idx > 0) {
int result;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
int result;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
for (idx = 0; idx < ht->nNumUsed; idx++) {
int result;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
int result;
IS_CONSISTENT(ht);
+ HT_ASSERT(GC_REFCOUNT(ht) == 1);
HASH_PROTECT_RECURSION(ht);
idx = ht->nNumUsed;
IS_CONSISTENT(source);
IS_CONSISTENT(target);
+ HT_ASSERT(GC_REFCOUNT(target) == 1);
setTargetPointer = (target->nInternalPointer == INVALID_IDX);
for (idx = 0; idx < source->nNumUsed; idx++) {
}
-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;
target->arData = NULL;
target->arHash = (uint32_t*)&uninitialized_bucket;
}
+ return target;
}
IS_CONSISTENT(source);
IS_CONSISTENT(target);
+ HT_ASSERT(GC_REFCOUNT(target) == 1);
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
IS_CONSISTENT(source);
IS_CONSISTENT(target);
+ HT_ASSERT(GC_REFCOUNT(target) == 1);
for (idx = 0; idx < source->nNumUsed; idx++) {
p = source->arData + idx;
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;
uint32_t idx;
IS_CONSISTENT(ht);
+ HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
idx = ht->nNumUsed;
while (idx > 0) {
uint32_t idx = *pos;
IS_CONSISTENT(ht);
+ HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
if (idx != INVALID_IDX) {
while (1) {
uint32_t idx = *pos;
IS_CONSISTENT(ht);
+ HT_ASSERT(ht->nInternalPointer != &pos || GC_REFCOUNT(ht) == 1);
if (idx != INVALID_IDX) {
while (idx > 0) {
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;
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);
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);
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;
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(
Bucket *arData;
uint32_t *arHash;
dtor_func_t pDestructor;
-} HashTable;
+};
#define HT_MIN_SIZE 8
HashPosition pos;
} HashTableIterator;
-struct _zend_array {
- zend_refcounted gc;
- HashTable ht;
-};
-
struct _zend_object {
zend_refcounted gc;
uint32_t handle; // TODO: may be removed ???
#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
#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))
#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
#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)
#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)
#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));
}
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: {
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: {
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));
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);
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));
/* 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)) ||
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):
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));
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));
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));
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));
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));
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));
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));
/* 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)) ||
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:
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));
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));
*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;
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);
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);
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);
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;
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;
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);
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;
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);
}
}
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] = '$';
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);
}
/* }}} */
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
}
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;
}
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;
}
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;
}
}
*/
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))
) {
}
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))
) {
}
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))
) {
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 &&
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) {
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) {
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);
}
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);
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));
}
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) /* {{{ */
/* {{{ 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) {
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;
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)) {
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;
}
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++;
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;
}
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;
}
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);
}
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 */
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);
/* 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);
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;
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++;
}
}
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]);
}
}
/* }}} */
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);
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);
/* 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);
/* 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);
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;
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);
}
/* 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) {
}
/* 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) {
* 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;
}
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);
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;
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>");
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"));
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);
}
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) {
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);
}
}
}
/* 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);
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);
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
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 */
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 */
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 */
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 */
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);
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 */
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 */
}
}
- zend_hash_update(&EG(symbol_table).ht, name, &form_variables);
+ zend_hash_update(&EG(symbol_table), name, &form_variables);
return 0;
}
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) {
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;
}
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);
}
/* 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();
}
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();
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;
}
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)) */
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) /* {{{ */
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]);