summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend_execute.c36
-rw-r--r--Zend/zend_hash.c9
-rw-r--r--Zend/zend_hash.h20
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);