diff options
author | Dmitry Stogov <dmitry@zend.com> | 2014-05-26 17:16:16 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2014-05-26 17:16:16 +0400 |
commit | 40256e0f9c76b7233e264b8a6e8430feee2c551c (patch) | |
tree | d4756b05ae1c24ee4ccf414b4ff91d1074714767 | |
parent | 22f6cf91d54d2a475e818ba82b673ede08e923ea (diff) | |
download | php-git-40256e0f9c76b7233e264b8a6e8430feee2c551c.tar.gz |
Use specialized functions instead of macros
-rw-r--r-- | Zend/zend_builtin_functions.c | 24 | ||||
-rw-r--r-- | Zend/zend_execute.c | 2 | ||||
-rw-r--r-- | Zend/zend_execute_API.c | 2 | ||||
-rw-r--r-- | Zend/zend_hash.c | 161 | ||||
-rw-r--r-- | Zend/zend_hash.h | 43 | ||||
-rw-r--r-- | Zend/zend_object_handlers.c | 2 | ||||
-rw-r--r-- | Zend/zend_operators.c | 2 | ||||
-rw-r--r-- | Zend/zend_variables.c | 2 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 6 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 28 | ||||
-rw-r--r-- | ext/standard/array.c | 136 |
11 files changed, 270 insertions, 138 deletions
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 6f5b25fbf2..e8e4c54e9c 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -621,7 +621,7 @@ ZEND_FUNCTION(each) if (Z_REFCOUNTED_P(entry)) Z_ADDREF_P(entry); } zend_hash_index_update(Z_ARRVAL_P(return_value), 1, entry); - zend_hash_str_update(Z_ARRVAL_P(return_value), "value", sizeof("value")-1, entry); + zend_hash_str_add_new(Z_ARRVAL_P(return_value), "value", sizeof("value")-1, entry); /* add the key elements */ if (zend_hash_get_current_key(target_hash, &key, &num_key, 0) == HASH_KEY_IS_STRING) { @@ -629,7 +629,7 @@ ZEND_FUNCTION(each) } else { inserted_pointer = add_get_index_long(return_value, 0, num_key); } - zend_hash_str_update(Z_ARRVAL_P(return_value), "key", sizeof("key")-1, inserted_pointer); + zend_hash_str_add_new(Z_ARRVAL_P(return_value), "key", sizeof("key")-1, inserted_pointer); if (Z_REFCOUNTED_P(inserted_pointer)) Z_ADDREF_P(inserted_pointer); zend_hash_move_forward(target_hash); } @@ -934,7 +934,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value zval_update_constant(&prop_copy, 0 TSRMLS_CC); } - zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy); + zend_hash_add_new(Z_ARRVAL_P(return_value), key, &prop_copy); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1001,9 +1001,9 @@ ZEND_FUNCTION(get_object_vars) if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); if (key->val[0] == 0) { zend_unmangle_property_name_ex(key->val, key->len, &class_name, &prop_name, (int*) &prop_len); - zend_hash_str_update(Z_ARRVAL_P(return_value), prop_name, prop_len, value); + zend_hash_str_add_new(Z_ARRVAL_P(return_value), prop_name, prop_len, value); } else { - zend_hash_update(Z_ARRVAL_P(return_value), key, value); + zend_hash_add_new(Z_ARRVAL_P(return_value), key, value); } } } @@ -1063,7 +1063,7 @@ ZEND_FUNCTION(get_class_methods) if (!key) { // TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? ZVAL_STR(&method_name, STR_DUP(mptr->common.function_name, 0)); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &method_name); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); } else if ((mptr->common.fn_flags & ZEND_ACC_CTOR) == 0 || mptr->common.scope == ce || zend_binary_strcasecmp(key->val, key->len, mptr->common.function_name->val, len) == 0) { @@ -1073,11 +1073,11 @@ ZEND_FUNCTION(get_class_methods) (len != key->len || !same_name(key->val, mptr->common.function_name->val, len))) { ZVAL_STR(&method_name, STR_COPY(zend_find_alias_name(mptr->common.scope, key))); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &method_name); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); } else { // TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? ZVAL_STR(&method_name, STR_DUP(mptr->common.function_name, 0)); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &method_name); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &method_name); } } } @@ -1693,7 +1693,7 @@ ZEND_FUNCTION(get_defined_functions) zend_hash_apply_with_arguments(EG(function_table) TSRMLS_CC, copy_function_name, 2, &internal, &user); - ret = zend_hash_str_add(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal); + ret = zend_hash_str_add_new(Z_ARRVAL_P(return_value), "internal", sizeof("internal")-1, &internal); if (!ret) { zval_ptr_dtor(&internal); @@ -1703,7 +1703,7 @@ ZEND_FUNCTION(get_defined_functions) RETURN_FALSE; } - ret = zend_hash_str_add(Z_ARRVAL_P(return_value), "user", sizeof("user")-1, &user); + ret = zend_hash_str_add_new(Z_ARRVAL_P(return_value), "user", sizeof("user")-1, &user); if (!ret) { zval_ptr_dtor(&user); zval_dtor(return_value); @@ -1862,7 +1862,7 @@ static int add_constant_info(zval *item, void *arg TSRMLS_DC) } ZVAL_DUP(&const_val, &constant->value); - zend_hash_update(Z_ARRVAL_P(name_array), constant->name, &const_val); + zend_hash_add_new(Z_ARRVAL_P(name_array), constant->name, &const_val); return 0; } @@ -1942,7 +1942,7 @@ ZEND_FUNCTION(get_defined_constants) ZVAL_DUP_DEREF(&const_val, &val->value); - zend_hash_update(Z_ARRVAL(modules[module_number]), val->name, &const_val); + zend_hash_add_new(Z_ARRVAL(modules[module_number]), val->name, &const_val); } ZEND_HASH_FOREACH_END(); efree(module_names); diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index fa0e4634f3..b360e6d75b 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1081,7 +1081,7 @@ str_index: zend_error(E_NOTICE,"Undefined index: %s", offset_key->val); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(ht, offset_key, &EG(uninitialized_zval)); + retval = zend_hash_add_new(ht, offset_key, &EG(uninitialized_zval)); break; } } diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 14f6a47ab3..f0f856d670 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -1607,7 +1607,7 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */ zval zv; ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i)); - zend_hash_update(&EG(active_symbol_table)->ht, + zend_hash_add_new(&EG(active_symbol_table)->ht, ex->op_array->vars[i], &zv); } } diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index b598b8efb1..5bf3e42b4e 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -244,7 +244,7 @@ static zend_always_inline Bucket *zend_hash_index_find_bucket(const HashTable *h return NULL; } -ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC) +static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC) { ulong h; uint nIndex; @@ -262,26 +262,29 @@ ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *p } h = STR_HASH_VAL(key); - p = zend_hash_find_bucket(ht, key); - if (p) { - zval *data; + if ((flag & HASH_ADD_NEW) == 0) { + p = zend_hash_find_bucket(ht, key); - if (flag & HASH_ADD) { - return NULL; - } - ZEND_ASSERT(&p->val != pData); - data = &p->val; - if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) { - data = Z_INDIRECT_P(data); - } - HANDLE_BLOCK_INTERRUPTIONS(); - if (ht->pDestructor) { - ht->pDestructor(data); + if (p) { + zval *data; + + if (flag & HASH_ADD) { + return NULL; + } + ZEND_ASSERT(&p->val != pData); + data = &p->val; + if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) { + data = Z_INDIRECT_P(data); + } + HANDLE_BLOCK_INTERRUPTIONS(); + if (ht->pDestructor) { + ht->pDestructor(data); + } + ZVAL_COPY_VALUE(data, pData); + HANDLE_UNBLOCK_INTERRUPTIONS(); + return data; } - ZVAL_COPY_VALUE(data, pData); - HANDLE_UNBLOCK_INTERRUPTIONS(); - return data; } ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ @@ -305,10 +308,67 @@ ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *p return &p->val; } +ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC) +{ + return _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_add(HashTable *ht, zend_string *key, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_update(HashTable *ht, zend_string *key, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_update_ind(HashTable *ht, zend_string *key, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC); +} + ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *str, int len, zval *pData, int flag ZEND_FILE_LINE_DC) { zend_string *key = STR_INIT(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); - zval *ret = _zend_hash_add_or_update(ht, key, pData, flag ZEND_FILE_LINE_CC); + zval *ret = _zend_hash_add_or_update_i(ht, key, pData, flag ZEND_FILE_LINE_CC); + STR_RELEASE(key); + return ret; +} + +ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zend_string *key = STR_INIT(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); + zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC); + STR_RELEASE(key); + return ret; +} + +ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zend_string *key = STR_INIT(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); + zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC); + STR_RELEASE(key); + return ret; +} + +ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zend_string *key = STR_INIT(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); + zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC); + STR_RELEASE(key); + return ret; +} + +ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *str, int len, zval *pData ZEND_FILE_LINE_DC) +{ + zend_string *key = STR_INIT(str, len, ht->u.flags & HASH_FLAG_PERSISTENT); + zval *ret = _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW ZEND_FILE_LINE_CC); STR_RELEASE(key); return ret; } @@ -340,7 +400,7 @@ ZEND_API zval *zend_hash_str_add_empty_element(HashTable *ht, const char *str, i return zend_hash_str_add(ht, str, len, &dummy); } -ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC) +static zend_always_inline zval *_zend_hash_index_update_or_next_insert_i(HashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC) { uint nIndex; uint idx; @@ -415,22 +475,24 @@ convert_to_hash: } } - p = zend_hash_index_find_bucket(ht, h); - if (p) { - if (flag & (HASH_NEXT_INSERT | HASH_ADD)) { - return NULL; - } - ZEND_ASSERT(&p->val != pData); - HANDLE_BLOCK_INTERRUPTIONS(); - if (ht->pDestructor) { - ht->pDestructor(&p->val); - } - ZVAL_COPY_VALUE(&p->val, pData); - HANDLE_UNBLOCK_INTERRUPTIONS(); - if ((long)h >= (long)ht->nNextFreeElement) { - ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX; + if ((flag & HASH_ADD_NEW) == 0) { + p = zend_hash_index_find_bucket(ht, h); + if (p) { + if (flag & (HASH_NEXT_INSERT | HASH_ADD)) { + return NULL; + } + ZEND_ASSERT(&p->val != pData); + HANDLE_BLOCK_INTERRUPTIONS(); + if (ht->pDestructor) { + ht->pDestructor(&p->val); + } + ZVAL_COPY_VALUE(&p->val, pData); + HANDLE_UNBLOCK_INTERRUPTIONS(); + if ((long)h >= (long)ht->nNextFreeElement) { + ht->nNextFreeElement = h < LONG_MAX ? h + 1 : LONG_MAX; + } + return &p->val; } - return &p->val; } ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ @@ -456,6 +518,35 @@ convert_to_hash: return &p->val; } +ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, h, pData, flag ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_index_add(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_ADD ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_index_add_new(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_ADD | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_index_update(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, ht->nNextFreeElement, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_RELAY_CC); +} + +ZEND_API zval *_zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_FILE_LINE_DC) +{ + return _zend_hash_index_update_or_next_insert_i(ht, ht->nNextFreeElement, pData, HASH_NEXT_INSERT | HASH_ADD_NEW ZEND_FILE_LINE_RELAY_CC); +} static void zend_hash_do_resize(HashTable *ht) { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 04fc311a52..da0433a6c9 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -34,6 +34,7 @@ #define HASH_ADD (1<<1) #define HASH_NEXT_INSERT (1<<2) #define HASH_UPDATE_INDIRECT (1<<3) +#define HASH_ADD_NEW (1<<4) #define INVALID_IDX ((uint)-1) @@ -68,28 +69,52 @@ ZEND_API void zend_hash_to_packed(HashTable *ht); /* additions/updates/changes */ ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_update(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_update_ind(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_add(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_add_new(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC); + #define zend_hash_update(ht, key, pData) \ - _zend_hash_add_or_update(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC) + _zend_hash_update(ht, key, pData ZEND_FILE_LINE_CC) #define zend_hash_update_ind(ht, key, pData) \ - _zend_hash_add_or_update(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC) + _zend_hash_update_ind(ht, key, pData ZEND_FILE_LINE_CC) #define zend_hash_add(ht, key, pData) \ - _zend_hash_add_or_update(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC) + _zend_hash_add(ht, key, pData ZEND_FILE_LINE_CC) +#define zend_hash_add_new(ht, key, pData) \ + _zend_hash_add_new(ht, key, pData ZEND_FILE_LINE_CC) ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, int len, zval *pData, int flag ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_str_update(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_str_update_ind(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_str_add(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_str_add_new(HashTable *ht, const char *key, int len, zval *pData ZEND_FILE_LINE_DC); + #define zend_hash_str_update(ht, key, len, pData) \ - _zend_hash_str_add_or_update(ht, key, len, pData, HASH_UPDATE ZEND_FILE_LINE_CC) + _zend_hash_str_update(ht, key, len, pData ZEND_FILE_LINE_CC) #define zend_hash_str_update_ind(ht, key, len, pData) \ - _zend_hash_str_add_or_update(ht, key, len, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC) + _zend_hash_str_update_ind(ht, key, len, pData ZEND_FILE_LINE_CC) #define zend_hash_str_add(ht, key, len, pData) \ - _zend_hash_str_add_or_update(ht, key, len, pData, HASH_ADD ZEND_FILE_LINE_CC) + _zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC) +#define zend_hash_str_add_new(ht, key, len, pData) \ + _zend_hash_str_add_new(ht, key, len, pData ZEND_FILE_LINE_CC) ZEND_API zval *_zend_hash_index_update_or_next_insert(HashTable *ht, ulong h, zval *pData, int flag ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_index_add(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_index_add_new(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_index_update(HashTable *ht, ulong h, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC); +ZEND_API zval *_zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_FILE_LINE_DC); + #define zend_hash_index_add(ht, h, pData) \ - _zend_hash_index_update_or_next_insert(ht, h, pData, HASH_ADD ZEND_FILE_LINE_CC) + _zend_hash_index_add(ht, h, pData ZEND_FILE_LINE_CC) +#define zend_hash_index_add_new(ht, h, pData) \ + _zend_hash_index_add_new(ht, h, pData ZEND_FILE_LINE_CC) #define zend_hash_index_update(ht, h, pData) \ - _zend_hash_index_update_or_next_insert(ht, h, pData, HASH_UPDATE ZEND_FILE_LINE_CC) + _zend_hash_index_update(ht, h, pData ZEND_FILE_LINE_CC) #define zend_hash_next_index_insert(ht, pData) \ - _zend_hash_index_update_or_next_insert(ht, 0, pData, HASH_NEXT_INSERT ZEND_FILE_LINE_CC) + _zend_hash_next_index_insert(ht, pData ZEND_FILE_LINE_CC) +#define zend_hash_next_index_insert_new(ht, pData) \ + _zend_hash_next_index_insert_new(ht, pData ZEND_FILE_LINE_CC) ZEND_API zval *zend_hash_index_add_empty_element(HashTable *ht, ulong h); ZEND_API zval *zend_hash_add_empty_element(HashTable *ht, zend_string *key); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 5dff0d9f50..d5f2096277 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -450,7 +450,7 @@ static long *zend_get_property_guard(zend_object *zobj, zend_property_info *prop } ZVAL_LONG(&stub, 0); - guard = zend_hash_add(zobj->guards, property_info->name, &stub); + guard = zend_hash_add_new(zobj->guards, property_info->name, &stub); if (str) { STR_RELEASE(str); } diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index f90412ac45..2ab70e8fa1 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -728,7 +728,7 @@ ZEND_API void convert_to_object(zval *op) /* {{{ */ zval tmp; ZVAL_COPY_VALUE(&tmp, op); object_init(op); - zend_hash_str_update(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &tmp); + zend_hash_str_add_new(Z_OBJPROP_P(op), "scalar", sizeof("scalar")-1, &tmp); break; } } diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index ac65d9d18c..79bd00db13 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -321,7 +321,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args, ZVAL_NULL(&tmp); if (is_ref) { ZVAL_NEW_REF(&tmp, &tmp); - zend_hash_add(&EG(active_symbol_table)->ht, key->key, &tmp); + zend_hash_add_new(&EG(active_symbol_table)->ht, 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 7ba615bfef..cba6e77d2b 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1165,7 +1165,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST| zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -3360,13 +3360,13 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC); - zend_hash_next_index_insert(Z_ARRVAL_P(params), param); + zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; } while (++arg_num <= arg_count); } else { do { - zend_hash_next_index_insert(Z_ARRVAL_P(params), param); + zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; } while (++arg_num <= arg_count); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 17f7b6018f..2e7184e30d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -923,13 +923,13 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR if (UNEXPECTED((EX(op_array)->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { zend_verify_arg_type((zend_function *) EX(op_array), arg_num, param, opline->extended_value TSRMLS_CC); - zend_hash_next_index_insert(Z_ARRVAL_P(params), param); + zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; } while (++arg_num <= arg_count); } else { do { - zend_hash_next_index_insert(Z_ARRVAL_P(params), param); + zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; } while (++arg_num <= arg_count); @@ -3591,7 +3591,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -5398,7 +5398,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -6102,7 +6102,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -8749,7 +8749,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -10424,7 +10424,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -11128,7 +11128,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -14573,7 +14573,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -18913,7 +18913,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -20797,7 +20797,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -31476,7 +31476,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -35490,7 +35490,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } @@ -37256,7 +37256,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type, zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname)); /* break missing intentionally */ case BP_VAR_W: - retval = zend_hash_update(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); + retval = zend_hash_add_new(target_symbol_table, Z_STR_P(varname), &EG(uninitialized_zval)); break; EMPTY_SWITCH_DEFAULT_CASE() } diff --git a/ext/standard/array.c b/ext/standard/array.c index 689d083b06..045b80c28b 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -2182,12 +2182,12 @@ PHP_FUNCTION(array_slice) zval_add_ref(entry); if (string_key) { - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry); } else { if (preserve_keys) { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry); } else { - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry); } } } ZEND_HASH_FOREACH_END(); @@ -2199,79 +2199,95 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS zval *src_entry, *dest_entry; zend_string *string_key; - ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) { - if (string_key) { - if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) { - zval *src_zval = src_entry; - zval *dest_zval = dest_entry; - HashTable *thash; - zval tmp; + if (recursive) { + ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) { + if (string_key) { + if ((dest_entry = zend_hash_find(dest, string_key)) != NULL) { + zval *src_zval = src_entry; + zval *dest_zval = dest_entry; + HashTable *thash; + zval tmp; - ZVAL_DEREF(src_zval); - ZVAL_DEREF(dest_zval); - thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; - if ((thash && thash->u.v.nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); - return 0; - } + ZVAL_DEREF(src_zval); + ZVAL_DEREF(dest_zval); + thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; + if ((thash && thash->u.v.nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); + return 0; + } - if (Z_ISREF_P(dest_entry)) { - if (Z_REFCOUNT_P(dest_entry) == 1) { - ZVAL_UNREF(dest_entry); + if (Z_ISREF_P(dest_entry)) { + if (Z_REFCOUNT_P(dest_entry) == 1) { + ZVAL_UNREF(dest_entry); + } else { + Z_DELREF_P(dest_entry); + ZVAL_DUP(dest_entry, dest_zval); + } + dest_zval = dest_entry; } else { - Z_DELREF_P(dest_entry); - ZVAL_DUP(dest_entry, dest_zval); + SEPARATE_ZVAL(dest_zval); } - dest_zval = dest_entry; - } else { - SEPARATE_ZVAL(dest_zval); - } - if (Z_TYPE_P(dest_zval) == IS_NULL) { - convert_to_array_ex(dest_zval); - add_next_index_null(dest_zval); - } else { - convert_to_array_ex(dest_zval); - } - ZVAL_UNDEF(&tmp); - if (Z_TYPE_P(src_zval) == IS_OBJECT) { - ZVAL_DUP(&tmp, src_zval); - convert_to_array(&tmp); - src_zval = &tmp; - } - if (Z_TYPE_P(src_zval) == IS_ARRAY) { - if (thash) { - thash->u.v.nApplyCount++; + if (Z_TYPE_P(dest_zval) == IS_NULL) { + convert_to_array_ex(dest_zval); + add_next_index_null(dest_zval); + } else { + convert_to_array_ex(dest_zval); + } + ZVAL_UNDEF(&tmp); + if (Z_TYPE_P(src_zval) == IS_OBJECT) { + ZVAL_DUP(&tmp, src_zval); + convert_to_array(&tmp); + src_zval = &tmp; } - if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { + if (Z_TYPE_P(src_zval) == IS_ARRAY) { + if (thash) { + thash->u.v.nApplyCount++; + } + if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), 1 TSRMLS_CC)) { + if (thash) { + thash->u.v.nApplyCount--; + } + return 0; + } if (thash) { thash->u.v.nApplyCount--; } - return 0; - } - if (thash) { - thash->u.v.nApplyCount--; + } else { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); } + zval_ptr_dtor(&tmp); } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); + zend_hash_update(dest, string_key, src_entry); } - zval_ptr_dtor(&tmp); } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_update(dest, string_key, src_entry); + zend_hash_next_index_insert_new(dest, src_entry); } - } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); + } ZEND_HASH_FOREACH_END(); + } else { + ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) { + if (string_key) { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + zend_hash_update(dest, string_key, src_entry); + } else { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + zend_hash_next_index_insert_new(dest, src_entry); } - zend_hash_next_index_insert(dest, src_entry); - } - } ZEND_HASH_FOREACH_END(); + } ZEND_HASH_FOREACH_END(); + } return 1; } /* }}} */ @@ -2457,7 +2473,7 @@ PHP_FUNCTION(array_keys) } else { ZVAL_LONG(&new_val, num_idx); } - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &new_val); } } ZEND_HASH_FOREACH_END(); } @@ -2480,7 +2496,7 @@ PHP_FUNCTION(array_values) /* Go through input array and add values to the return array */ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { zval_add_ref(entry); - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry); } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2640,12 +2656,12 @@ PHP_FUNCTION(array_reverse) zval_add_ref(entry); if (string_key) { - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + zend_hash_add_new(Z_ARRVAL_P(return_value), string_key, entry); } else { if (preserve_keys) { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + zend_hash_index_add_new(Z_ARRVAL_P(return_value), num_key, entry); } else { - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), entry); } } } ZEND_HASH_FOREACH_END(); |