diff options
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend_execute.c | 36 | ||||
-rw-r--r-- | Zend/zend_hash.c | 9 | ||||
-rw-r--r-- | Zend/zend_hash.h | 20 |
3 files changed, 47 insertions, 18 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index eb685e8104..53f2362e19 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -1559,24 +1559,24 @@ try_again: if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) { hval = Z_LVAL_P(dim); num_index: - retval = zend_hash_index_find(ht, hval); - if (retval == NULL) { - switch (type) { - case BP_VAR_R: - zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval); - /* break missing intentionally */ - case BP_VAR_UNSET: - case BP_VAR_IS: - retval = &EG(uninitialized_zval); - break; - case BP_VAR_RW: - zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval); - retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval)); - break; - case BP_VAR_W: - retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval)); - break; - } + ZEND_HASH_INDEX_FIND(ht, hval, retval, num_undef); + return retval; +num_undef: + switch (type) { + case BP_VAR_R: + zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval); + /* break missing intentionally */ + case BP_VAR_UNSET: + case BP_VAR_IS: + retval = &EG(uninitialized_zval); + break; + case BP_VAR_RW: + zend_error(E_NOTICE,"Undefined offset: " ZEND_LONG_FMT, hval); + retval = zend_hash_index_update(ht, hval, &EG(uninitialized_zval)); + break; + case BP_VAR_W: + retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval)); + break; } } else if (EXPECTED(Z_TYPE_P(dim) == IS_STRING)) { offset_key = Z_STR_P(dim); diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index e116ffe55e..1e3a9aa69a 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2038,6 +2038,15 @@ ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulon return p ? &p->val : NULL; } +ZEND_API zval* ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h) +{ + Bucket *p; + + IS_CONSISTENT(ht); + + p = zend_hash_index_find_bucket(ht, h); + return p ? &p->val : NULL; +} ZEND_API zend_bool ZEND_FASTCALL zend_hash_index_exists(const HashTable *ht, zend_ulong h) { diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index f18ce5c058..aa5dc24fd2 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -154,6 +154,26 @@ ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p); ZEND_API zval* ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key); ZEND_API zval* ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *key, size_t len); ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h); +ZEND_API zval* ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h); + +#define ZEND_HASH_INDEX_FIND(_ht, _h, _ret, _not_found) do { \ + if (EXPECTED((_ht)->u.flags & HASH_FLAG_PACKED)) { \ + if (EXPECTED((_h) < (_ht)->nNumUsed)) { \ + _ret = &ht->arData[_h].val; \ + if (UNEXPECTED(Z_TYPE_P(_ret) == IS_UNDEF)) { \ + goto _not_found; \ + } \ + } else { \ + goto _not_found; \ + } \ + } else { \ + _ret = _zend_hash_index_find(_ht, _h); \ + if (UNEXPECTED(_ret == NULL)) { \ + goto _not_found; \ + } \ + } \ + } while (0) + /* Misc */ ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_string *key); |