root/Zend/zend_hash.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. zend_hash_iterators_update
  2. _zend_handle_numeric_str
  3. zend_hash_find_ind
  4. zend_hash_exists_ind
  5. zend_hash_str_find_ind
  6. zend_symtable_update
  7. zend_symtable_update_ind
  8. zend_symtable_del
  9. zend_symtable_del_ind
  10. zend_symtable_find
  11. zend_symtable_find_ind
  12. zend_symtable_exists
  13. zend_symtable_exists_ind
  14. zend_symtable_str_update
  15. zend_symtable_str_update_ind
  16. zend_symtable_str_del
  17. zend_symtable_str_del_ind
  18. zend_symtable_str_find
  19. zend_symtable_str_exists
  20. zend_hash_add_ptr
  21. zend_hash_add_new_ptr
  22. zend_hash_str_add_ptr
  23. zend_hash_str_add_new_ptr
  24. zend_hash_update_ptr
  25. zend_hash_str_update_ptr
  26. zend_hash_add_mem
  27. zend_hash_str_add_mem
  28. zend_hash_update_mem
  29. zend_hash_str_update_mem
  30. zend_hash_index_add_ptr
  31. zend_hash_index_add_new_ptr
  32. zend_hash_index_update_ptr
  33. zend_hash_index_add_mem
  34. zend_hash_next_index_insert_ptr
  35. zend_hash_index_update_mem
  36. zend_hash_next_index_insert_mem
  37. zend_hash_find_ptr
  38. zend_hash_str_find_ptr
  39. zend_hash_index_find_ptr
  40. zend_symtable_str_find_ptr
  41. zend_hash_get_current_data_ptr_ex
  42. _zend_hash_append
  43. _zend_hash_append_ptr
  44. _zend_hash_append_ind

   1 /*
   2    +----------------------------------------------------------------------+
   3    | Zend Engine                                                          |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1998-2016 Zend Technologies Ltd. (http://www.zend.com) |
   6    +----------------------------------------------------------------------+
   7    | This source file is subject to version 2.00 of the Zend license,     |
   8    | that is bundled with this package in the file LICENSE, and is        |
   9    | available through the world-wide-web at the following url:           |
  10    | http://www.zend.com/license/2_00.txt.                                |
  11    | If you did not receive a copy of the Zend license and are unable to  |
  12    | obtain it through the world-wide-web, please send a note to          |
  13    | license@zend.com so we can mail you a copy immediately.              |
  14    +----------------------------------------------------------------------+
  15    | Authors: Andi Gutmans <andi@zend.com>                                |
  16    |          Zeev Suraski <zeev@zend.com>                                |
  17    |          Dmitry Stogov <dmitry@zend.com>                             |
  18    +----------------------------------------------------------------------+
  19 */
  20 
  21 /* $Id$ */
  22 
  23 #ifndef ZEND_HASH_H
  24 #define ZEND_HASH_H
  25 
  26 #include "zend.h"
  27 
  28 #define HASH_KEY_IS_STRING 1
  29 #define HASH_KEY_IS_LONG 2
  30 #define HASH_KEY_NON_EXISTENT 3
  31 
  32 #define HASH_UPDATE                     (1<<0)
  33 #define HASH_ADD                                (1<<1)
  34 #define HASH_UPDATE_INDIRECT    (1<<2)
  35 #define HASH_ADD_NEW                    (1<<3)
  36 #define HASH_ADD_NEXT                   (1<<4)
  37 
  38 #define HASH_FLAG_PERSISTENT       (1<<0)
  39 #define HASH_FLAG_APPLY_PROTECTION (1<<1)
  40 #define HASH_FLAG_PACKED           (1<<2)
  41 #define HASH_FLAG_INITIALIZED      (1<<3)
  42 #define HASH_FLAG_STATIC_KEYS      (1<<4)
  43 #define HASH_FLAG_HAS_EMPTY_IND    (1<<5)
  44 
  45 #define HASH_MASK_CONSISTENCY      0xc0
  46 
  47 typedef struct _zend_hash_key {
  48         zend_ulong h;
  49         zend_string *key;
  50 } zend_hash_key;
  51 
  52 typedef zend_bool (*merge_checker_func_t)(HashTable *target_ht, zval *source_data, zend_hash_key *hash_key, void *pParam);
  53 
  54 BEGIN_EXTERN_C()
  55 
  56 /* startup/shutdown */
  57 ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC);
  58 ZEND_API void ZEND_FASTCALL _zend_hash_init_ex(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent, zend_bool bApplyProtection ZEND_FILE_LINE_DC);
  59 ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht);
  60 ZEND_API void ZEND_FASTCALL zend_hash_clean(HashTable *ht);
  61 #define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)                                               _zend_hash_init((ht), (nSize), (pDestructor), (persistent) ZEND_FILE_LINE_CC)
  62 #define zend_hash_init_ex(ht, nSize, pHashFunction, pDestructor, persistent, bApplyProtection)          _zend_hash_init_ex((ht), (nSize), (pDestructor), (persistent), (bApplyProtection) ZEND_FILE_LINE_CC)
  63 
  64 ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, zend_bool packed);
  65 ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht);
  66 ZEND_API void ZEND_FASTCALL zend_hash_to_packed(HashTable *ht);
  67 ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend_bool packed);
  68 
  69 /* additions/updates/changes */
  70 ZEND_API zval* ZEND_FASTCALL _zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, uint32_t flag ZEND_FILE_LINE_DC);
  71 ZEND_API zval* ZEND_FASTCALL _zend_hash_update(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
  72 ZEND_API zval* ZEND_FASTCALL _zend_hash_update_ind(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
  73 ZEND_API zval* ZEND_FASTCALL _zend_hash_add(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
  74 ZEND_API zval* ZEND_FASTCALL _zend_hash_add_new(HashTable *ht, zend_string *key,zval *pData ZEND_FILE_LINE_DC);
  75 
  76 #define zend_hash_update(ht, key, pData) \
  77                 _zend_hash_update(ht, key, pData ZEND_FILE_LINE_CC)
  78 #define zend_hash_update_ind(ht, key, pData) \
  79                 _zend_hash_update_ind(ht, key, pData ZEND_FILE_LINE_CC)
  80 #define zend_hash_add(ht, key, pData) \
  81                 _zend_hash_add(ht, key, pData ZEND_FILE_LINE_CC)
  82 #define zend_hash_add_new(ht, key, pData) \
  83                 _zend_hash_add_new(ht, key, pData ZEND_FILE_LINE_CC)
  84 
  85 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_FILE_LINE_DC);
  86 ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
  87 ZEND_API zval* ZEND_FASTCALL _zend_hash_str_update_ind(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
  88 ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
  89 ZEND_API zval* ZEND_FASTCALL _zend_hash_str_add_new(HashTable *ht, const char *key, size_t len, zval *pData ZEND_FILE_LINE_DC);
  90 
  91 #define zend_hash_str_update(ht, key, len, pData) \
  92                 _zend_hash_str_update(ht, key, len, pData ZEND_FILE_LINE_CC)
  93 #define zend_hash_str_update_ind(ht, key, len, pData) \
  94                 _zend_hash_str_update_ind(ht, key, len, pData ZEND_FILE_LINE_CC)
  95 #define zend_hash_str_add(ht, key, len, pData) \
  96                 _zend_hash_str_add(ht, key, len, pData ZEND_FILE_LINE_CC)
  97 #define zend_hash_str_add_new(ht, key, len, pData) \
  98                 _zend_hash_str_add_new(ht, key, len, pData ZEND_FILE_LINE_CC)
  99 
 100 ZEND_API zval* ZEND_FASTCALL _zend_hash_index_add_or_update(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag ZEND_FILE_LINE_DC);
 101 ZEND_API zval* ZEND_FASTCALL _zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
 102 ZEND_API zval* ZEND_FASTCALL _zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
 103 ZEND_API zval* ZEND_FASTCALL _zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData ZEND_FILE_LINE_DC);
 104 ZEND_API zval* ZEND_FASTCALL _zend_hash_next_index_insert(HashTable *ht, zval *pData ZEND_FILE_LINE_DC);
 105 ZEND_API zval* ZEND_FASTCALL _zend_hash_next_index_insert_new(HashTable *ht, zval *pData ZEND_FILE_LINE_DC);
 106 
 107 #define zend_hash_index_add(ht, h, pData) \
 108                 _zend_hash_index_add(ht, h, pData ZEND_FILE_LINE_CC)
 109 #define zend_hash_index_add_new(ht, h, pData) \
 110                 _zend_hash_index_add_new(ht, h, pData ZEND_FILE_LINE_CC)
 111 #define zend_hash_index_update(ht, h, pData) \
 112                 _zend_hash_index_update(ht, h, pData ZEND_FILE_LINE_CC)
 113 #define zend_hash_next_index_insert(ht, pData) \
 114                 _zend_hash_next_index_insert(ht, pData ZEND_FILE_LINE_CC)
 115 #define zend_hash_next_index_insert_new(ht, pData) \
 116                 _zend_hash_next_index_insert_new(ht, pData ZEND_FILE_LINE_CC)
 117 
 118 ZEND_API zval* ZEND_FASTCALL zend_hash_index_add_empty_element(HashTable *ht, zend_ulong h);
 119 ZEND_API zval* ZEND_FASTCALL zend_hash_add_empty_element(HashTable *ht, zend_string *key);
 120 ZEND_API zval* ZEND_FASTCALL zend_hash_str_add_empty_element(HashTable *ht, const char *key, size_t len);
 121 
 122 #define ZEND_HASH_APPLY_KEEP                            0
 123 #define ZEND_HASH_APPLY_REMOVE                          1<<0
 124 #define ZEND_HASH_APPLY_STOP                            1<<1
 125 
 126 typedef int (*apply_func_t)(zval *pDest);
 127 typedef int (*apply_func_arg_t)(zval *pDest, void *argument);
 128 typedef int (*apply_func_args_t)(zval *pDest, int num_args, va_list args, zend_hash_key *hash_key);
 129 
 130 ZEND_API void ZEND_FASTCALL zend_hash_graceful_destroy(HashTable *ht);
 131 ZEND_API void ZEND_FASTCALL zend_hash_graceful_reverse_destroy(HashTable *ht);
 132 ZEND_API void ZEND_FASTCALL zend_hash_apply(HashTable *ht, apply_func_t apply_func);
 133 ZEND_API void ZEND_FASTCALL zend_hash_apply_with_argument(HashTable *ht, apply_func_arg_t apply_func, void *);
 134 ZEND_API void ZEND_FASTCALL zend_hash_apply_with_arguments(HashTable *ht, apply_func_args_t apply_func, int, ...);
 135 
 136 /* This function should be used with special care (in other words,
 137  * it should usually not be used).  When used with the ZEND_HASH_APPLY_STOP
 138  * return value, it assumes things about the order of the elements in the hash.
 139  * Also, it does not provide the same kind of reentrancy protection that
 140  * the standard apply functions do.
 141  */
 142 ZEND_API void ZEND_FASTCALL zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func);
 143 
 144 
 145 /* Deletes */
 146 ZEND_API int ZEND_FASTCALL zend_hash_del(HashTable *ht, zend_string *key);
 147 ZEND_API int ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string *key);
 148 ZEND_API int ZEND_FASTCALL zend_hash_str_del(HashTable *ht, const char *key, size_t len);
 149 ZEND_API int ZEND_FASTCALL zend_hash_str_del_ind(HashTable *ht, const char *key, size_t len);
 150 ZEND_API int ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h);
 151 ZEND_API void ZEND_FASTCALL zend_hash_del_bucket(HashTable *ht, Bucket *p);
 152 
 153 /* Data retreival */
 154 ZEND_API zval* ZEND_FASTCALL zend_hash_find(const HashTable *ht, zend_string *key);
 155 ZEND_API zval* ZEND_FASTCALL zend_hash_str_find(const HashTable *ht, const char *key, size_t len);
 156 ZEND_API zval* ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h);
 157 
 158 /* Misc */
 159 ZEND_API zend_bool ZEND_FASTCALL zend_hash_exists(const HashTable *ht, zend_string *key);
 160 ZEND_API zend_bool ZEND_FASTCALL zend_hash_str_exists(const HashTable *ht, const char *str, size_t len);
 161 ZEND_API zend_bool ZEND_FASTCALL zend_hash_index_exists(const HashTable *ht, zend_ulong h);
 162 
 163 /* traversing */
 164 #define zend_hash_has_more_elements_ex(ht, pos) \
 165         (zend_hash_get_current_key_type_ex(ht, pos) == HASH_KEY_NON_EXISTENT ? FAILURE : SUCCESS)
 166 ZEND_API int   ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos);
 167 ZEND_API int   ZEND_FASTCALL zend_hash_move_backwards_ex(HashTable *ht, HashPosition *pos);
 168 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos);
 169 ZEND_API void  ZEND_FASTCALL zend_hash_get_current_key_zval_ex(const HashTable *ht, zval *key, HashPosition *pos);
 170 ZEND_API int   ZEND_FASTCALL zend_hash_get_current_key_type_ex(HashTable *ht, HashPosition *pos);
 171 ZEND_API zval* ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos);
 172 ZEND_API void  ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos);
 173 ZEND_API void  ZEND_FASTCALL zend_hash_internal_pointer_end_ex(HashTable *ht, HashPosition *pos);
 174 
 175 #define zend_hash_has_more_elements(ht) \
 176         zend_hash_has_more_elements_ex(ht, &(ht)->nInternalPointer)
 177 #define zend_hash_move_forward(ht) \
 178         zend_hash_move_forward_ex(ht, &(ht)->nInternalPointer)
 179 #define zend_hash_move_backwards(ht) \
 180         zend_hash_move_backwards_ex(ht, &(ht)->nInternalPointer)
 181 #define zend_hash_get_current_key(ht, str_index, num_index) \
 182         zend_hash_get_current_key_ex(ht, str_index, num_index, &(ht)->nInternalPointer)
 183 #define zend_hash_get_current_key_zval(ht, key) \
 184         zend_hash_get_current_key_zval_ex(ht, key, &(ht)->nInternalPointer)
 185 #define zend_hash_get_current_key_type(ht) \
 186         zend_hash_get_current_key_type_ex(ht, &(ht)->nInternalPointer)
 187 #define zend_hash_get_current_data(ht) \
 188         zend_hash_get_current_data_ex(ht, &(ht)->nInternalPointer)
 189 #define zend_hash_internal_pointer_reset(ht) \
 190         zend_hash_internal_pointer_reset_ex(ht, &(ht)->nInternalPointer)
 191 #define zend_hash_internal_pointer_end(ht) \
 192         zend_hash_internal_pointer_end_ex(ht, &(ht)->nInternalPointer)
 193 
 194 /* Copying, merging and sorting */
 195 ZEND_API void  ZEND_FASTCALL zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor);
 196 ZEND_API void  ZEND_FASTCALL _zend_hash_merge(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, zend_bool overwrite ZEND_FILE_LINE_DC);
 197 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);
 198 ZEND_API void  zend_hash_bucket_swap(Bucket *p, Bucket *q);
 199 ZEND_API void  zend_hash_bucket_renum_swap(Bucket *p, Bucket *q);
 200 ZEND_API void  zend_hash_bucket_packed_swap(Bucket *p, Bucket *q);
 201 ZEND_API int   zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered);
 202 ZEND_API int   ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, compare_func_t compare_func, zend_bool renumber);
 203 ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag);
 204 
 205 #define zend_hash_merge(target, source, pCopyConstructor, overwrite)                                    \
 206         _zend_hash_merge(target, source, pCopyConstructor, overwrite ZEND_FILE_LINE_CC)
 207 
 208 #define zend_hash_sort(ht, compare_func, renumber) \
 209         zend_hash_sort_ex(ht, zend_sort, compare_func, renumber)
 210 
 211 #define zend_hash_num_elements(ht) \
 212         (ht)->nNumOfElements
 213 
 214 #define zend_hash_next_free_element(ht) \
 215         (ht)->nNextFreeElement
 216 
 217 ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht);
 218 
 219 ZEND_API uint32_t zend_array_count(HashTable *ht);
 220 ZEND_API HashTable* ZEND_FASTCALL zend_array_dup(HashTable *source);
 221 ZEND_API void ZEND_FASTCALL zend_array_destroy(HashTable *ht);
 222 ZEND_API void ZEND_FASTCALL zend_symtable_clean(HashTable *ht);
 223 
 224 ZEND_API int ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx);
 225 
 226 ZEND_API uint32_t     ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos);
 227 ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos(uint32_t idx, HashTable *ht);
 228 ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterator_pos_ex(uint32_t idx, zval *array);
 229 ZEND_API void         ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx);
 230 ZEND_API HashPosition ZEND_FASTCALL zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start);
 231 ZEND_API void         ZEND_FASTCALL _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to);
 232 
 233 static zend_always_inline void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
 234 {
 235         if (UNEXPECTED(ht->u.v.nIteratorsCount)) {
 236                 _zend_hash_iterators_update(ht, from, to);
 237         }
 238 }
 239 
 240 
 241 END_EXTERN_C()
 242 
 243 #define ZEND_INIT_SYMTABLE(ht)                                                          \
 244         ZEND_INIT_SYMTABLE_EX(ht, 8, 0)
 245 
 246 #define ZEND_INIT_SYMTABLE_EX(ht, n, persistent)                        \
 247         zend_hash_init(ht, n, NULL, ZVAL_PTR_DTOR, persistent)
 248 
 249 static zend_always_inline int _zend_handle_numeric_str(const char *key, size_t length, zend_ulong *idx)
 250 {
 251         register const char *tmp = key;
 252 
 253         if (*tmp > '9') {
 254                 return 0;
 255         } else if (*tmp < '0') {
 256                 if (*tmp != '-') {
 257                         return 0;
 258                 }
 259                 tmp++;
 260                 if (*tmp > '9' || *tmp < '0') {
 261                         return 0;
 262                 }
 263         }
 264         return _zend_handle_numeric_str_ex(key, length, idx);
 265 }
 266 
 267 #define ZEND_HANDLE_NUMERIC_STR(key, length, idx) \
 268         _zend_handle_numeric_str(key, length, &idx)
 269 
 270 #define ZEND_HANDLE_NUMERIC(key, idx) \
 271         ZEND_HANDLE_NUMERIC_STR(ZSTR_VAL(key), ZSTR_LEN(key), idx)
 272 
 273 
 274 static zend_always_inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
 275 {
 276         zval *zv;
 277 
 278         zv = zend_hash_find(ht, key);
 279         return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? 
 280                 ((Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF) ? Z_INDIRECT_P(zv) : NULL) : zv;
 281 }
 282 
 283 
 284 static zend_always_inline int zend_hash_exists_ind(const HashTable *ht, zend_string *key)
 285 {
 286         zval *zv;
 287 
 288         zv = zend_hash_find(ht, key);
 289         return zv && (Z_TYPE_P(zv) != IS_INDIRECT ||
 290                         Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF);
 291 }
 292 
 293 
 294 static zend_always_inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str, size_t len)
 295 {
 296         zval *zv;
 297 
 298         zv = zend_hash_str_find(ht, str, len);
 299         return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? 
 300                 ((Z_TYPE_P(Z_INDIRECT_P(zv)) != IS_UNDEF) ? Z_INDIRECT_P(zv) : NULL) : zv;
 301 }
 302 
 303 
 304 static zend_always_inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
 305 {
 306         zend_ulong idx;
 307 
 308         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 309                 return zend_hash_index_update(ht, idx, pData);
 310         } else {
 311                 return zend_hash_update(ht, key, pData);
 312         }
 313 }
 314 
 315 
 316 static zend_always_inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zval *pData)
 317 {
 318         zend_ulong idx;
 319 
 320         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 321                 return zend_hash_index_update(ht, idx, pData);
 322         } else {
 323                 return zend_hash_update_ind(ht, key, pData);
 324         }
 325 }
 326 
 327 
 328 static zend_always_inline int zend_symtable_del(HashTable *ht, zend_string *key)
 329 {
 330         zend_ulong idx;
 331 
 332         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 333                 return zend_hash_index_del(ht, idx);
 334         } else {
 335                 return zend_hash_del(ht, key);
 336         }
 337 }
 338 
 339 
 340 static zend_always_inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
 341 {
 342         zend_ulong idx;
 343 
 344         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 345                 return zend_hash_index_del(ht, idx);
 346         } else {
 347                 return zend_hash_del_ind(ht, key);
 348         }
 349 }
 350 
 351 
 352 static zend_always_inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
 353 {
 354         zend_ulong idx;
 355 
 356         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 357                 return zend_hash_index_find(ht, idx);
 358         } else {
 359                 return zend_hash_find(ht, key);
 360         }
 361 }
 362 
 363 
 364 static zend_always_inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key)
 365 {
 366         zend_ulong idx;
 367 
 368         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 369                 return zend_hash_index_find(ht, idx);
 370         } else {
 371                 return zend_hash_find_ind(ht, key);
 372         }
 373 }
 374 
 375 
 376 static zend_always_inline int zend_symtable_exists(HashTable *ht, zend_string *key)
 377 {
 378         zend_ulong idx;
 379 
 380         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 381                 return zend_hash_index_exists(ht, idx);
 382         } else {
 383                 return zend_hash_exists(ht, key);
 384         }
 385 }
 386 
 387 
 388 static zend_always_inline int zend_symtable_exists_ind(HashTable *ht, zend_string *key)
 389 {
 390         zend_ulong idx;
 391 
 392         if (ZEND_HANDLE_NUMERIC(key, idx)) {
 393                 return zend_hash_index_exists(ht, idx);
 394         } else {
 395                 return zend_hash_exists_ind(ht, key);
 396         }
 397 }
 398 
 399 
 400 static zend_always_inline zval *zend_symtable_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
 401 {
 402         zend_ulong idx;
 403 
 404         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 405                 return zend_hash_index_update(ht, idx, pData);
 406         } else {
 407                 return zend_hash_str_update(ht, str, len, pData);
 408         }
 409 }
 410 
 411 
 412 static zend_always_inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData)
 413 {
 414         zend_ulong idx;
 415 
 416         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 417                 return zend_hash_index_update(ht, idx, pData);
 418         } else {
 419                 return zend_hash_str_update_ind(ht, str, len, pData);
 420         }
 421 }
 422 
 423 
 424 static zend_always_inline int zend_symtable_str_del(HashTable *ht, const char *str, size_t len)
 425 {
 426         zend_ulong idx;
 427 
 428         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 429                 return zend_hash_index_del(ht, idx);
 430         } else {
 431                 return zend_hash_str_del(ht, str, len);
 432         }
 433 }
 434 
 435 
 436 static zend_always_inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, size_t len)
 437 {
 438         zend_ulong idx;
 439 
 440         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 441                 return zend_hash_index_del(ht, idx);
 442         } else {
 443                 return zend_hash_str_del_ind(ht, str, len);
 444         }
 445 }
 446 
 447 
 448 static zend_always_inline zval *zend_symtable_str_find(HashTable *ht, const char *str, size_t len)
 449 {
 450         zend_ulong idx;
 451 
 452         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 453                 return zend_hash_index_find(ht, idx);
 454         } else {
 455                 return zend_hash_str_find(ht, str, len);
 456         }
 457 }
 458 
 459 
 460 static zend_always_inline int zend_symtable_str_exists(HashTable *ht, const char *str, size_t len)
 461 {
 462         zend_ulong idx;
 463 
 464         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 465                 return zend_hash_index_exists(ht, idx);
 466         } else {
 467                 return zend_hash_str_exists(ht, str, len);
 468         }
 469 }
 470 
 471 static zend_always_inline void *zend_hash_add_ptr(HashTable *ht, zend_string *key, void *pData)
 472 {
 473         zval tmp, *zv;
 474 
 475         ZVAL_PTR(&tmp, pData);
 476         zv = zend_hash_add(ht, key, &tmp);
 477         if (zv) {
 478                 ZEND_ASSUME(Z_PTR_P(zv));
 479                 return Z_PTR_P(zv);
 480         } else {
 481                 return NULL;
 482         }
 483 }
 484 
 485 static zend_always_inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string *key, void *pData)
 486 {
 487         zval tmp, *zv;
 488 
 489         ZVAL_PTR(&tmp, pData);
 490         zv = zend_hash_add_new(ht, key, &tmp);
 491         if (zv) {
 492                 ZEND_ASSUME(Z_PTR_P(zv));
 493                 return Z_PTR_P(zv);
 494         } else {
 495                 return NULL;
 496         }
 497 }
 498 
 499 static zend_always_inline void *zend_hash_str_add_ptr(HashTable *ht, const char *str, size_t len, void *pData)
 500 {
 501         zval tmp, *zv;
 502 
 503         ZVAL_PTR(&tmp, pData);
 504         zv = zend_hash_str_add(ht, str, len, &tmp);
 505         if (zv) {
 506                 ZEND_ASSUME(Z_PTR_P(zv));
 507                 return Z_PTR_P(zv);
 508         } else {
 509                 return NULL;
 510         }
 511 }
 512 
 513 static zend_always_inline void *zend_hash_str_add_new_ptr(HashTable *ht, const char *str, size_t len, void *pData)
 514 {
 515         zval tmp, *zv;
 516 
 517         ZVAL_PTR(&tmp, pData);
 518         zv = zend_hash_str_add_new(ht, str, len, &tmp);
 519         if (zv) {
 520                 ZEND_ASSUME(Z_PTR_P(zv));
 521                 return Z_PTR_P(zv);
 522         } else {
 523                 return NULL;
 524         }
 525 }
 526 
 527 static zend_always_inline void *zend_hash_update_ptr(HashTable *ht, zend_string *key, void *pData)
 528 {
 529         zval tmp, *zv;
 530 
 531         ZVAL_PTR(&tmp, pData);
 532         zv = zend_hash_update(ht, key, &tmp);
 533         if (zv) {
 534                 ZEND_ASSUME(Z_PTR_P(zv));
 535                 return Z_PTR_P(zv);
 536         } else {
 537                 return NULL;
 538         }
 539 }
 540 
 541 static zend_always_inline void *zend_hash_str_update_ptr(HashTable *ht, const char *str, size_t len, void *pData)
 542 {
 543         zval tmp, *zv;
 544 
 545         ZVAL_PTR(&tmp, pData);
 546         zv = zend_hash_str_update(ht, str, len, &tmp);
 547         if (zv) {
 548                 ZEND_ASSUME(Z_PTR_P(zv));
 549                 return Z_PTR_P(zv);
 550         } else {
 551                 return NULL;
 552         }
 553 }
 554 
 555 static zend_always_inline void *zend_hash_add_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
 556 {
 557         zval tmp, *zv;
 558 
 559         ZVAL_PTR(&tmp, NULL);
 560         if ((zv = zend_hash_add(ht, key, &tmp))) {
 561                 Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 562                 memcpy(Z_PTR_P(zv), pData, size);
 563                 return Z_PTR_P(zv);
 564         }
 565         return NULL;
 566 }
 567 
 568 static zend_always_inline void *zend_hash_str_add_mem(HashTable *ht, const char *str, size_t len, void *pData, size_t size)
 569 {
 570         zval tmp, *zv;
 571 
 572         ZVAL_PTR(&tmp, NULL);
 573         if ((zv = zend_hash_str_add(ht, str, len, &tmp))) {
 574                 Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 575                 memcpy(Z_PTR_P(zv), pData, size);
 576                 return Z_PTR_P(zv);
 577         }
 578         return NULL;
 579 }
 580 
 581 static zend_always_inline void *zend_hash_update_mem(HashTable *ht, zend_string *key, void *pData, size_t size)
 582 {
 583         void *p;
 584 
 585         p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 586         memcpy(p, pData, size);
 587         return zend_hash_update_ptr(ht, key, p);
 588 }
 589 
 590 static zend_always_inline void *zend_hash_str_update_mem(HashTable *ht, const char *str, size_t len, void *pData, size_t size)
 591 {
 592         void *p;
 593 
 594         p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 595         memcpy(p, pData, size);
 596         return zend_hash_str_update_ptr(ht, str, len, p);
 597 }
 598 
 599 static zend_always_inline void *zend_hash_index_add_ptr(HashTable *ht, zend_ulong h, void *pData)
 600 {
 601         zval tmp, *zv;
 602 
 603         ZVAL_PTR(&tmp, pData);
 604         zv = zend_hash_index_add(ht, h, &tmp);
 605         return zv ? Z_PTR_P(zv) : NULL;
 606 }
 607 
 608 static zend_always_inline void *zend_hash_index_add_new_ptr(HashTable *ht, zend_ulong h, void *pData)
 609 {
 610         zval tmp, *zv;
 611 
 612         ZVAL_PTR(&tmp, pData);
 613         zv = zend_hash_index_add_new(ht, h, &tmp);
 614         return zv ? Z_PTR_P(zv) : NULL;
 615 }
 616 
 617 static zend_always_inline void *zend_hash_index_update_ptr(HashTable *ht, zend_ulong h, void *pData)
 618 {
 619         zval tmp, *zv;
 620 
 621         ZVAL_PTR(&tmp, pData);
 622         zv = zend_hash_index_update(ht, h, &tmp);
 623         if (zv) {
 624                 ZEND_ASSUME(Z_PTR_P(zv));
 625                 return Z_PTR_P(zv);
 626         } else {
 627                 return NULL;
 628         }
 629 }
 630 
 631 static zend_always_inline void *zend_hash_index_add_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
 632 {
 633         zval tmp, *zv;
 634 
 635         ZVAL_PTR(&tmp, NULL);
 636         if ((zv = zend_hash_index_add(ht, h, &tmp))) {
 637                 Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 638                 memcpy(Z_PTR_P(zv), pData, size);
 639                 return Z_PTR_P(zv);
 640         }
 641         return NULL;
 642 }
 643 
 644 static zend_always_inline void *zend_hash_next_index_insert_ptr(HashTable *ht, void *pData)
 645 {
 646         zval tmp, *zv;
 647 
 648         ZVAL_PTR(&tmp, pData);
 649         zv = zend_hash_next_index_insert(ht, &tmp);
 650         if (zv) {
 651                 ZEND_ASSUME(Z_PTR_P(zv));
 652                 return Z_PTR_P(zv);
 653         } else {
 654                 return NULL;
 655         }
 656 }
 657 
 658 static zend_always_inline void *zend_hash_index_update_mem(HashTable *ht, zend_ulong h, void *pData, size_t size)
 659 {
 660         void *p;
 661 
 662         p = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 663         memcpy(p, pData, size);
 664         return zend_hash_index_update_ptr(ht, h, p);
 665 }
 666 
 667 static zend_always_inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
 668 {
 669         zval tmp, *zv;
 670 
 671         ZVAL_PTR(&tmp, NULL);
 672         if ((zv = zend_hash_next_index_insert(ht, &tmp))) {
 673                 Z_PTR_P(zv) = pemalloc(size, ht->u.flags & HASH_FLAG_PERSISTENT);
 674                 memcpy(Z_PTR_P(zv), pData, size);
 675                 return Z_PTR_P(zv);
 676         }
 677         return NULL;
 678 }
 679 
 680 static zend_always_inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
 681 {
 682         zval *zv;
 683 
 684         zv = zend_hash_find(ht, key);
 685         if (zv) {
 686                 ZEND_ASSUME(Z_PTR_P(zv));
 687                 return Z_PTR_P(zv);
 688         } else {
 689                 return NULL;
 690         }
 691 }
 692 
 693 static zend_always_inline void *zend_hash_str_find_ptr(const HashTable *ht, const char *str, size_t len)
 694 {
 695         zval *zv;
 696 
 697         zv = zend_hash_str_find(ht, str, len);
 698         if (zv) {
 699                 ZEND_ASSUME(Z_PTR_P(zv));
 700                 return Z_PTR_P(zv);
 701         } else {
 702                 return NULL;
 703         }
 704 }
 705 
 706 static zend_always_inline void *zend_hash_index_find_ptr(const HashTable *ht, zend_ulong h)
 707 {
 708         zval *zv;
 709 
 710         zv = zend_hash_index_find(ht, h);
 711         if (zv) {
 712                 ZEND_ASSUME(Z_PTR_P(zv));
 713                 return Z_PTR_P(zv);
 714         } else {
 715                 return NULL;
 716         }
 717 }
 718 
 719 static zend_always_inline void *zend_symtable_str_find_ptr(HashTable *ht, const char *str, size_t len)
 720 {
 721         zend_ulong idx;
 722 
 723         if (ZEND_HANDLE_NUMERIC_STR(str, len, idx)) {
 724                 return zend_hash_index_find_ptr(ht, idx);
 725         } else {
 726                 return zend_hash_str_find_ptr(ht, str, len);
 727         }
 728 }
 729 
 730 static zend_always_inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPosition *pos)
 731 {
 732         zval *zv;
 733 
 734         zv = zend_hash_get_current_data_ex(ht, pos);
 735         if (zv) {
 736                 ZEND_ASSUME(Z_PTR_P(zv));
 737                 return Z_PTR_P(zv);
 738         } else {
 739                 return NULL;
 740         }
 741 }
 742 
 743 #define zend_hash_get_current_data_ptr(ht) \
 744         zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer)
 745 
 746 #define ZEND_HASH_FOREACH(_ht, indirect) do { \
 747                 Bucket *_p = (_ht)->arData; \
 748                 Bucket *_end = _p + (_ht)->nNumUsed; \
 749                 for (; _p != _end; _p++) { \
 750                         zval *_z = &_p->val; \
 751                         if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
 752                                 _z = Z_INDIRECT_P(_z); \
 753                         } \
 754                         if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
 755 
 756 #define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \
 757                 uint _idx; \
 758                 for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \
 759                         Bucket *_p = (_ht)->arData + _idx - 1; \
 760                         zval *_z = &_p->val; \
 761                         if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \
 762                                 _z = Z_INDIRECT_P(_z); \
 763                         } \
 764                         if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue;
 765 
 766 #define ZEND_HASH_FOREACH_END() \
 767                 } \
 768         } while (0)
 769 
 770 #define ZEND_HASH_FOREACH_BUCKET(ht, _bucket) \
 771         ZEND_HASH_FOREACH(ht, 0); \
 772         _bucket = _p;
 773 
 774 #define ZEND_HASH_FOREACH_VAL(ht, _val) \
 775         ZEND_HASH_FOREACH(ht, 0); \
 776         _val = _z;
 777 
 778 #define ZEND_HASH_FOREACH_VAL_IND(ht, _val) \
 779         ZEND_HASH_FOREACH(ht, 1); \
 780         _val = _z;
 781 
 782 #define ZEND_HASH_FOREACH_PTR(ht, _ptr) \
 783         ZEND_HASH_FOREACH(ht, 0); \
 784         _ptr = Z_PTR_P(_z);
 785 
 786 #define ZEND_HASH_FOREACH_NUM_KEY(ht, _h) \
 787         ZEND_HASH_FOREACH(ht, 0); \
 788         _h = _p->h;
 789 
 790 #define ZEND_HASH_FOREACH_STR_KEY(ht, _key) \
 791         ZEND_HASH_FOREACH(ht, 0); \
 792         _key = _p->key;
 793 
 794 #define ZEND_HASH_FOREACH_KEY(ht, _h, _key) \
 795         ZEND_HASH_FOREACH(ht, 0); \
 796         _h = _p->h; \
 797         _key = _p->key;
 798 
 799 #define ZEND_HASH_FOREACH_NUM_KEY_VAL(ht, _h, _val) \
 800         ZEND_HASH_FOREACH(ht, 0); \
 801         _h = _p->h; \
 802         _val = _z;
 803 
 804 #define ZEND_HASH_FOREACH_STR_KEY_VAL(ht, _key, _val) \
 805         ZEND_HASH_FOREACH(ht, 0); \
 806         _key = _p->key; \
 807         _val = _z;
 808 
 809 #define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val) \
 810         ZEND_HASH_FOREACH(ht, 0); \
 811         _h = _p->h; \
 812         _key = _p->key; \
 813         _val = _z;
 814 
 815 #define ZEND_HASH_FOREACH_STR_KEY_VAL_IND(ht, _key, _val) \
 816         ZEND_HASH_FOREACH(ht, 1); \
 817         _key = _p->key; \
 818         _val = _z;
 819 
 820 #define ZEND_HASH_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
 821         ZEND_HASH_FOREACH(ht, 1); \
 822         _h = _p->h; \
 823         _key = _p->key; \
 824         _val = _z;
 825 
 826 #define ZEND_HASH_FOREACH_NUM_KEY_PTR(ht, _h, _ptr) \
 827         ZEND_HASH_FOREACH(ht, 0); \
 828         _h = _p->h; \
 829         _ptr = Z_PTR_P(_z);
 830 
 831 #define ZEND_HASH_FOREACH_STR_KEY_PTR(ht, _key, _ptr) \
 832         ZEND_HASH_FOREACH(ht, 0); \
 833         _key = _p->key; \
 834         _ptr = Z_PTR_P(_z);
 835 
 836 #define ZEND_HASH_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \
 837         ZEND_HASH_FOREACH(ht, 0); \
 838         _h = _p->h; \
 839         _key = _p->key; \
 840         _ptr = Z_PTR_P(_z);
 841 
 842 #define ZEND_HASH_REVERSE_FOREACH_BUCKET(ht, _bucket) \
 843         ZEND_HASH_REVERSE_FOREACH(ht, 0); \
 844         _bucket = _p;
 845 
 846 #define ZEND_HASH_REVERSE_FOREACH_VAL(ht, _val) \
 847         ZEND_HASH_REVERSE_FOREACH(ht, 0); \
 848         _val = _z;
 849 
 850 #define ZEND_HASH_REVERSE_FOREACH_PTR(ht, _ptr) \
 851         ZEND_HASH_REVERSE_FOREACH(ht, 0); \
 852         _ptr = Z_PTR_P(_z);
 853 
 854 #define ZEND_HASH_REVERSE_FOREACH_VAL_IND(ht, _val) \
 855         ZEND_HASH_REVERSE_FOREACH(ht, 1); \
 856         _val = _z;
 857 
 858 #define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(ht, _h, _key, _val) \
 859         ZEND_HASH_REVERSE_FOREACH(ht, 0); \
 860         _h = _p->h; \
 861         _key = _p->key; \
 862         _val = _z;
 863 
 864 #define ZEND_HASH_REVERSE_FOREACH_KEY_VAL_IND(ht, _h, _key, _val) \
 865         ZEND_HASH_REVERSE_FOREACH(ht, 1); \
 866         _h = _p->h; \
 867         _key = _p->key; \
 868         _val = _z;
 869 
 870 #define ZEND_HASH_APPLY_PROTECTION(ht) \
 871         ((ht)->u.flags & HASH_FLAG_APPLY_PROTECTION)
 872 
 873 #define ZEND_HASH_APPLY_SHIFT         8
 874 #define ZEND_HASH_APPLY_COUNT_MASK    0xff00
 875 #define ZEND_HASH_GET_APPLY_COUNT(ht) (((ht)->u.flags & ZEND_HASH_APPLY_COUNT_MASK) >> ZEND_HASH_APPLY_SHIFT)
 876 #define ZEND_HASH_INC_APPLY_COUNT(ht) ((ht)->u.flags += (1 << ZEND_HASH_APPLY_SHIFT))
 877 #define ZEND_HASH_DEC_APPLY_COUNT(ht) ((ht)->u.flags -= (1 << ZEND_HASH_APPLY_SHIFT))
 878 
 879 
 880 /* The following macros are useful to insert a sequence of new elements
 881  * of packed array. They may be use insted of series of
 882  * zend_hash_next_index_insert_new()
 883  * (HashTable must have enough free buckets).
 884  */
 885 #define ZEND_HASH_FILL_PACKED(ht) do { \
 886                 HashTable *__fill_ht = (ht); \
 887                 Bucket *__fill_bkt = __fill_ht->arData + __fill_ht->nNumUsed; \
 888                 uint32_t __fill_idx = __fill_ht->nNumUsed; \
 889                 ZEND_ASSERT(__fill_ht->u.flags & HASH_FLAG_PACKED);
 890 
 891 #define ZEND_HASH_FILL_ADD(_val) do { \
 892                 ZVAL_COPY_VALUE(&__fill_bkt->val, _val); \
 893                 __fill_bkt->h = (__fill_idx); \
 894                 __fill_bkt->key = NULL; \
 895                 __fill_bkt++; \
 896                 __fill_idx++; \
 897         } while (0)
 898 
 899 #define ZEND_HASH_FILL_END() \
 900                 __fill_ht->nNumUsed = __fill_idx; \
 901                 __fill_ht->nNumOfElements = __fill_idx; \
 902                 __fill_ht->nNextFreeElement = __fill_idx; \
 903                 __fill_ht->nInternalPointer = __fill_idx ? 0 : HT_INVALID_IDX; \
 904         } while (0)
 905 
 906 static zend_always_inline zval *_zend_hash_append(HashTable *ht, zend_string *key, zval *zv)
 907 {
 908         uint32_t idx = ht->nNumUsed++;
 909         uint32_t nIndex;
 910         Bucket *p = ht->arData + idx;
 911 
 912         ZVAL_COPY_VALUE(&p->val, zv);
 913         if (!ZSTR_IS_INTERNED(key)) {
 914                 ht->u.flags &= ~HASH_FLAG_STATIC_KEYS;
 915                 zend_string_addref(key);
 916                 zend_string_hash_val(key);              
 917         }
 918         p->key = key;
 919         p->h = ZSTR_H(key);
 920         nIndex = (uint32_t)p->h | ht->nTableMask;
 921         Z_NEXT(p->val) = HT_HASH(ht, nIndex);
 922         HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
 923         ht->nNumUsed = idx + 1;
 924         ht->nNumOfElements++;
 925         return &p->val;
 926 }
 927 
 928 static zend_always_inline zval *_zend_hash_append_ptr(HashTable *ht, zend_string *key, void *ptr)
 929 {
 930         uint32_t idx = ht->nNumUsed++;
 931         uint32_t nIndex;
 932         Bucket *p = ht->arData + idx;
 933 
 934         ZVAL_PTR(&p->val, ptr);
 935         if (!ZSTR_IS_INTERNED(key)) {
 936                 ht->u.flags &= ~HASH_FLAG_STATIC_KEYS;
 937                 zend_string_addref(key);
 938                 zend_string_hash_val(key);              
 939         }
 940         p->key = key;
 941         p->h = ZSTR_H(key);
 942         nIndex = (uint32_t)p->h | ht->nTableMask;
 943         Z_NEXT(p->val) = HT_HASH(ht, nIndex);
 944         HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
 945         ht->nNumUsed = idx + 1;
 946         ht->nNumOfElements++;
 947         return &p->val;
 948 }
 949 
 950 static zend_always_inline void _zend_hash_append_ind(HashTable *ht, zend_string *key, zval *ptr)
 951 {
 952         uint32_t idx = ht->nNumUsed++;
 953         uint32_t nIndex;
 954         Bucket *p = ht->arData + idx;
 955 
 956         ZVAL_INDIRECT(&p->val, ptr);
 957         if (!ZSTR_IS_INTERNED(key)) {
 958                 ht->u.flags &= ~HASH_FLAG_STATIC_KEYS;
 959                 zend_string_addref(key);
 960                 zend_string_hash_val(key);              
 961         }
 962         p->key = key;
 963         p->h = ZSTR_H(key);
 964         nIndex = (uint32_t)p->h | ht->nTableMask;
 965         Z_NEXT(p->val) = HT_HASH(ht, nIndex);
 966         HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
 967         ht->nNumUsed = idx + 1;
 968         ht->nNumOfElements++;
 969 }
 970 
 971 #endif                                                  /* ZEND_HASH_H */
 972 
 973 /*
 974  * Local variables:
 975  * tab-width: 4
 976  * c-basic-offset: 4
 977  * indent-tabs-mode: t
 978  * End:
 979  */

/* [<][>][^][v][top][bottom][index][help] */