29#define HASH_KEY_IS_STRING 1
30#define HASH_KEY_IS_LONG 2
31#define HASH_KEY_NON_EXISTENT 3
33#define HASH_UPDATE (1<<0)
34#define HASH_ADD (1<<1)
35#define HASH_UPDATE_INDIRECT (1<<2)
36#define HASH_ADD_NEW (1<<3)
37#define HASH_ADD_NEXT (1<<4)
38#define HASH_LOOKUP (1<<5)
40#define HASH_FLAG_CONSISTENCY ((1<<0) | (1<<1))
41#define HASH_FLAG_PACKED (1<<2)
42#define HASH_FLAG_UNINITIALIZED (1<<3)
43#define HASH_FLAG_STATIC_KEYS (1<<4)
44#define HASH_FLAG_HAS_EMPTY_IND (1<<5)
45#define HASH_FLAG_ALLOW_COW_VIOLATION (1<<6)
48#define HASH_FLAG_MASK 0xff
50#define HT_FLAGS(ht) (ht)->u.flags
52#define HT_INVALIDATE(ht) do { \
53 HT_FLAGS(ht) = HASH_FLAG_UNINITIALIZED; \
56#define HT_IS_INITIALIZED(ht) \
57 ((HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) == 0)
59#define HT_IS_PACKED(ht) \
60 ((HT_FLAGS(ht) & HASH_FLAG_PACKED) != 0)
62#define HT_IS_WITHOUT_HOLES(ht) \
63 ((ht)->nNumUsed == (ht)->nNumOfElements)
65#define HT_HAS_STATIC_KEYS_ONLY(ht) \
66 ((HT_FLAGS(ht) & (HASH_FLAG_PACKED|HASH_FLAG_STATIC_KEYS)) != 0)
69# define HT_ALLOW_COW_VIOLATION(ht) HT_FLAGS(ht) |= HASH_FLAG_ALLOW_COW_VIOLATION
71# define HT_ALLOW_COW_VIOLATION(ht)
74#define HT_ITERATORS_COUNT(ht) (ht)->u.v.nIteratorsCount
75#define HT_ITERATORS_OVERFLOW(ht) (HT_ITERATORS_COUNT(ht) == 0xff)
76#define HT_HAS_ITERATORS(ht) (HT_ITERATORS_COUNT(ht) != 0)
78#define HT_SET_ITERATORS_COUNT(ht, iters) \
79 do { HT_ITERATORS_COUNT(ht) = (iters); } while (0)
80#define HT_INC_ITERATORS_COUNT(ht) \
81 HT_SET_ITERATORS_COUNT(ht, HT_ITERATORS_COUNT(ht) + 1)
82#define HT_DEC_ITERATORS_COUNT(ht) \
83 HT_SET_ITERATORS_COUNT(ht, HT_ITERATORS_COUNT(ht) - 1)
87#define ZVAL_EMPTY_ARRAY(z) do { \
89 Z_ARR_P(__z) = (zend_array*)&zend_empty_array; \
90 Z_TYPE_INFO_P(__z) = IS_ARRAY; \
108#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent) \
109 _zend_hash_init((ht), (nSize), (pDestructor), (persistent))
146#define ZEND_HASH_APPLY_KEEP 0
147#define ZEND_HASH_APPLY_REMOVE 1<<0
148#define ZEND_HASH_APPLY_STOP 1<<1
196#define ZEND_HASH_INDEX_FIND(_ht, _h, _ret, _not_found) do { \
197 if (EXPECTED(HT_IS_PACKED(_ht))) { \
198 if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed)) { \
199 _ret = &_ht->arPacked[_h]; \
200 if (UNEXPECTED(Z_TYPE_P(_ret) == IS_UNDEF)) { \
207 _ret = _zend_hash_index_find(_ht, _h); \
208 if (UNEXPECTED(_ret == NULL)) { \
219#define ZEND_HASH_INDEX_LOOKUP(_ht, _h, _ret) do { \
220 if (EXPECTED(HT_IS_PACKED(_ht))) { \
221 if (EXPECTED((zend_ulong)(_h) < (zend_ulong)(_ht)->nNumUsed)) { \
222 _ret = &_ht->arPacked[_h]; \
223 if (EXPECTED(Z_TYPE_P(_ret) != IS_UNDEF)) { \
228 _ret = zend_hash_index_lookup(_ht, _h); \
264 return zend_hash_has_more_elements_ex(
ht, &
ht->nInternalPointer);
317 return ht->nNumOfElements;
321 return ht->nNextFreeElement;
326#if !ZEND_DEBUG && defined(HAVE_BUILTIN_CONSTANT_P)
327# define zend_new_array(size) \
328 (__builtin_constant_p(size) ? \
329 ((((uint32_t)(size)) <= HT_MIN_SIZE) ? \
330 _zend_new_array_0() \
332 _zend_new_array((size)) \
335 _zend_new_array((size)) \
338# define zend_new_array(size) \
339 _zend_new_array(size)
393#define ZEND_INIT_SYMTABLE(ht) \
394 ZEND_INIT_SYMTABLE_EX(ht, 8, 0)
396#define ZEND_INIT_SYMTABLE_EX(ht, n, persistent) \
397 zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
401 const char *tmp =
key;
405 }
else if (*tmp <
'0') {
410 if (*tmp >
'9' || *tmp <
'0') {
417#define ZEND_HANDLE_NUMERIC_STR(key, length, idx) \
418 _zend_handle_numeric_str(key, length, &idx)
420#define ZEND_HANDLE_NUMERIC(key, idx) \
421 ZEND_HANDLE_NUMERIC_STR(ZSTR_VAL(key), ZSTR_LEN(key), idx)
438 zv = zend_hash_find_ex(
ht,
key, known_hash);
551 return zend_hash_find_ind(
ht,
key);
561 return zend_hash_index_exists(
ht, idx);
563 return zend_hash_exists(
ht,
key);
573 return zend_hash_index_exists(
ht, idx);
575 return zend_hash_exists_ind(
ht,
key);
645 return zend_hash_index_exists(
ht, idx);
647 return zend_hash_str_exists(
ht, str,
len);
785 return zend_hash_update_ptr(
ht,
key,
p);
794 return zend_hash_str_update_ptr(
ht, str,
len,
p);
858 return zend_hash_index_update_ptr(
ht, h,
p);
892 zv = zend_hash_find_ex(
ht,
key, known_hash);
971 return zend_hash_index_find_ptr(
ht, idx);
973 return zend_hash_str_find_ptr(
ht, str,
len);
990#define zend_hash_get_current_data_ptr(ht) \
991 zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
995# define ZEND_HASH_ELEMENT_SIZE(__ht) \
996 (HT_IS_PACKED(__ht) ? sizeof(zval) : sizeof(Bucket))
998# define ZEND_HASH_ELEMENT_SIZE(__ht) \
999 (sizeof(zval) + (~HT_FLAGS(__ht) & HASH_FLAG_PACKED) * ((sizeof(Bucket)-sizeof(zval))/HASH_FLAG_PACKED))
1002#define ZEND_HASH_ELEMENT_EX(__ht, _idx, _size) \
1003 ((zval*)(((char*)(__ht)->arPacked) + ((_idx) * (_size))))
1005#define ZEND_HASH_ELEMENT(__ht, _idx) \
1006 ZEND_HASH_ELEMENT_EX(__ht, _idx, ZEND_HASH_ELEMENT_SIZE(__ht))
1008#define ZEND_HASH_NEXT_ELEMENT(_el, _size) \
1009 ((zval*)(((char*)(_el)) + (_size)))
1011#define ZEND_HASH_PREV_ELEMENT(_el, _size) \
1012 ((zval*)(((char*)(_el)) - (_size)))
1014#define _ZEND_HASH_FOREACH_VAL(_ht) do { \
1015 const HashTable *__ht = (_ht); \
1016 uint32_t _count = __ht->nNumUsed; \
1017 size_t _size = ZEND_HASH_ELEMENT_SIZE(__ht); \
1018 zval *_z = __ht->arPacked; \
1019 for (; _count > 0; _z = ZEND_HASH_NEXT_ELEMENT(_z, _size), _count--) { \
1020 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1022#define _ZEND_HASH_REVERSE_FOREACH_VAL(_ht) do { \
1023 const HashTable *__ht = (_ht); \
1024 uint32_t _idx = __ht->nNumUsed; \
1025 size_t _size = ZEND_HASH_ELEMENT_SIZE(__ht); \
1026 zval *_z = ZEND_HASH_ELEMENT_EX(__ht, _idx, _size); \
1027 for (;_idx > 0; _idx--) { \
1028 _z = ZEND_HASH_PREV_ELEMENT(_z, _size); \
1029 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1031#define ZEND_HASH_FOREACH_FROM(_ht, indirect, _from) do { \
1032 const HashTable *__ht = (_ht); \
1034 zend_string *__key = NULL; \
1035 uint32_t _idx = (_from); \
1036 size_t _size = ZEND_HASH_ELEMENT_SIZE(__ht); \
1037 zval *__z = ZEND_HASH_ELEMENT_EX(__ht, _idx, _size); \
1038 uint32_t _count = __ht->nNumUsed - _idx; \
1039 for (;_count > 0; _count--) { \
1041 if (HT_IS_PACKED(__ht)) { \
1046 Bucket *_p = (Bucket*)__z; \
1047 __z = &(_p + 1)->val; \
1050 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
1051 _z = Z_INDIRECT_P(_z); \
1054 (void) __h; (void) __key; (void) _idx; \
1055 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1057#define ZEND_HASH_FOREACH(_ht, indirect) ZEND_HASH_FOREACH_FROM(_ht, indirect, 0)
1059#define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
1060 const HashTable *__ht = (_ht); \
1061 uint32_t _idx = __ht->nNumUsed; \
1064 zend_string *__key = NULL; \
1065 size_t _size = ZEND_HASH_ELEMENT_SIZE(__ht); \
1066 zval *__z = ZEND_HASH_ELEMENT_EX(__ht, _idx, _size); \
1067 for (;_idx > 0; _idx--) { \
1068 if (HT_IS_PACKED(__ht)) { \
1073 Bucket *_p = (Bucket*)__z; \
1079 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
1080 _z = Z_INDIRECT_P(_z); \
1083 (void) __h; (void) __key; (void) __z; \
1084 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1086#define ZEND_HASH_FOREACH_END() \
1090#define ZEND_HASH_FOREACH_END_DEL() \
1091 ZEND_HASH_MAP_FOREACH_END_DEL()
1093#define ZEND_HASH_FOREACH_BUCKET(ht, _bucket) \
1094 ZEND_HASH_MAP_FOREACH_BUCKET(ht, _bucket)
1096#define ZEND_HASH_FOREACH_BUCKET_FROM(ht, _bucket, _from) \
1097 ZEND_HASH_MAP_FOREACH_BUCKET_FROM(ht, _bucket, _from)
1099#define ZEND_HASH_REVERSE_FOREACH_BUCKET(ht, _bucket) \
1100 ZEND_HASH_MAP_REVERSE_FOREACH_BUCKET(ht, _bucket)
1102#define ZEND_HASH_FOREACH_VAL(ht, _val) \
1103 _ZEND_HASH_FOREACH_VAL(ht); \
1106#define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val) \
1107 _ZEND_HASH_REVERSE_FOREACH_VAL(ht); \
1110#define ZEND_HASH_FOREACH_VAL_IND(ht, _val) \
1111 ZEND_HASH_FOREACH(ht, 1); \
1114#define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val) \
1115 ZEND_HASH_REVERSE_FOREACH(ht, 1); \
1118#define ZEND_HASH_FOREACH_PTR(ht, _ptr) \
1119 _ZEND_HASH_FOREACH_VAL(ht); \
1122#define ZEND_HASH_FOREACH_PTR_FROM(ht, _ptr, _from) \
1123 ZEND_HASH_FOREACH_FROM(ht, 0, _from); \
1126#define ZEND_HASH_REVERSE_FOREACH_PTR(ht, _ptr) \
1127 _ZEND_HASH_REVERSE_FOREACH_VAL(ht); \
1130#define ZEND_HASH_FOREACH_NUM_KEY(ht, _h) \
1131 ZEND_HASH_FOREACH(ht, 0); \
1134#define ZEND_HASH_REVERSE_FOREACH_NUM_KEY(ht, _h) \
1135 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1138#define ZEND_HASH_FOREACH_STR_KEY(ht, _key) \
1139 ZEND_HASH_FOREACH(ht, 0); \
1142#define ZEND_HASH_REVERSE_FOREACH_STR_KEY(ht, _key) \
1143 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1146#define ZEND_HASH_FOREACH_KEY(ht, _h, _key) \
1147 ZEND_HASH_FOREACH(ht, 0); \
1151#define ZEND_HASH_REVERSE_FOREACH_KEY(ht, _h, _key) \
1152 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1156#define ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, _h, _val) \
1157 ZEND_HASH_FOREACH(ht, 0); \
1161#define ZEND_HASH_REVERSE_FOREACH_NUM_KEY_VAL(ht, _h, _val) \
1162 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1166#define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val) \
1167 ZEND_HASH_FOREACH(ht, 0); \
1171#define ZEND_HASH_FOREACH_STR_KEY_VAL_FROM(ht, _key, _val, _from) \
1172 ZEND_HASH_FOREACH_FROM(ht, 0, _from); \
1176#define ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(ht, _key, _val) \
1177 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1181#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
1182 ZEND_HASH_FOREACH(ht, 0); \
1187#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
1188 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1193#define ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
1194 ZEND_HASH_FOREACH(ht, 1); \
1198#define ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
1199 ZEND_HASH_REVERSE_FOREACH(ht, 1); \
1203#define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
1204 ZEND_HASH_FOREACH(ht, 1); \
1209#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
1210 ZEND_HASH_REVERSE_FOREACH(ht, 1); \
1215#define ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
1216 ZEND_HASH_FOREACH(ht, 0); \
1220#define ZEND_HASH_REVERSE_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
1221 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1225#define ZEND_HASH_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
1226 ZEND_HASH_FOREACH(ht, 0); \
1230#define ZEND_HASH_REVERSE_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
1231 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1235#define ZEND_HASH_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
1236 ZEND_HASH_FOREACH(ht, 0); \
1241#define ZEND_HASH_REVERSE_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
1242 ZEND_HASH_REVERSE_FOREACH(ht, 0); \
1248#define ZEND_HASH_MAP_FOREACH_FROM(_ht, indirect, _from) do { \
1249 const HashTable *__ht = (_ht); \
1250 Bucket *_p = __ht->arData + (_from); \
1251 const Bucket *_end = __ht->arData + __ht->nNumUsed; \
1252 ZEND_ASSERT(!HT_IS_PACKED(__ht)); \
1253 for (; _p != _end; _p++) { \
1254 zval *_z = &_p->val; \
1255 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
1256 _z = Z_INDIRECT_P(_z); \
1258 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1260#define ZEND_HASH_MAP_FOREACH(_ht, indirect) ZEND_HASH_MAP_FOREACH_FROM(_ht, indirect, 0)
1262#define ZEND_HASH_MAP_REVERSE_FOREACH(_ht, indirect) do { \
1263 HashTable *__ht = (_ht); \
1264 uint32_t _idx = __ht->nNumUsed; \
1265 Bucket *_p = __ht->arData + _idx; \
1267 ZEND_ASSERT(!HT_IS_PACKED(__ht)); \
1268 for (_idx = __ht->nNumUsed; _idx > 0; _idx--) { \
1271 if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
1272 _z = Z_INDIRECT_P(_z); \
1274 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1276#define ZEND_HASH_MAP_FOREACH_END_DEL() \
1277 ZEND_ASSERT(!HT_IS_PACKED(__ht)); \
1278 __ht->nNumOfElements--; \
1280 uint32_t j = HT_IDX_TO_HASH(_idx - 1); \
1281 uint32_t nIndex = _p->h | __ht->nTableMask; \
1282 uint32_t i = HT_HASH(__ht, nIndex); \
1283 if (UNEXPECTED(j != i)) { \
1284 Bucket *prev = HT_HASH_TO_BUCKET(__ht, i); \
1285 while (Z_NEXT(prev->val) != j) { \
1286 i = Z_NEXT(prev->val); \
1287 prev = HT_HASH_TO_BUCKET(__ht, i); \
1289 Z_NEXT(prev->val) = Z_NEXT(_p->val); \
1291 HT_HASH(__ht, nIndex) = Z_NEXT(_p->val); \
1295 __ht->nNumUsed = _idx; \
1298#define ZEND_HASH_MAP_FOREACH_BUCKET(ht, _bucket) \
1299 ZEND_HASH_MAP_FOREACH(ht, 0); \
1302#define ZEND_HASH_MAP_FOREACH_BUCKET_FROM(ht, _bucket, _from) \
1303 ZEND_HASH_MAP_FOREACH_FROM(ht, 0, _from); \
1306#define ZEND_HASH_MAP_REVERSE_FOREACH_BUCKET(ht, _bucket) \
1307 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1310#define ZEND_HASH_MAP_FOREACH_VAL(ht, _val) \
1311 ZEND_HASH_MAP_FOREACH(ht, 0); \
1314#define ZEND_HASH_MAP_REVERSE_FOREACH_VAL(ht, _val) \
1315 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1318#define ZEND_HASH_MAP_FOREACH_VAL_IND(ht, _val) \
1319 ZEND_HASH_MAP_FOREACH(ht, 1); \
1322#define ZEND_HASH_MAP_REVERSE_FOREACH_VAL_IND(ht, _val) \
1323 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 1); \
1326#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr) \
1327 ZEND_HASH_MAP_FOREACH(ht, 0); \
1330#define ZEND_HASH_MAP_FOREACH_PTR_FROM(ht, _ptr, _from) \
1331 ZEND_HASH_MAP_FOREACH_FROM(ht, 0, _from); \
1334#define ZEND_HASH_MAP_REVERSE_FOREACH_PTR(ht, _ptr) \
1335 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1338#define ZEND_HASH_MAP_FOREACH_NUM_KEY(ht, _h) \
1339 ZEND_HASH_MAP_FOREACH(ht, 0); \
1342#define ZEND_HASH_MAP_REVERSE_FOREACH_NUM_KEY(ht, _h) \
1343 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1346#define ZEND_HASH_MAP_FOREACH_STR_KEY(ht, _key) \
1347 ZEND_HASH_MAP_FOREACH(ht, 0); \
1350#define ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY(ht, _key) \
1351 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1354#define ZEND_HASH_MAP_FOREACH_KEY(ht, _h, _key) \
1355 ZEND_HASH_MAP_FOREACH(ht, 0); \
1359#define ZEND_HASH_MAP_REVERSE_FOREACH_KEY(ht, _h, _key) \
1360 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1364#define ZEND_HASH_MAP_FOREACH_NUM_KEY_VAL(ht, _h, _val) \
1365 ZEND_HASH_MAP_FOREACH(ht, 0); \
1369#define ZEND_HASH_MAP_REVERSE_FOREACH_NUM_KEY_VAL(ht, _h, _val) \
1370 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1374#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, _key, _val) \
1375 ZEND_HASH_MAP_FOREACH(ht, 0); \
1379#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_FROM(ht, _key, _val, _from) \
1380 ZEND_HASH_MAP_FOREACH_FROM(ht, 0, _from); \
1384#define ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL(ht, _key, _val) \
1385 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1389#define ZEND_HASH_MAP_FOREACH_KEY_VAL(ht, _h, _key, _val) \
1390 ZEND_HASH_MAP_FOREACH(ht, 0); \
1395#define ZEND_HASH_MAP_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
1396 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1401#define ZEND_HASH_MAP_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
1402 ZEND_HASH_MAP_FOREACH(ht, 1); \
1406#define ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
1407 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 1); \
1411#define ZEND_HASH_MAP_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
1412 ZEND_HASH_MAP_FOREACH(ht, 1); \
1417#define ZEND_HASH_MAP_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
1418 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 1); \
1423#define ZEND_HASH_MAP_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
1424 ZEND_HASH_MAP_FOREACH(ht, 0); \
1428#define ZEND_HASH_MAP_REVERSE_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
1429 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1433#define ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
1434 ZEND_HASH_MAP_FOREACH(ht, 0); \
1438#define ZEND_HASH_MAP_REVERSE_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
1439 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1443#define ZEND_HASH_MAP_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
1444 ZEND_HASH_MAP_FOREACH(ht, 0); \
1449#define ZEND_HASH_MAP_REVERSE_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
1450 ZEND_HASH_MAP_REVERSE_FOREACH(ht, 0); \
1456#define ZEND_HASH_PACKED_FOREACH_FROM(_ht, _from) do { \
1457 const HashTable *__ht = (_ht); \
1458 zend_ulong _idx = (_from); \
1459 zval *_z = __ht->arPacked + (_from); \
1460 zval *_end = __ht->arPacked + __ht->nNumUsed; \
1461 ZEND_ASSERT(HT_IS_PACKED(__ht)); \
1462 for (;_z != _end; _z++, _idx++) { \
1464 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1466#define ZEND_HASH_PACKED_FOREACH(_ht) ZEND_HASH_PACKED_FOREACH_FROM(_ht, 0)
1468#define ZEND_HASH_PACKED_REVERSE_FOREACH(_ht) do { \
1469 const HashTable *__ht = (_ht); \
1470 zend_ulong _idx = __ht->nNumUsed; \
1471 zval *_z = __ht->arPacked + _idx; \
1472 ZEND_ASSERT(HT_IS_PACKED(__ht)); \
1473 while (_idx > 0) { \
1477 if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
1479#define ZEND_HASH_PACKED_FOREACH_VAL(ht, _val) \
1480 ZEND_HASH_PACKED_FOREACH(ht); \
1483#define ZEND_HASH_PACKED_REVERSE_FOREACH_VAL(ht, _val) \
1484 ZEND_HASH_PACKED_REVERSE_FOREACH(ht); \
1487#define ZEND_HASH_PACKED_FOREACH_PTR(ht, _ptr) \
1488 ZEND_HASH_PACKED_FOREACH(ht); \
1491#define ZEND_HASH_PACKED_REVERSE_FOREACH_PTR(ht, _ptr) \
1492 ZEND_HASH_PACKED_REVERSE_FOREACH(ht); \
1495#define ZEND_HASH_PACKED_FOREACH_KEY(ht, _h) \
1496 ZEND_HASH_PACKED_FOREACH(ht); \
1499#define ZEND_HASH_PACKED_REVERSE_FOREACH_KEY(ht, _h) \
1500 ZEND_HASH_PACKED_REVERSE_FOREACH(ht); \
1503#define ZEND_HASH_PACKED_FOREACH_KEY_VAL(ht, _h, _val) \
1504 ZEND_HASH_PACKED_FOREACH(ht); \
1508#define ZEND_HASH_PACKED_REVERSE_FOREACH_KEY_VAL(ht, _h, _val) \
1509 ZEND_HASH_PACKED_REVERSE_FOREACH(ht); \
1513#define ZEND_HASH_PACKED_FOREACH_KEY_PTR(ht, _h, _ptr) \
1514 ZEND_HASH_PACKED_FOREACH(ht); \
1518#define ZEND_HASH_PACKED_REVERSE_FOREACH_KEY_PTR(ht, _h, _ptr) \
1519 ZEND_HASH_PACKED_REVERSE_FOREACH(ht); \
1528#define ZEND_HASH_FILL_PACKED(ht) do { \
1529 HashTable *__fill_ht = (ht); \
1530 zval *__fill_val = __fill_ht->arPacked + __fill_ht->nNumUsed; \
1531 uint32_t __fill_idx = __fill_ht->nNumUsed; \
1532 ZEND_ASSERT(HT_IS_PACKED(__fill_ht));
1534#define ZEND_HASH_FILL_GROW() do { \
1535 if (UNEXPECTED(__fill_idx >= __fill_ht->nTableSize)) { \
1536 __fill_ht->nNumOfElements += __fill_idx - __fill_ht->nNumUsed; \
1537 __fill_ht->nNumUsed = __fill_idx; \
1538 __fill_ht->nNextFreeElement = __fill_idx; \
1539 zend_hash_packed_grow(__fill_ht); \
1540 __fill_val = __fill_ht->arPacked + __fill_idx; \
1544#define ZEND_HASH_FILL_SET(_val) \
1545 ZVAL_COPY_VALUE(__fill_val, _val)
1547#define ZEND_HASH_FILL_SET_NULL() \
1548 ZVAL_NULL(__fill_val)
1550#define ZEND_HASH_FILL_SET_LONG(_val) \
1551 ZVAL_LONG(__fill_val, _val)
1553#define ZEND_HASH_FILL_SET_DOUBLE(_val) \
1554 ZVAL_DOUBLE(__fill_val, _val)
1556#define ZEND_HASH_FILL_SET_STR(_val) \
1557 ZVAL_STR(__fill_val, _val)
1559#define ZEND_HASH_FILL_SET_STR_COPY(_val) \
1560 ZVAL_STR_COPY(__fill_val, _val)
1562#define ZEND_HASH_FILL_SET_INTERNED_STR(_val) \
1563 ZVAL_INTERNED_STR(__fill_val, _val)
1565#define ZEND_HASH_FILL_NEXT() do {\
1570#define ZEND_HASH_FILL_ADD(_val) do { \
1571 ZEND_HASH_FILL_SET(_val); \
1572 ZEND_HASH_FILL_NEXT(); \
1575#define ZEND_HASH_FILL_FINISH() do { \
1576 __fill_ht->nNumOfElements += __fill_idx - __fill_ht->nNumUsed; \
1577 __fill_ht->nNumUsed = __fill_idx; \
1578 __fill_ht->nNextFreeElement = __fill_idx; \
1579 __fill_ht->nInternalPointer = 0; \
1582#define ZEND_HASH_FILL_END() \
1583 ZEND_HASH_FILL_FINISH(); \
1593 if (zend_hash_num_elements(array) == 0) {
1604 if (num_idx != expected_idx++) {
1611 if (str_idx !=
NULL || num_idx != expected_idx++) {
1623 uint32_t idx =
ht->nNumUsed++;
1630 zend_string_addref(
key);
1631 zend_string_hash_val(
key);
1635 nIndex = (uint32_t)
p->h |
ht->nTableMask;
1637 HT_HASH(
ht, nIndex) = HT_IDX_TO_HASH(idx);
1638 ht->nNumOfElements++;
1644 return _zend_hash_append_ex(
ht,
key,
zv, 0);
1649 uint32_t idx =
ht->nNumUsed++;
1656 zend_string_addref(
key);
1657 zend_string_hash_val(
key);
1661 nIndex = (uint32_t)
p->h |
ht->nTableMask;
1663 HT_HASH(
ht, nIndex) = HT_IDX_TO_HASH(idx);
1664 ht->nNumOfElements++;
1670 return _zend_hash_append_ptr_ex(
ht,
key,
ptr, 0);
1675 uint32_t idx =
ht->nNumUsed++;
1682 zend_string_addref(
key);
1683 zend_string_hash_val(
key);
1687 nIndex = (uint32_t)
p->h |
ht->nTableMask;
1689 HT_HASH(
ht, nIndex) = HT_IDX_TO_HASH(idx);
1690 ht->nNumOfElements++;
unsigned const char * pos
collator_compare_func_t compare_func
unsigned char key[REFLECTION_KEY_LEN]
#define zend_hash_str_add(...)
#define pefree(ptr, persistent)
#define pemalloc(size, persistent)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API void * zend_hash_str_find_ptr_lc(const HashTable *ht, const char *str, size_t len)
ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, bool persistent)
ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht)
ZEND_API void * zend_hash_find_ptr_lc(const HashTable *ht, zend_string *key)
ZEND_API const HashTable zend_empty_array
int(* apply_func_arg_t)(zval *pDest, void *argument)
ZEND_API void zend_hash_bucket_renum_swap(Bucket *p, Bucket *q)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_func)
ZEND_API HashTable *ZEND_FASTCALL zend_proptable_to_symtable(HashTable *ht, bool always_duplicate)
ZEND_API HashTable *ZEND_FASTCALL _zend_new_array_0(void)
ZEND_API void zend_hash_bucket_swap(Bucket *p, Bucket *q)
ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht)
ZEND_API HashTable *ZEND_FASTCALL zend_symtable_to_proptable(HashTable *ht)
ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del_ind(HashTable *ht, const char *key, size_t len)
ZEND_API void ZEND_FASTCALL zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func)
ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *)
ZEND_API void ZEND_FASTCALL zend_hash_real_init_packed(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h)
#define HASH_KEY_NON_EXISTENT
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_new(HashTable *ht, const char *key, size_t len, zval *pData)
ZEND_API HashTable * zend_array_to_list(HashTable *source)
ZEND_API uint32_t zend_array_count(HashTable *ht)
struct _zend_hash_key zend_hash_key
ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos)
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos)
ZEND_API void zend_hash_bucket_packed_swap(Bucket *p, Bucket *q)
ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht)
#define ZEND_HASH_MAP_FOREACH_KEY(ht, _h, _key)
#define HT_IS_WITHOUT_HOLES(ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert(HashTable *ht, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, bool packed)
ZEND_API void ZEND_FASTCALL zend_hash_iterators_advance(HashTable *ht, HashPosition step)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_lookup(HashTable *ht, zend_ulong h)
bool(* merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam)
ZEND_API zval *ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_empty_element(HashTable *ht, const char *key, size_t len)
int(* apply_func_args_t)(zval *pDest, int num_args, va_list args, zend_hash_key *hash_key)
int(* bucket_compare_func_t)(Bucket *a, Bucket *b)
ZEND_API zval *ZEND_FASTCALL zend_hash_lookup(HashTable *ht, zend_string *key)
ZEND_API void ZEND_FASTCALL zend_hash_graceful_destroy(HashTable *ht)
#define ZEND_HASH_PACKED_FOREACH_KEY(ht, _h)
ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, bool ordered)
ZEND_API void ZEND_FASTCALL zend_hash_packed_del_val(HashTable *ht, zval *zv)
ZEND_API void ZEND_FASTCALL zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, bool overwrite)
ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zend_result ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h)
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_find_known_hash(const HashTable *ht, const zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update_ind(HashTable *ht, const char *key, size_t len, zval *pData)
#define HASH_FLAG_STATIC_KEYS
ZEND_API zval *ZEND_FASTCALL zend_hash_update_ind(HashTable *ht, zend_string *key, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_graceful_reverse_destroy(HashTable *ht)
ZEND_API zend_result ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, const HashPosition *pos)
ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTable *ht)
ZEND_API void zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int,...)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_to_packed(HashTable *ht)
ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool packed)
ZEND_API zend_result ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *key, size_t len)
ZEND_API zend_result ZEND_FASTCALL zend_hash_del_ind(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 bool ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx)
#define HT_HAS_ITERATORS(ht)
ZEND_API void ZEND_FASTCALL zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor)
ZEND_API zval *ZEND_FASTCALL zend_hash_set_bucket_key(HashTable *ht, Bucket *p, zend_string *key)
#define ZEND_HANDLE_NUMERIC_STR(key, length, idx)
ZEND_API HashTable *ZEND_FASTCALL zend_new_pair(zval *val1, zval *val2)
ZEND_API void ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber)
#define ZEND_HANDLE_NUMERIC(key, idx)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag)
ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht)
ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval *array)
ZEND_API void ZEND_FASTCALL zend_hash_merge_ex(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_update(HashTable *ht, const char *key, size_t len, zval *pData)
ZEND_API HashTable *ZEND_FASTCALL zend_array_dup(HashTable *source)
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos_ex(const HashTable *ht, HashPosition pos)
void ZEND_FASTCALL zend_array_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber)
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
ZEND_API void ZEND_FASTCALL zend_hash_real_init_mixed(HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key)
ZEND_API zend_result ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key)
ZEND_API zval *ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key)
int(* apply_func_t)(zval *pDest)
ZEND_API zval *ZEND_FASTCALL _zend_hash_index_find(const HashTable *ht, zend_ulong h)
ZEND_API zval *ZEND_FASTCALL zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
#define ZEND_HASH_FOREACH_END()
ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start)
ZEND_API void ZEND_FASTCALL zend_hash_discard(HashTable *ht, uint32_t nNumUsed)
ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
ZEND_API zval *ZEND_FASTCALL zend_hash_str_add_or_update(HashTable *ht, const char *key, size_t len, zval *pData, uint32_t flag)
ZEND_API HashPosition ZEND_FASTCALL zend_hash_get_current_pos(const HashTable *ht)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_or_update(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag)
ZEND_API void ZEND_FASTCALL _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
ZEND_API HashTable *ZEND_FASTCALL _zend_new_array(uint32_t size)
struct _zend_string zend_string
#define EXPECTED(condition)
#define zend_always_inline
#define UNEXPECTED(condition)
struct _zend_array zend_array
ZEND_API void zend_sort(void *base, size_t nmemb, size_t siz, compare_func_t cmp, swap_func_t swp)
#define ZSTR_IS_INTERNED(s)
int(* compare_func_t)(const void *, const void *)
#define ZVAL_INDIRECT(z, v)
struct _zend_array HashTable
void(* sort_func_t)(void *, size_t, size_t, compare_func_t, swap_func_t)
void(* dtor_func_t)(zval *pDest)
void(* copy_ctor_func_t)(zval *pElement)
#define Z_INDIRECT_P(zval_p)
ZEND_RESULT_CODE zend_result
#define IS_ARRAY_IMMUTABLE
#define IS_ARRAY_PERSISTENT
#define ZVAL_COPY_VALUE(z, v)