php  7.3.12
About: PHP 7.3.x - a server-side, cross-platform, html-embedded scripting language to create dynamic web pages.
  Fossies Dox: php-7.3.12.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

zend_hash.c File Reference
#include "zend.h"
#include "zend_globals.h"
#include "zend_variables.h"
Include dependency graph for zend_hash.c:

Go to the source code of this file.

Macros

#define HT_ASSERT(ht, expr)
 
#define HT_ASSERT_RC1(ht)   HT_ASSERT(ht, GC_REFCOUNT(ht) == 1)
 
#define HT_POISONED_PTR   ((HashTable *) (intptr_t) -1)
 
#define IS_CONSISTENT(a)
 
#define SET_INCONSISTENT(n)
 
#define ZEND_HASH_IF_FULL_DO_RESIZE(ht)
 

Functions

static void zend_hash_do_resize (HashTable *ht)
 
static uint32_t zend_hash_check_size (uint32_t nSize)
 
static void zend_hash_real_init_packed_ex (HashTable *ht)
 
static void zend_hash_real_init_mixed_ex (HashTable *ht)
 
static void zend_hash_real_init_ex (HashTable *ht, int packed)
 
static void _zend_hash_init_int (HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
 
ZEND_API void _zend_hash_init (HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
 
ZEND_API HashTable_zend_new_array_0 (void)
 
ZEND_API HashTable_zend_new_array (uint32_t nSize)
 
static void zend_hash_packed_grow (HashTable *ht)
 
ZEND_API void zend_hash_real_init (HashTable *ht, zend_bool packed)
 
ZEND_API void zend_hash_real_init_packed (HashTable *ht)
 
ZEND_API void zend_hash_real_init_mixed (HashTable *ht)
 
ZEND_API void zend_hash_packed_to_hash (HashTable *ht)
 
ZEND_API void zend_hash_to_packed (HashTable *ht)
 
ZEND_API void zend_hash_extend (HashTable *ht, uint32_t nSize, zend_bool packed)
 
ZEND_API void zend_hash_discard (HashTable *ht, uint32_t nNumUsed)
 
static uint32_t zend_array_recalc_elements (HashTable *ht)
 
ZEND_API uint32_t zend_array_count (HashTable *ht)
 
static HashPosition _zend_hash_get_valid_pos (const HashTable *ht, HashPosition pos)
 
static HashPosition _zend_hash_get_current_pos (const HashTable *ht)
 
ZEND_API HashPosition zend_hash_get_current_pos (const HashTable *ht)
 
ZEND_API uint32_t zend_hash_iterator_add (HashTable *ht, HashPosition pos)
 
ZEND_API HashPosition zend_hash_iterator_pos (uint32_t idx, HashTable *ht)
 
ZEND_API HashPosition zend_hash_iterator_pos_ex (uint32_t idx, zval *array)
 
ZEND_API void zend_hash_iterator_del (uint32_t idx)
 
static void _zend_hash_iterators_remove (HashTable *ht)
 
static void zend_hash_iterators_remove (HashTable *ht)
 
ZEND_API HashPosition zend_hash_iterators_lower_pos (HashTable *ht, HashPosition start)
 
ZEND_API void _zend_hash_iterators_update (HashTable *ht, HashPosition from, HashPosition to)
 
ZEND_API void zend_hash_iterators_advance (HashTable *ht, HashPosition step)
 
static Bucketzend_hash_find_bucket (const HashTable *ht, zend_string *key, zend_bool known_hash)
 
static Bucketzend_hash_str_find_bucket (const HashTable *ht, const char *str, size_t len, zend_ulong h)
 
static Bucketzend_hash_index_find_bucket (const HashTable *ht, zend_ulong h)
 
static zval_zend_hash_add_or_update_i (HashTable *ht, zend_string *key, zval *pData, uint32_t flag)
 
static zval_zend_hash_str_add_or_update_i (HashTable *ht, const char *str, size_t len, zend_ulong h, zval *pData, uint32_t flag)
 
ZEND_API zvalzend_hash_add_or_update (HashTable *ht, zend_string *key, zval *pData, uint32_t flag)
 
ZEND_API zvalzend_hash_add (HashTable *ht, zend_string *key, zval *pData)
 
ZEND_API zvalzend_hash_update (HashTable *ht, zend_string *key, zval *pData)
 
ZEND_API zvalzend_hash_update_ind (HashTable *ht, zend_string *key, zval *pData)
 
ZEND_API zvalzend_hash_add_new (HashTable *ht, zend_string *key, zval *pData)
 
ZEND_API zvalzend_hash_str_add_or_update (HashTable *ht, const char *str, size_t len, zval *pData, uint32_t flag)
 
ZEND_API zvalzend_hash_str_update (HashTable *ht, const char *str, size_t len, zval *pData)
 
ZEND_API zvalzend_hash_str_update_ind (HashTable *ht, const char *str, size_t len, zval *pData)
 
ZEND_API zvalzend_hash_str_add (HashTable *ht, const char *str, size_t len, zval *pData)
 
ZEND_API zvalzend_hash_str_add_new (HashTable *ht, const char *str, size_t len, zval *pData)
 
ZEND_API zvalzend_hash_index_add_empty_element (HashTable *ht, zend_ulong h)
 
ZEND_API zvalzend_hash_add_empty_element (HashTable *ht, zend_string *key)
 
ZEND_API zvalzend_hash_str_add_empty_element (HashTable *ht, const char *str, size_t len)
 
static zval_zend_hash_index_add_or_update_i (HashTable *ht, zend_ulong h, zval *pData, uint32_t flag)
 
ZEND_API zvalzend_hash_index_add_or_update (HashTable *ht, zend_ulong h, zval *pData, uint32_t flag)
 
ZEND_API zvalzend_hash_index_add (HashTable *ht, zend_ulong h, zval *pData)
 
ZEND_API zvalzend_hash_index_add_new (HashTable *ht, zend_ulong h, zval *pData)
 
ZEND_API zvalzend_hash_index_update (HashTable *ht, zend_ulong h, zval *pData)
 
ZEND_API zvalzend_hash_next_index_insert (HashTable *ht, zval *pData)
 
ZEND_API zvalzend_hash_next_index_insert_new (HashTable *ht, zval *pData)
 
ZEND_API int zend_hash_rehash (HashTable *ht)
 
static void _zend_hash_del_el_ex (HashTable *ht, uint32_t idx, Bucket *p, Bucket *prev)
 
static void _zend_hash_del_el (HashTable *ht, uint32_t idx, Bucket *p)
 
ZEND_API void zend_hash_del_bucket (HashTable *ht, Bucket *p)
 
ZEND_API int zend_hash_del (HashTable *ht, zend_string *key)
 
ZEND_API int zend_hash_del_ind (HashTable *ht, zend_string *key)
 
ZEND_API int zend_hash_str_del_ind (HashTable *ht, const char *str, size_t len)
 
ZEND_API int zend_hash_str_del (HashTable *ht, const char *str, size_t len)
 
ZEND_API int zend_hash_index_del (HashTable *ht, zend_ulong h)
 
ZEND_API void zend_hash_destroy (HashTable *ht)
 
ZEND_API void zend_array_destroy (HashTable *ht)
 
ZEND_API void zend_hash_clean (HashTable *ht)
 
ZEND_API void zend_symtable_clean (HashTable *ht)
 
ZEND_API void zend_hash_graceful_destroy (HashTable *ht)
 
ZEND_API void zend_hash_graceful_reverse_destroy (HashTable *ht)
 
ZEND_API void zend_hash_apply (HashTable *ht, apply_func_t apply_func)
 
ZEND_API void zend_hash_apply_with_argument (HashTable *ht, apply_func_arg_t apply_func, void *argument)
 
ZEND_API void zend_hash_apply_with_arguments (HashTable *ht, apply_func_args_t apply_func, int num_args,...)
 
ZEND_API void zend_hash_reverse_apply (HashTable *ht, apply_func_t apply_func)
 
ZEND_API void zend_hash_copy (HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor)
 
static int zend_array_dup_element (HashTable *source, HashTable *target, uint32_t idx, Bucket *p, Bucket *q, int packed, int static_keys, int with_holes)
 
static void zend_array_dup_packed_elements (HashTable *source, HashTable *target, int with_holes)
 
static uint32_t zend_array_dup_elements (HashTable *source, HashTable *target, int static_keys, int with_holes)
 
ZEND_API HashTablezend_array_dup (HashTable *source)
 
ZEND_API void zend_hash_merge (HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, zend_bool overwrite)
 
static zend_bool zend_hash_replace_checker_wrapper (HashTable *target, zval *source_data, Bucket *p, void *pParam, merge_checker_func_t merge_checker_func)
 
ZEND_API void zend_hash_merge_ex (HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor, merge_checker_func_t pMergeSource, void *pParam)
 
ZEND_API zvalzend_hash_find (const HashTable *ht, zend_string *key)
 
ZEND_API zval_zend_hash_find_known_hash (const HashTable *ht, zend_string *key)
 
ZEND_API zvalzend_hash_str_find (const HashTable *ht, const char *str, size_t len)
 
ZEND_API zend_bool zend_hash_exists (const HashTable *ht, zend_string *key)
 
ZEND_API zend_bool zend_hash_str_exists (const HashTable *ht, const char *str, size_t len)
 
ZEND_API zvalzend_hash_index_find (const HashTable *ht, zend_ulong h)
 
ZEND_API zval_zend_hash_index_find (const HashTable *ht, zend_ulong h)
 
ZEND_API zend_bool zend_hash_index_exists (const HashTable *ht, zend_ulong h)
 
ZEND_API void zend_hash_internal_pointer_reset_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API void zend_hash_internal_pointer_end_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API int zend_hash_move_forward_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API int zend_hash_move_backwards_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API int zend_hash_get_current_key_ex (const HashTable *ht, zend_string **str_index, zend_ulong *num_index, HashPosition *pos)
 
ZEND_API void zend_hash_get_current_key_zval_ex (const HashTable *ht, zval *key, HashPosition *pos)
 
ZEND_API int zend_hash_get_current_key_type_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API zvalzend_hash_get_current_data_ex (HashTable *ht, HashPosition *pos)
 
ZEND_API void zend_hash_bucket_swap (Bucket *p, Bucket *q)
 
ZEND_API void zend_hash_bucket_renum_swap (Bucket *p, Bucket *q)
 
ZEND_API void zend_hash_bucket_packed_swap (Bucket *p, Bucket *q)
 
ZEND_API int zend_hash_sort_ex (HashTable *ht, sort_func_t sort, compare_func_t compar, zend_bool renumber)
 
static int zend_hash_compare_impl (HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered)
 
ZEND_API int zend_hash_compare (HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered)
 
ZEND_API zvalzend_hash_minmax (const HashTable *ht, compare_func_t compar, uint32_t flag)
 
ZEND_API int _zend_handle_numeric_str_ex (const char *key, size_t length, zend_ulong *idx)
 
ZEND_API HashTablezend_symtable_to_proptable (HashTable *ht)
 
ZEND_API HashTablezend_proptable_to_symtable (HashTable *ht, zend_bool always_duplicate)
 

Variables

static const uint32_t uninitialized_bucket [-((uint32_t) -2)]
 
const ZEND_API HashTable zend_empty_array
 

Macro Definition Documentation

◆ HT_ASSERT

#define HT_ASSERT (   ht,
  expr 
)

Definition at line 34 of file zend_hash.c.

◆ HT_ASSERT_RC1

#define HT_ASSERT_RC1 (   ht)    HT_ASSERT(ht, GC_REFCOUNT(ht) == 1)

Definition at line 37 of file zend_hash.c.

◆ HT_POISONED_PTR

#define HT_POISONED_PTR   ((HashTable *) (intptr_t) -1)

Definition at line 39 of file zend_hash.c.

◆ IS_CONSISTENT

#define IS_CONSISTENT (   a)

Definition at line 74 of file zend_hash.c.

◆ SET_INCONSISTENT

#define SET_INCONSISTENT (   n)

Definition at line 75 of file zend_hash.c.

◆ ZEND_HASH_IF_FULL_DO_RESIZE

#define ZEND_HASH_IF_FULL_DO_RESIZE (   ht)
Value:
if ((ht)->nNumUsed >= (ht)->nTableSize) { \
zend_hash_do_resize(ht); \
}

Definition at line 78 of file zend_hash.c.

Function Documentation

◆ _zend_handle_numeric_str_ex()

ZEND_API int _zend_handle_numeric_str_ex ( const char *  key,
size_t  length,
zend_ulong idx 
)

Definition at line 2598 of file zend_hash.c.

2599 {
2600  register const char *tmp = key;
2601 
2602  const char *end = key + length;
2603 
2604  if (*tmp == '-') {
2605  tmp++;
2606  }
2607 
2608  if ((*tmp == '0' && length > 1) /* numbers with leading zeros */
2609  || (end - tmp > MAX_LENGTH_OF_LONG - 1) /* number too long */
2610  || (SIZEOF_ZEND_LONG == 4 &&
2611  end - tmp == MAX_LENGTH_OF_LONG - 1 &&
2612  *tmp > '2')) { /* overflow */
2613  return 0;
2614  }
2615  *idx = (*tmp - '0');
2616  while (1) {
2617  ++tmp;
2618  if (tmp == end) {
2619  if (*key == '-') {
2620  if (*idx-1 > ZEND_LONG_MAX) { /* overflow */
2621  return 0;
2622  }
2623  *idx = 0 - *idx;
2624  } else if (*idx > ZEND_LONG_MAX) { /* overflow */
2625  return 0;
2626  }
2627  return 1;
2628  }
2629  if (*tmp <= '9' && *tmp >= '0') {
2630  *idx = (*idx * 10) + (*tmp - '0');
2631  } else {
2632  return 0;
2633  }
2634  }
2635 }

References MAX_LENGTH_OF_LONG, SIZEOF_ZEND_LONG, tmp, and ZEND_LONG_MAX.

Referenced by _zend_handle_numeric_str().

◆ _zend_hash_add_or_update_i()

static zval* _zend_hash_add_or_update_i ( HashTable ht,
zend_string key,
zval pData,
uint32_t  flag 
)
inlinestatic

Definition at line 644 of file zend_hash.c.

645 {
646  zend_ulong h;
647  uint32_t nIndex;
648  uint32_t idx;
649  Bucket *p, *arData;
650 
651  IS_CONSISTENT(ht);
652  HT_ASSERT_RC1(ht);
653 
654  if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
656  if (!ZSTR_IS_INTERNED(key)) {
657  zend_string_addref(key);
660  }
661  goto add_to_hash;
662  } else if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
664  if (!ZSTR_IS_INTERNED(key)) {
665  zend_string_addref(key);
668  }
669  } else if ((flag & HASH_ADD_NEW) == 0) {
670  p = zend_hash_find_bucket(ht, key, 0);
671 
672  if (p) {
673  zval *data;
674 
675  if (flag & HASH_ADD) {
676  if (!(flag & HASH_UPDATE_INDIRECT)) {
677  return NULL;
678  }
679  ZEND_ASSERT(&p->val != pData);
680  data = &p->val;
681  if (Z_TYPE_P(data) == IS_INDIRECT) {
682  data = Z_INDIRECT_P(data);
683  if (Z_TYPE_P(data) != IS_UNDEF) {
684  return NULL;
685  }
686  } else {
687  return NULL;
688  }
689  } else {
690  ZEND_ASSERT(&p->val != pData);
691  data = &p->val;
692  if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) {
693  data = Z_INDIRECT_P(data);
694  }
695  }
696  if (ht->pDestructor) {
697  ht->pDestructor(data);
698  }
699  ZVAL_COPY_VALUE(data, pData);
700  return data;
701  }
702  if (!ZSTR_IS_INTERNED(key)) {
703  zend_string_addref(key);
705  }
706  } else if (!ZSTR_IS_INTERNED(key)) {
707  zend_string_addref(key);
710  }
711 
712  ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
713 
714 add_to_hash:
715  idx = ht->nNumUsed++;
716  ht->nNumOfElements++;
717  arData = ht->arData;
718  p = arData + idx;
719  p->key = key;
720  p->h = h = ZSTR_H(key);
721  nIndex = h | ht->nTableMask;
722  Z_NEXT(p->val) = HT_HASH_EX(arData, nIndex);
723  HT_HASH_EX(arData, nIndex) = HT_IDX_TO_HASH(idx);
724  ZVAL_COPY_VALUE(&p->val, pData);
725 
726  return &p->val;
727 }

References _zend_array::arData, _Bucket::h, HASH_ADD, HASH_ADD_NEW, HASH_FLAG_INITIALIZED, HASH_FLAG_PACKED, HASH_FLAG_STATIC_KEYS, HASH_UPDATE_INDIRECT, HT_ASSERT_RC1, HT_FLAGS, HT_HASH_EX, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, NULL, _zend_array::pDestructor, UNEXPECTED, _Bucket::val, Z_INDIRECT_P, Z_NEXT, Z_TYPE_P, ZEND_ASSERT(), zend_hash_find_bucket(), ZEND_HASH_IF_FULL_DO_RESIZE, zend_hash_packed_to_hash(), zend_hash_real_init_mixed(), zend_string_addref(), zend_string_hash_val(), ZSTR_H, ZSTR_IS_INTERNED, and ZVAL_COPY_VALUE.

Referenced by zend_hash_add(), zend_hash_add_new(), zend_hash_merge(), zend_hash_update(), and zend_hash_update_ind().

Here is the call graph for this function:

◆ _zend_hash_del_el()

static void _zend_hash_del_el ( HashTable ht,
uint32_t  idx,
Bucket p 
)
inlinestatic

Definition at line 1188 of file zend_hash.c.

1189 {
1190  Bucket *prev = NULL;
1191 
1192  if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED)) {
1193  uint32_t nIndex = p->h | ht->nTableMask;
1194  uint32_t i = HT_HASH(ht, nIndex);
1195 
1196  if (i != idx) {
1197  prev = HT_HASH_TO_BUCKET(ht, i);
1198  while (Z_NEXT(prev->val) != idx) {
1199  i = Z_NEXT(prev->val);
1200  prev = HT_HASH_TO_BUCKET(ht, i);
1201  }
1202  }
1203  }
1204 
1205  _zend_hash_del_el_ex(ht, idx, p, prev);
1206 }

References _zend_hash_del_el_ex(), _Bucket::h, HASH_FLAG_PACKED, HT_FLAGS, HT_HASH, HT_HASH_TO_BUCKET, _zend_array::nTableMask, NULL, _Bucket::val, and Z_NEXT.

Referenced by zend_hash_apply(), zend_hash_apply_with_argument(), zend_hash_apply_with_arguments(), zend_hash_del_bucket(), zend_hash_graceful_destroy(), zend_hash_graceful_reverse_destroy(), and zend_hash_reverse_apply().

Here is the call graph for this function:

◆ _zend_hash_del_el_ex()

static void _zend_hash_del_el_ex ( HashTable ht,
uint32_t  idx,
Bucket p,
Bucket prev 
)
inlinestatic

Definition at line 1141 of file zend_hash.c.

1142 {
1143  if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED)) {
1144  if (prev) {
1145  Z_NEXT(prev->val) = Z_NEXT(p->val);
1146  } else {
1147  HT_HASH(ht, p->h | ht->nTableMask) = Z_NEXT(p->val);
1148  }
1149  }
1150  idx = HT_HASH_TO_IDX(idx);
1151  ht->nNumOfElements--;
1152  if (ht->nInternalPointer == idx || UNEXPECTED(HT_HAS_ITERATORS(ht))) {
1153  uint32_t new_idx;
1154 
1155  new_idx = idx;
1156  while (1) {
1157  new_idx++;
1158  if (new_idx >= ht->nNumUsed) {
1159  break;
1160  } else if (Z_TYPE(ht->arData[new_idx].val) != IS_UNDEF) {
1161  break;
1162  }
1163  }
1164  if (ht->nInternalPointer == idx) {
1165  ht->nInternalPointer = new_idx;
1166  }
1167  zend_hash_iterators_update(ht, idx, new_idx);
1168  }
1169  if (ht->nNumUsed - 1 == idx) {
1170  do {
1171  ht->nNumUsed--;
1172  } while (ht->nNumUsed > 0 && (UNEXPECTED(Z_TYPE(ht->arData[ht->nNumUsed-1].val) == IS_UNDEF)));
1174  }
1175  if (p->key) {
1176  zend_string_release(p->key);
1177  }
1178  if (ht->pDestructor) {
1179  zval tmp;
1180  ZVAL_COPY_VALUE(&tmp, &p->val);
1181  ZVAL_UNDEF(&p->val);
1182  ht->pDestructor(&tmp);
1183  } else {
1184  ZVAL_UNDEF(&p->val);
1185  }
1186 }

References _zend_array::arData, _Bucket::h, HASH_FLAG_PACKED, HT_FLAGS, HT_HAS_ITERATORS, HT_HASH, IS_UNDEF, _Bucket::key, MIN, _zend_array::nInternalPointer, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::pDestructor, tmp, UNEXPECTED, _Bucket::val, Z_NEXT, Z_TYPE, zend_hash_iterators_update(), ZVAL_COPY_VALUE, and ZVAL_UNDEF.

Referenced by _zend_hash_del_el(), zend_hash_del(), zend_hash_del_ind(), zend_hash_index_del(), zend_hash_str_del(), and zend_hash_str_del_ind().

Here is the call graph for this function:

◆ _zend_hash_find_known_hash()

ZEND_API zval* _zend_hash_find_known_hash ( const HashTable ht,
zend_string key 
)

Definition at line 2096 of file zend_hash.c.

2097 {
2098  Bucket *p;
2099 
2100  IS_CONSISTENT(ht);
2101 
2102  p = zend_hash_find_bucket(ht, key, 1);
2103  return p ? &p->val : NULL;
2104 }

References IS_CONSISTENT, NULL, _Bucket::val, and zend_hash_find_bucket().

Referenced by zend_hash_find_ex().

Here is the call graph for this function:

◆ _zend_hash_get_current_pos()

static HashPosition _zend_hash_get_current_pos ( const HashTable ht)
inlinestatic

Definition at line 388 of file zend_hash.c.

389 {
391 }

References _zend_hash_get_valid_pos(), and _zend_array::nInternalPointer.

Referenced by zend_hash_get_current_pos(), zend_hash_iterator_pos(), and zend_hash_iterator_pos_ex().

Here is the call graph for this function:

◆ _zend_hash_get_valid_pos()

static HashPosition _zend_hash_get_valid_pos ( const HashTable ht,
HashPosition  pos 
)
inlinestatic

◆ _zend_hash_index_add_or_update_i()

static zval* _zend_hash_index_add_or_update_i ( HashTable ht,
zend_ulong  h,
zval pData,
uint32_t  flag 
)
inlinestatic

Definition at line 896 of file zend_hash.c.

897 {
898  uint32_t nIndex;
899  uint32_t idx;
900  Bucket *p;
901 
902  IS_CONSISTENT(ht);
903  HT_ASSERT_RC1(ht);
904 
905  if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
906  if (h < ht->nNumUsed) {
907  p = ht->arData + h;
908  if (Z_TYPE(p->val) != IS_UNDEF) {
909 replace:
910  if (flag & HASH_ADD) {
911  return NULL;
912  }
913  if (ht->pDestructor) {
914  ht->pDestructor(&p->val);
915  }
916  ZVAL_COPY_VALUE(&p->val, pData);
917  return &p->val;
918  } else { /* we have to keep the order :( */
919  goto convert_to_hash;
920  }
921  } else if (EXPECTED(h < ht->nTableSize)) {
922 add_to_packed:
923  p = ht->arData + h;
924  /* incremental initialization of empty Buckets */
926  if (h > ht->nNumUsed) {
927  Bucket *q = ht->arData + ht->nNumUsed;
928  while (q != p) {
929  ZVAL_UNDEF(&q->val);
930  q++;
931  }
932  }
933  }
934  ht->nNextFreeElement = ht->nNumUsed = h + 1;
935  goto add;
936  } else if ((h >> 1) < ht->nTableSize &&
937  (ht->nTableSize >> 1) < ht->nNumOfElements) {
939  goto add_to_packed;
940  } else {
941  if (ht->nNumUsed >= ht->nTableSize) {
942  ht->nTableSize += ht->nTableSize;
943  }
944 convert_to_hash:
946  }
947  } else if (!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED)) {
948  if (h < ht->nTableSize) {
950  goto add_to_packed;
951  }
953  } else {
954  if ((flag & HASH_ADD_NEW) == 0) {
955  p = zend_hash_index_find_bucket(ht, h);
956  if (p) {
957  goto replace;
958  }
959  }
960  ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
961  }
962 
963  idx = ht->nNumUsed++;
964  nIndex = h | ht->nTableMask;
965  p = ht->arData + idx;
966  Z_NEXT(p->val) = HT_HASH(ht, nIndex);
967  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
968  if ((zend_long)h >= (zend_long)ht->nNextFreeElement) {
969  ht->nNextFreeElement = h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX;
970  }
971 add:
972  ht->nNumOfElements++;
973  p->h = h;
974  p->key = NULL;
975  ZVAL_COPY_VALUE(&p->val, pData);
976 
977  return &p->val;
978 }

References _zend_array::arData, EXPECTED, _Bucket::h, HASH_ADD, HASH_ADD_NEW, HASH_ADD_NEXT, HASH_FLAG_INITIALIZED, HASH_FLAG_PACKED, HT_ASSERT_RC1, HT_FLAGS, HT_HASH, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, NULL, _zend_array::pDestructor, _Bucket::val, Z_NEXT, Z_TYPE, ZEND_HASH_IF_FULL_DO_RESIZE, zend_hash_index_find_bucket(), zend_hash_packed_grow(), zend_hash_packed_to_hash(), zend_hash_real_init_mixed(), zend_hash_real_init_packed_ex(), ZEND_LONG_MAX, ZVAL_COPY_VALUE, and ZVAL_UNDEF.

Referenced by zend_hash_index_add(), zend_hash_index_add_new(), zend_hash_index_update(), zend_hash_next_index_insert(), and zend_hash_next_index_insert_new().

Here is the call graph for this function:

◆ _zend_hash_index_find()

ZEND_API zval* _zend_hash_index_find ( const HashTable ht,
zend_ulong  h 
)

Definition at line 2160 of file zend_hash.c.

2161 {
2162  Bucket *p;
2163 
2164  IS_CONSISTENT(ht);
2165 
2166  p = zend_hash_index_find_bucket(ht, h);
2167  return p ? &p->val : NULL;
2168 }

References IS_CONSISTENT, NULL, _Bucket::val, and zend_hash_index_find_bucket().

Here is the call graph for this function:

◆ _zend_hash_init()

ZEND_API void _zend_hash_init ( HashTable ht,
uint32_t  nSize,
dtor_func_t  pDestructor,
zend_bool  persistent 
)

Definition at line 210 of file zend_hash.c.

211 {
212  _zend_hash_init_int(ht, nSize, pDestructor, persistent);
213 }

References _zend_hash_init_int().

Referenced by _zend_ts_hash_init().

Here is the call graph for this function:

◆ _zend_hash_init_int()

static void _zend_hash_init_int ( HashTable ht,
uint32_t  nSize,
dtor_func_t  pDestructor,
zend_bool  persistent 
)
inlinestatic

Definition at line 195 of file zend_hash.c.

196 {
197  GC_SET_REFCOUNT(ht, 1);
200  ht->nTableMask = HT_MIN_MASK;
202  ht->nNumUsed = 0;
203  ht->nNumOfElements = 0;
204  ht->nInternalPointer = 0;
205  ht->nNextFreeElement = 0;
206  ht->pDestructor = pDestructor;
207  ht->nTableSize = zend_hash_check_size(nSize);
208 }

References GC_COLLECTABLE, GC_FLAGS_SHIFT, GC_PERSISTENT, GC_SET_REFCOUNT, GC_TYPE_INFO, HASH_FLAG_STATIC_KEYS, HT_FLAGS, HT_MIN_MASK, HT_SET_DATA_ADDR, IS_ARRAY, _zend_array::nInternalPointer, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, _zend_array::pDestructor, uninitialized_bucket, and zend_hash_check_size().

Referenced by _zend_hash_init(), _zend_new_array(), and _zend_new_array_0().

Here is the call graph for this function:

◆ _zend_hash_iterators_remove()

static void _zend_hash_iterators_remove ( HashTable ht)
static

Definition at line 497 of file zend_hash.c.

498 {
499  HashTableIterator *iter = EG(ht_iterators);
500  HashTableIterator *end = iter + EG(ht_iterators_used);
501 
502  while (iter != end) {
503  if (iter->ht == ht) {
504  iter->ht = HT_POISONED_PTR;
505  }
506  iter++;
507  }
508 }

References EG(), _HashTableIterator::ht, and HT_POISONED_PTR.

Referenced by zend_hash_iterators_remove().

Here is the call graph for this function:

◆ _zend_hash_iterators_update()

ZEND_API void _zend_hash_iterators_update ( HashTable ht,
HashPosition  from,
HashPosition  to 
)

Definition at line 534 of file zend_hash.c.

535 {
536  HashTableIterator *iter = EG(ht_iterators);
537  HashTableIterator *end = iter + EG(ht_iterators_used);
538 
539  while (iter != end) {
540  if (iter->ht == ht && iter->pos == from) {
541  iter->pos = to;
542  }
543  iter++;
544  }
545 }

References EG(), _HashTableIterator::ht, and _HashTableIterator::pos.

Referenced by zend_hash_iterators_update(), and zend_hash_rehash().

Here is the call graph for this function:

◆ _zend_hash_str_add_or_update_i()

static zval* _zend_hash_str_add_or_update_i ( HashTable ht,
const char *  str,
size_t  len,
zend_ulong  h,
zval pData,
uint32_t  flag 
)
inlinestatic

Definition at line 729 of file zend_hash.c.

730 {
731  zend_string *key;
732  uint32_t nIndex;
733  uint32_t idx;
734  Bucket *p;
735 
736  IS_CONSISTENT(ht);
737  HT_ASSERT_RC1(ht);
738 
739  if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
741  goto add_to_hash;
742  } else if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
744  } else if ((flag & HASH_ADD_NEW) == 0) {
745  p = zend_hash_str_find_bucket(ht, str, len, h);
746 
747  if (p) {
748  zval *data;
749 
750  if (flag & HASH_ADD) {
751  if (!(flag & HASH_UPDATE_INDIRECT)) {
752  return NULL;
753  }
754  ZEND_ASSERT(&p->val != pData);
755  data = &p->val;
756  if (Z_TYPE_P(data) == IS_INDIRECT) {
757  data = Z_INDIRECT_P(data);
758  if (Z_TYPE_P(data) != IS_UNDEF) {
759  return NULL;
760  }
761  } else {
762  return NULL;
763  }
764  } else {
765  ZEND_ASSERT(&p->val != pData);
766  data = &p->val;
767  if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) {
768  data = Z_INDIRECT_P(data);
769  }
770  }
771  if (ht->pDestructor) {
772  ht->pDestructor(data);
773  }
774  ZVAL_COPY_VALUE(data, pData);
775  return data;
776  }
777  }
778 
779  ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
780 
781 add_to_hash:
782  idx = ht->nNumUsed++;
783  ht->nNumOfElements++;
784  p = ht->arData + idx;
785  p->key = key = zend_string_init(str, len, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
786  p->h = ZSTR_H(key) = h;
788  ZVAL_COPY_VALUE(&p->val, pData);
789  nIndex = h | ht->nTableMask;
790  Z_NEXT(p->val) = HT_HASH(ht, nIndex);
791  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx);
792 
793  return &p->val;
794 }

References _zend_array::arData, GC_FLAGS, _Bucket::h, HASH_ADD, HASH_ADD_NEW, HASH_FLAG_INITIALIZED, HASH_FLAG_PACKED, HASH_FLAG_STATIC_KEYS, HASH_UPDATE_INDIRECT, HT_ASSERT_RC1, HT_FLAGS, HT_HASH, IS_ARRAY_PERSISTENT, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, len, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, NULL, _zend_array::pDestructor, UNEXPECTED, _Bucket::val, Z_INDIRECT_P, Z_NEXT, Z_TYPE_P, ZEND_ASSERT(), ZEND_HASH_IF_FULL_DO_RESIZE, zend_hash_packed_to_hash(), zend_hash_real_init_mixed(), zend_hash_str_find_bucket(), zend_string_init(), ZSTR_H, and ZVAL_COPY_VALUE.

Referenced by zend_hash_str_add(), zend_hash_str_add_new(), zend_hash_str_update(), and zend_hash_str_update_ind().

Here is the call graph for this function:

◆ _zend_new_array()

ZEND_API HashTable* _zend_new_array ( uint32_t  nSize)

Definition at line 222 of file zend_hash.c.

223 {
224  HashTable *ht = emalloc(sizeof(HashTable));
225  _zend_hash_init_int(ht, nSize, ZVAL_PTR_DTOR, 0);
226  return ht;
227 }

References _zend_hash_init_int(), emalloc, and ZVAL_PTR_DTOR.

Here is the call graph for this function:

◆ _zend_new_array_0()

ZEND_API HashTable* _zend_new_array_0 ( void  )

Definition at line 215 of file zend_hash.c.

216 {
217  HashTable *ht = emalloc(sizeof(HashTable));
219  return ht;
220 }

References _zend_hash_init_int(), emalloc, HT_MIN_SIZE, and ZVAL_PTR_DTOR.

Here is the call graph for this function:

◆ zend_array_count()

ZEND_API uint32_t zend_array_count ( HashTable ht)

Definition at line 363 of file zend_hash.c.

364 {
365  uint32_t num;
367  num = zend_array_recalc_elements(ht);
368  if (UNEXPECTED(ht->nNumOfElements == num)) {
370  }
371  } else if (UNEXPECTED(ht == &EG(symbol_table))) {
372  num = zend_array_recalc_elements(ht);
373  } else {
374  num = zend_hash_num_elements(ht);
375  }
376  return num;
377 }

References EG(), HASH_FLAG_HAS_EMPTY_IND, HT_FLAGS, _zend_array::nNumOfElements, UNEXPECTED, zend_array_recalc_elements(), and zend_hash_num_elements.

Referenced by ZEND_COUNT_SPEC_CONST_UNUSED_HANDLER(), ZEND_COUNT_SPEC_CV_UNUSED_HANDLER(), ZEND_COUNT_SPEC_TMP_UNUSED_HANDLER(), ZEND_COUNT_SPEC_VAR_UNUSED_HANDLER(), and ZEND_VM_COLD_CONST_HANDLER().

Here is the call graph for this function:

◆ zend_array_destroy()

ZEND_API void zend_array_destroy ( HashTable ht)

Definition at line 1464 of file zend_hash.c.

1465 {
1466  Bucket *p, *end;
1467 
1468  IS_CONSISTENT(ht);
1469  HT_ASSERT(ht, GC_REFCOUNT(ht) <= 1);
1470 
1471  /* break possible cycles */
1473  GC_TYPE_INFO(ht) = IS_NULL /*???| (GC_WHITE << 16)*/;
1474 
1475  if (ht->nNumUsed) {
1476  /* In some rare cases destructors of regular arrays may be changed */
1477  if (UNEXPECTED(ht->pDestructor != ZVAL_PTR_DTOR)) {
1478  zend_hash_destroy(ht);
1479  goto free_ht;
1480  }
1481 
1482  p = ht->arData;
1483  end = p + ht->nNumUsed;
1484  SET_INCONSISTENT(HT_IS_DESTROYING);
1485 
1486  if (HT_HAS_STATIC_KEYS_ONLY(ht)) {
1487  do {
1489  } while (++p != end);
1490  } else if (HT_IS_WITHOUT_HOLES(ht)) {
1491  do {
1493  if (EXPECTED(p->key)) {
1494  zend_string_release_ex(p->key, 0);
1495  }
1496  } while (++p != end);
1497  } else {
1498  do {
1499  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1501  if (EXPECTED(p->key)) {
1502  zend_string_release_ex(p->key, 0);
1503  }
1504  }
1505  } while (++p != end);
1506  }
1508  SET_INCONSISTENT(HT_DESTROYED);
1509  } else if (EXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
1510  goto free_ht;
1511  }
1512  efree(HT_GET_DATA_ADDR(ht));
1513 free_ht:
1514  FREE_HASHTABLE(ht);
1515 }

References _zend_array::arData, efree, EXPECTED, FREE_HASHTABLE, GC_REFCOUNT, GC_REMOVE_FROM_BUFFER, GC_TYPE_INFO, HASH_FLAG_INITIALIZED, HT_ASSERT, HT_FLAGS, HT_GET_DATA_ADDR, HT_HAS_STATIC_KEYS_ONLY, HT_IS_WITHOUT_HOLES, i_zval_ptr_dtor(), IS_CONSISTENT, IS_NULL, IS_UNDEF, _Bucket::key, _zend_array::nNumUsed, _zend_array::pDestructor, SET_INCONSISTENT, UNEXPECTED, _Bucket::val, Z_TYPE, ZEND_FILE_LINE_CC, zend_hash_destroy(), zend_hash_iterators_remove(), and ZVAL_PTR_DTOR.

Referenced by cgi_php_import_environment_variables(), destroy_op_array(), php_register_variable_ex(), phpdbg_webdata_compress(), zend_clean_and_cache_symbol_table(), zend_compile_func_in_array(), and zend_object_std_dtor().

Here is the call graph for this function:

◆ zend_array_dup()

ZEND_API HashTable* zend_array_dup ( HashTable source)

Definition at line 1917 of file zend_hash.c.

1918 {
1919  uint32_t idx;
1920  HashTable *target;
1921 
1922  IS_CONSISTENT(source);
1923 
1925  GC_SET_REFCOUNT(target, 1);
1927 
1928  target->nTableSize = source->nTableSize;
1929  target->pDestructor = ZVAL_PTR_DTOR;
1930 
1931  if (source->nNumOfElements == 0) {
1933  HT_FLAGS(target) = (HT_FLAGS(source) & mask) | HASH_FLAG_STATIC_KEYS;
1934  target->nTableMask = HT_MIN_MASK;
1935  target->nNumUsed = 0;
1936  target->nNumOfElements = 0;
1937  target->nNextFreeElement = 0;
1938  target->nInternalPointer = 0;
1940  } else if (GC_FLAGS(source) & IS_ARRAY_IMMUTABLE) {
1941  HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
1942  target->nTableMask = source->nTableMask;
1943  target->nNumUsed = source->nNumUsed;
1944  target->nNumOfElements = source->nNumOfElements;
1945  target->nNextFreeElement = source->nNextFreeElement;
1947  target->nInternalPointer = source->nInternalPointer;
1949  } else if (HT_FLAGS(source) & HASH_FLAG_PACKED) {
1950  HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
1951  target->nTableMask = HT_MIN_MASK;
1952  target->nNumUsed = source->nNumUsed;
1953  target->nNumOfElements = source->nNumOfElements;
1954  target->nNextFreeElement = source->nNextFreeElement;
1956  target->nInternalPointer =
1957  (source->nInternalPointer < source->nNumUsed) ?
1958  source->nInternalPointer : 0;
1959 
1961 
1962  if (HT_IS_WITHOUT_HOLES(target)) {
1964  } else {
1966  }
1967  } else {
1968  HT_FLAGS(target) = HT_FLAGS(source) & HASH_FLAG_MASK;
1969  target->nTableMask = source->nTableMask;
1970  target->nNextFreeElement = source->nNextFreeElement;
1971  target->nInternalPointer =
1972  (source->nInternalPointer < source->nNumUsed) ?
1973  source->nInternalPointer : 0;
1974 
1977 
1979  if (HT_IS_WITHOUT_HOLES(source)) {
1980  idx = zend_array_dup_elements(source, target, 1, 0);
1981  } else {
1982  idx = zend_array_dup_elements(source, target, 1, 1);
1983  }
1984  } else {
1985  if (HT_IS_WITHOUT_HOLES(source)) {
1986  idx = zend_array_dup_elements(source, target, 0, 0);
1987  } else {
1988  idx = zend_array_dup_elements(source, target, 0, 1);
1989  }
1990  }
1991  target->nNumUsed = idx;
1992  target->nNumOfElements = idx;
1993  }
1994  return target;
1995 }

References ALLOC_HASHTABLE, emalloc, GC_COLLECTABLE, GC_FLAGS, GC_FLAGS_SHIFT, GC_SET_REFCOUNT, GC_TYPE_INFO, HASH_FLAG_INITIALIZED, HASH_FLAG_MASK, HASH_FLAG_PACKED, HASH_FLAG_STATIC_KEYS, HT_FLAGS, HT_GET_DATA_ADDR, HT_HAS_STATIC_KEYS_ONLY, HT_HASH_RESET, HT_HASH_RESET_PACKED, HT_IS_WITHOUT_HOLES, HT_MIN_MASK, HT_SET_DATA_ADDR, HT_SIZE, HT_SIZE_EX, HT_USED_SIZE, IS_ARRAY, IS_ARRAY_IMMUTABLE, IS_CONSISTENT, memcpy, _zend_array::nInternalPointer, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, target, uninitialized_bucket, zend_array_dup_elements(), zend_array_dup_packed_elements(), and ZVAL_PTR_DTOR.

Referenced by add_function_array(), cgi_php_import_environment_variables(), convert_to_object(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_BIND_STATIC_SPEC_CV_CONST_HANDLER(), ZEND_CAST_SPEC_CONST_HANDLER(), ZEND_CAST_SPEC_CV_HANDLER(), ZEND_CAST_SPEC_TMP_HANDLER(), ZEND_CAST_SPEC_VAR_HANDLER(), zend_closure_get_debug_info(), zend_compile_closure_binding(), zend_compile_static_var_common(), zend_create_closure(), zend_error(), ZEND_FE_RESET_R_SPEC_CONST_HANDLER(), ZEND_FE_RESET_R_SPEC_CV_HANDLER(), ZEND_FE_RESET_R_SPEC_TMP_HANDLER(), ZEND_FE_RESET_R_SPEC_VAR_HANDLER(), ZEND_FE_RESET_RW_SPEC_CONST_HANDLER(), ZEND_FE_RESET_RW_SPEC_CV_HANDLER(), ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(), ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(), zend_fetch_property_address(), zend_parse_arg_array_ht(), zend_proptable_to_symtable(), zend_std_get_debug_info(), zend_std_get_gc(), zend_std_get_property_ptr_ptr(), zend_std_unset_property(), zend_std_write_property(), ZEND_VM_C_LABEL(), ZEND_VM_COLD_CONST_HANDLER(), ZEND_VM_HANDLER(), zif_get_defined_vars(), zval_copy_ctor(), and zval_opt_copy_ctor().

Here is the call graph for this function:

◆ zend_array_dup_element()

static int zend_array_dup_element ( HashTable source,
HashTable target,
uint32_t  idx,
Bucket p,
Bucket q,
int  packed,
int  static_keys,
int  with_holes 
)
inlinestatic

Definition at line 1819 of file zend_hash.c.

1820 {
1821  zval *data = &p->val;
1822 
1823  if (with_holes) {
1824  if (!packed && Z_TYPE_INFO_P(data) == IS_INDIRECT) {
1825  data = Z_INDIRECT_P(data);
1826  }
1827  if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) {
1828  return 0;
1829  }
1830  } else if (!packed) {
1831  /* INDIRECT element may point to UNDEF-ined slots */
1832  if (Z_TYPE_INFO_P(data) == IS_INDIRECT) {
1833  data = Z_INDIRECT_P(data);
1834  if (UNEXPECTED(Z_TYPE_INFO_P(data) == IS_UNDEF)) {
1835  return 0;
1836  }
1837  }
1838  }
1839 
1840  do {
1841  if (Z_OPT_REFCOUNTED_P(data)) {
1842  if (Z_ISREF_P(data) && Z_REFCOUNT_P(data) == 1 &&
1843  (Z_TYPE_P(Z_REFVAL_P(data)) != IS_ARRAY ||
1844  Z_ARRVAL_P(Z_REFVAL_P(data)) != source)) {
1845  data = Z_REFVAL_P(data);
1846  if (!Z_OPT_REFCOUNTED_P(data)) {
1847  break;
1848  }
1849  }
1850  Z_ADDREF_P(data);
1851  }
1852  } while (0);
1853  ZVAL_COPY_VALUE(&q->val, data);
1854 
1855  q->h = p->h;
1856  if (packed) {
1857  q->key = NULL;
1858  } else {
1859  uint32_t nIndex;
1860 
1861  q->key = p->key;
1862  if (!static_keys && q->key) {
1863  zend_string_addref(q->key);
1864  }
1865 
1866  nIndex = q->h | target->nTableMask;
1867  Z_NEXT(q->val) = HT_HASH(target, nIndex);
1868  HT_HASH(target, nIndex) = HT_IDX_TO_HASH(idx);
1869  }
1870  return 1;
1871 }

References _Bucket::h, HT_HASH, IS_ARRAY, IS_INDIRECT, IS_UNDEF, _Bucket::key, NULL, target, UNEXPECTED, _Bucket::val, Z_ADDREF_P, Z_ARRVAL_P, Z_INDIRECT_P, Z_ISREF_P, Z_NEXT, Z_OPT_REFCOUNTED_P, Z_REFCOUNT_P, Z_REFVAL_P, Z_TYPE_INFO_P, Z_TYPE_P, zend_string_addref(), and ZVAL_COPY_VALUE.

Referenced by zend_array_dup_elements(), and zend_array_dup_packed_elements().

Here is the call graph for this function:

◆ zend_array_dup_elements()

static uint32_t zend_array_dup_elements ( HashTable source,
HashTable target,
int  static_keys,
int  with_holes 
)
inlinestatic

Definition at line 1889 of file zend_hash.c.

1890 {
1891  uint32_t idx = 0;
1892  Bucket *p = source->arData;
1893  Bucket *q = target->arData;
1894  Bucket *end = p + source->nNumUsed;
1895 
1896  do {
1897  if (!zend_array_dup_element(source, target, idx, p, q, 0, static_keys, with_holes)) {
1898  uint32_t target_idx = idx;
1899 
1900  idx++; p++;
1901  while (p != end) {
1902  if (zend_array_dup_element(source, target, target_idx, p, q, 0, static_keys, with_holes)) {
1903  if (source->nInternalPointer == idx) {
1904  target->nInternalPointer = target_idx;
1905  }
1906  target_idx++; q++;
1907  }
1908  idx++; p++;
1909  }
1910  return target_idx;
1911  }
1912  idx++; p++; q++;
1913  } while (p != end);
1914  return idx;
1915 }

References _zend_array::arData, _zend_array::nInternalPointer, _zend_array::nNumUsed, target, and zend_array_dup_element().

Referenced by zend_array_dup().

Here is the call graph for this function:

◆ zend_array_dup_packed_elements()

static void zend_array_dup_packed_elements ( HashTable source,
HashTable target,
int  with_holes 
)
inlinestatic

Definition at line 1873 of file zend_hash.c.

1874 {
1875  Bucket *p = source->arData;
1876  Bucket *q = target->arData;
1877  Bucket *end = p + source->nNumUsed;
1878 
1879  do {
1880  if (!zend_array_dup_element(source, target, 0, p, q, 1, 1, with_holes)) {
1881  if (with_holes) {
1882  ZVAL_UNDEF(&q->val);
1883  }
1884  }
1885  p++; q++;
1886  } while (p != end);
1887 }

References _zend_array::arData, _zend_array::nNumUsed, target, _Bucket::val, zend_array_dup_element(), and ZVAL_UNDEF.

Referenced by zend_array_dup().

Here is the call graph for this function:

◆ zend_array_recalc_elements()

static uint32_t zend_array_recalc_elements ( HashTable ht)
static

Definition at line 347 of file zend_hash.c.

348 {
349  zval *val;
350  uint32_t num = ht->nNumOfElements;
351 
352  ZEND_HASH_FOREACH_VAL(ht, val) {
353  if (Z_TYPE_P(val) == IS_INDIRECT) {
354  if (UNEXPECTED(Z_TYPE_P(Z_INDIRECT_P(val)) == IS_UNDEF)) {
355  num--;
356  }
357  }
359  return num;
360 }

References IS_INDIRECT, IS_UNDEF, _zend_array::nNumOfElements, UNEXPECTED, Z_INDIRECT_P, Z_TYPE_P, ZEND_HASH_FOREACH_END, and ZEND_HASH_FOREACH_VAL.

Referenced by zend_array_count().

◆ zend_hash_add()

ZEND_API zval* zend_hash_add ( HashTable ht,
zend_string key,
zval pData 
)

Definition at line 810 of file zend_hash.c.

811 {
812  return _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD);
813 }

References _zend_hash_add_or_update_i(), and HASH_ADD.

Referenced by fcgi_set_mgmt_var(), LoadDirectory(), merge_php_config(), phpdbg_webdata_compress(), rebuild_object_properties(), zend_compile_closure_binding(), zend_compile_func_in_array(), zend_compile_switch(), zend_hash_add_empty_element(), zend_hash_add_mem(), zend_hash_add_or_update(), zend_hash_add_ptr(), and zend_ts_hash_add().

Here is the call graph for this function:

◆ zend_hash_add_empty_element()

ZEND_API zval* zend_hash_add_empty_element ( HashTable ht,
zend_string key 
)

Definition at line 880 of file zend_hash.c.

881 {
882  zval dummy;
883 
884  ZVAL_NULL(&dummy);
885  return zend_hash_add(ht, key, &dummy);
886 }

References zend_hash_add(), and ZVAL_NULL().

Referenced by compile_filename(), php_execute_script(), PHP_FUNCTION(), zend_execute_scripts(), zend_include_or_eval(), zend_lookup_class_ex(), zend_traits_init_trait_structures(), and zend_ts_hash_add_empty_element().

Here is the call graph for this function:

◆ zend_hash_add_new()

ZEND_API zval* zend_hash_add_new ( HashTable ht,
zend_string key,
zval pData 
)

Definition at line 825 of file zend_hash.c.

826 {
827  return _zend_hash_add_or_update_i(ht, key, pData, HASH_ADD_NEW);
828 }

References _zend_hash_add_or_update_i(), and HASH_ADD_NEW.

Referenced by add_class_vars(), add_constant_info(), convert_to_object(), copy_constant_array(), phpdbg_add_empty_array(), zend_add_interned_string(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_OBJ_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(), zend_attach_symbol_table(), ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(), ZEND_CAST_SPEC_CONST_HANDLER(), ZEND_CAST_SPEC_CV_HANDLER(), ZEND_CAST_SPEC_TMP_HANDLER(), ZEND_CAST_SPEC_VAR_HANDLER(), zend_fetch_debug_backtrace(), zend_fetch_dimension_address_inner(), zend_fetch_var_address_helper_SPEC_CONST_UNUSED(), zend_fetch_var_address_helper_SPEC_CV_UNUSED(), zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(), zend_hash_add_new_mem(), zend_hash_add_new_ptr(), zend_hash_add_or_update(), zend_register_seen_symbol(), zend_set_compiled_filename(), zend_std_write_property(), zend_symtable_add_new(), ZEND_VM_C_LABEL(), ZEND_VM_COLD_CONST_HANDLER(), ZEND_VM_HELPER(), ZEND_VM_HOT_HANDLER(), zif_each(), and zif_get_defined_constants().

Here is the call graph for this function:

◆ zend_hash_add_or_update()

ZEND_API zval* zend_hash_add_or_update ( HashTable ht,
zend_string key,
zval pData,
uint32_t  flag 
)

Definition at line 796 of file zend_hash.c.

797 {
798  if (flag == HASH_ADD) {
799  return zend_hash_add(ht, key, pData);
800  } else if (flag == HASH_ADD_NEW) {
801  return zend_hash_add_new(ht, key, pData);
802  } else if (flag == HASH_UPDATE) {
803  return zend_hash_update(ht, key, pData);
804  } else {
806  return zend_hash_update_ind(ht, key, pData);
807  }
808 }

References HASH_ADD, HASH_ADD_NEW, HASH_UPDATE, HASH_UPDATE_INDIRECT, ZEND_ASSERT(), zend_hash_add(), zend_hash_add_new(), zend_hash_update(), and zend_hash_update_ind().

Here is the call graph for this function:

◆ zend_hash_apply()

ZEND_API void zend_hash_apply ( HashTable ht,
apply_func_t  apply_func 
)

Definition at line 1678 of file zend_hash.c.

1679 {
1680  uint32_t idx;
1681  Bucket *p;
1682  int result;
1683 
1684  IS_CONSISTENT(ht);
1685 
1686  for (idx = 0; idx < ht->nNumUsed; idx++) {
1687  p = ht->arData + idx;
1688  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1689  result = apply_func(&p->val);
1690 
1692  HT_ASSERT_RC1(ht);
1693  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1694  }
1695  if (result & ZEND_HASH_APPLY_STOP) {
1696  break;
1697  }
1698  }
1699 }

References _zend_hash_del_el(), _zend_array::arData, HT_ASSERT_RC1, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumUsed, result, UNEXPECTED, _Bucket::val, Z_TYPE, ZEND_HASH_APPLY_REMOVE, and ZEND_HASH_APPLY_STOP.

Referenced by destroy_uploaded_files_hash(), PHP_RSHUTDOWN_FUNCTION(), phpdbg_do_dl(), phpdbg_print_symbols(), phpdbg_webdata_decompress(), print_modules(), zend_ini_deactivate(), zend_post_deactivate_modules(), zend_startup_modules(), and zend_ts_hash_apply().

Here is the call graph for this function:

◆ zend_hash_apply_with_argument()

ZEND_API void zend_hash_apply_with_argument ( HashTable ht,
apply_func_arg_t  apply_func,
void *  argument 
)

Definition at line 1702 of file zend_hash.c.

1703 {
1704  uint32_t idx;
1705  Bucket *p;
1706  int result;
1707 
1708  IS_CONSISTENT(ht);
1709 
1710  for (idx = 0; idx < ht->nNumUsed; idx++) {
1711  p = ht->arData + idx;
1712  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1713  result = apply_func(&p->val, argument);
1714 
1716  HT_ASSERT_RC1(ht);
1717  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1718  }
1719  if (result & ZEND_HASH_APPLY_STOP) {
1720  break;
1721  }
1722  }
1723 }

References _zend_hash_del_el(), _zend_array::arData, HT_ASSERT_RC1, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumUsed, result, UNEXPECTED, _Bucket::val, Z_TYPE, ZEND_HASH_APPLY_REMOVE, and ZEND_HASH_APPLY_STOP.

Referenced by _php_stream_free(), clean_module_classes(), clean_module_constants(), display_ini_entries(), zend_clean_module_rsrc_dtors(), zend_clean_module_rsrc_dtors_cb(), zend_ts_hash_apply_with_argument(), zend_unregister_ini_entries(), zif_get_defined_constants(), and zif_get_loaded_extensions().

Here is the call graph for this function:

◆ zend_hash_apply_with_arguments()

ZEND_API void zend_hash_apply_with_arguments ( HashTable ht,
apply_func_args_t  apply_func,
int  num_args,
  ... 
)

Definition at line 1726 of file zend_hash.c.

1727 {
1728  uint32_t idx;
1729  Bucket *p;
1730  va_list args;
1731  zend_hash_key hash_key;
1732  int result;
1733 
1734  IS_CONSISTENT(ht);
1735 
1736  for (idx = 0; idx < ht->nNumUsed; idx++) {
1737  p = ht->arData + idx;
1738  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1739  va_start(args, num_args);
1740  hash_key.h = p->h;
1741  hash_key.key = p->key;
1742 
1743  result = apply_func(&p->val, num_args, args, &hash_key);
1744 
1746  HT_ASSERT_RC1(ht);
1747  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1748  }
1749  if (result & ZEND_HASH_APPLY_STOP) {
1750  va_end(args);
1751  break;
1752  }
1753  va_end(args);
1754  }
1755 }

References _zend_hash_del_el(), _zend_array::arData, _zend_hash_key::h, _Bucket::h, HT_ASSERT_RC1, IS_CONSISTENT, IS_UNDEF, _zend_hash_key::key, _Bucket::key, _zend_array::nNumUsed, result, UNEXPECTED, _Bucket::val, Z_TYPE, ZEND_HASH_APPLY_REMOVE, and ZEND_HASH_APPLY_STOP.

Referenced by phpdbg_xml_var_dump(), sapi_cli_server_register_variables(), zend_ts_hash_apply_with_arguments(), zif_get_declared_classes(), zif_get_declared_interfaces(), zif_get_declared_traits(), and zif_get_defined_functions().

Here is the call graph for this function:

◆ zend_hash_bucket_packed_swap()

ZEND_API void zend_hash_bucket_packed_swap ( Bucket p,
Bucket q 
)

Definition at line 2370 of file zend_hash.c.

2371 {
2372  zval val;
2373  zend_ulong h;
2374 
2375  ZVAL_COPY_VALUE(&val, &p->val);
2376  h = p->h;
2377 
2378  ZVAL_COPY_VALUE(&p->val, &q->val);
2379  p->h = q->h;
2380 
2381  ZVAL_COPY_VALUE(&q->val, &val);
2382  q->h = h;
2383 }

References _Bucket::h, _Bucket::val, and ZVAL_COPY_VALUE.

Referenced by zend_hash_sort_ex().

◆ zend_hash_bucket_renum_swap()

ZEND_API void zend_hash_bucket_renum_swap ( Bucket p,
Bucket q 
)

Definition at line 2361 of file zend_hash.c.

2362 {
2363  zval val;
2364 
2365  ZVAL_COPY_VALUE(&val, &p->val);
2366  ZVAL_COPY_VALUE(&p->val, &q->val);
2367  ZVAL_COPY_VALUE(&q->val, &val);
2368 }

References _Bucket::val, and ZVAL_COPY_VALUE.

Referenced by zend_hash_sort_ex().

◆ zend_hash_bucket_swap()

ZEND_API void zend_hash_bucket_swap ( Bucket p,
Bucket q 
)

Definition at line 2342 of file zend_hash.c.

2343 {
2344  zval val;
2345  zend_ulong h;
2346  zend_string *key;
2347 
2348  ZVAL_COPY_VALUE(&val, &p->val);
2349  h = p->h;
2350  key = p->key;
2351 
2352  ZVAL_COPY_VALUE(&p->val, &q->val);
2353  p->h = q->h;
2354  p->key = q->key;
2355 
2356  ZVAL_COPY_VALUE(&q->val, &val);
2357  q->h = h;
2358  q->key = key;
2359 }

References _Bucket::h, _Bucket::key, _Bucket::val, and ZVAL_COPY_VALUE.

Referenced by zend_hash_sort_ex().

◆ zend_hash_check_size()

static uint32_t zend_hash_check_size ( uint32_t  nSize)
inlinestatic

Definition at line 85 of file zend_hash.c.

86 {
87 #if defined(ZEND_WIN32)
88  unsigned long index;
89 #endif
90 
91  /* Use big enough power of 2 */
92  /* size should be between HT_MIN_SIZE and HT_MAX_SIZE */
93  if (nSize <= HT_MIN_SIZE) {
94  return HT_MIN_SIZE;
95  } else if (UNEXPECTED(nSize >= HT_MAX_SIZE)) {
96  zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", nSize, sizeof(Bucket), sizeof(Bucket));
97  }
98 
99 #if defined(ZEND_WIN32)
100  if (BitScanReverse(&index, nSize - 1)) {
101  return 0x2 << ((31 - index) ^ 0x1f);
102  } else {
103  /* nSize is ensured to be in the valid range, fall back to it
104  rather than using an undefined bis scan result. */
105  return nSize;
106  }
107 #elif (defined(__GNUC__) || __has_builtin(__builtin_clz)) && defined(PHP_HAVE_BUILTIN_CLZ)
108  return 0x2 << (__builtin_clz(nSize - 1) ^ 0x1f);
109 #else
110  nSize -= 1;
111  nSize |= (nSize >> 1);
112  nSize |= (nSize >> 2);
113  nSize |= (nSize >> 4);
114  nSize |= (nSize >> 8);
115  nSize |= (nSize >> 16);
116  return nSize + 1;
117 #endif
118 }

References E_ERROR, HT_MIN_SIZE, UNEXPECTED, and zend_error_noreturn.

Referenced by _zend_hash_init_int(), and zend_hash_extend().

◆ zend_hash_clean()

ZEND_API void zend_hash_clean ( HashTable ht)

Definition at line 1517 of file zend_hash.c.

1518 {
1519  Bucket *p, *end;
1520 
1521  IS_CONSISTENT(ht);
1522  HT_ASSERT_RC1(ht);
1523 
1524  if (ht->nNumUsed) {
1525  p = ht->arData;
1526  end = p + ht->nNumUsed;
1527  if (ht->pDestructor) {
1528  if (HT_HAS_STATIC_KEYS_ONLY(ht)) {
1529  if (HT_IS_WITHOUT_HOLES(ht)) {
1530  do {
1531  ht->pDestructor(&p->val);
1532  } while (++p != end);
1533  } else {
1534  do {
1535  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1536  ht->pDestructor(&p->val);
1537  }
1538  } while (++p != end);
1539  }
1540  } else if (HT_IS_WITHOUT_HOLES(ht)) {
1541  do {
1542  ht->pDestructor(&p->val);
1543  if (EXPECTED(p->key)) {
1544  zend_string_release(p->key);
1545  }
1546  } while (++p != end);
1547  } else {
1548  do {
1549  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1550  ht->pDestructor(&p->val);
1551  if (EXPECTED(p->key)) {
1552  zend_string_release(p->key);
1553  }
1554  }
1555  } while (++p != end);
1556  }
1557  } else {
1558  if (!HT_HAS_STATIC_KEYS_ONLY(ht)) {
1559  if (HT_IS_WITHOUT_HOLES(ht)) {
1560  do {
1561  if (EXPECTED(p->key)) {
1562  zend_string_release(p->key);
1563  }
1564  } while (++p != end);
1565  } else {
1566  do {
1567  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1568  if (EXPECTED(p->key)) {
1569  zend_string_release(p->key);
1570  }
1571  }
1572  } while (++p != end);
1573  }
1574  }
1575  }
1576  if (!(HT_FLAGS(ht) & HASH_FLAG_PACKED)) {
1577  HT_HASH_RESET(ht);
1578  }
1579  }
1580  ht->nNumUsed = 0;
1581  ht->nNumOfElements = 0;
1582  ht->nNextFreeElement = 0;
1583  ht->nInternalPointer = 0;
1584 }

References _zend_array::arData, EXPECTED, HASH_FLAG_PACKED, HT_ASSERT_RC1, HT_FLAGS, HT_HAS_STATIC_KEYS_ONLY, HT_HASH_RESET, HT_IS_WITHOUT_HOLES, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nInternalPointer, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::pDestructor, _Bucket::val, and Z_TYPE.

Referenced by php_cgi_ini_activate_user_config(), PHP_FUNCTION(), phpdbg_clear_breakpoints(), phpdbg_dequeue_elements_for_recreation(), phpdbg_do_finish(), phpdbg_do_leave(), phpdbg_do_run(), phpdbg_execute_ex(), phpdbg_reenable_memory_watches(), phpdbg_webdata_decompress(), UpdateIniFromRegistry(), and zend_ts_hash_clean().

◆ zend_hash_compare()

ZEND_API int zend_hash_compare ( HashTable ht1,
HashTable ht2,
compare_func_t  compar,
zend_bool  ordered 
)

Definition at line 2531 of file zend_hash.c.

2532 {
2533  int result;
2534  IS_CONSISTENT(ht1);
2535  IS_CONSISTENT(ht2);
2536 
2537  if (ht1 == ht2) {
2538  return 0;
2539  }
2540 
2541  /* It's enough to protect only one of the arrays.
2542  * The second one may be referenced from the first and this may cause
2543  * false recursion detection.
2544  */
2545  if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) {
2546  zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
2547  }
2548 
2549  if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
2550  GC_PROTECT_RECURSION(ht1);
2551  }
2552  result = zend_hash_compare_impl(ht1, ht2, compar, ordered);
2553  if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) {
2555  }
2556 
2557  return result;
2558 }

References E_ERROR, GC_FLAGS, GC_IMMUTABLE, GC_IS_RECURSIVE, GC_PROTECT_RECURSION, GC_UNPROTECT_RECURSION, IS_CONSISTENT, result, UNEXPECTED, zend_error_noreturn, and zend_hash_compare_impl().

Referenced by zend_compare_symbol_tables(), zend_is_identical(), and zend_ts_hash_compare().

Here is the call graph for this function:

◆ zend_hash_compare_impl()

static int zend_hash_compare_impl ( HashTable ht1,
HashTable ht2,
compare_func_t  compar,
zend_bool  ordered 
)
inlinestatic

Definition at line 2453 of file zend_hash.c.

2453  {
2454  uint32_t idx1, idx2;
2455 
2456  if (ht1->nNumOfElements != ht2->nNumOfElements) {
2457  return ht1->nNumOfElements > ht2->nNumOfElements ? 1 : -1;
2458  }
2459 
2460  for (idx1 = 0, idx2 = 0; idx1 < ht1->nNumUsed; idx1++) {
2461  Bucket *p1 = ht1->arData + idx1, *p2;
2462  zval *pData1, *pData2;
2463  int result;
2464 
2465  if (Z_TYPE(p1->val) == IS_UNDEF) continue;
2466  if (ordered) {
2467  while (1) {
2468  ZEND_ASSERT(idx2 != ht2->nNumUsed);
2469  p2 = ht2->arData + idx2;
2470  if (Z_TYPE(p2->val) != IS_UNDEF) break;
2471  idx2++;
2472  }
2473  if (p1->key == NULL && p2->key == NULL) { /* numeric indices */
2474  if (p1->h != p2->h) {
2475  return p1->h > p2->h ? 1 : -1;
2476  }
2477  } else if (p1->key != NULL && p2->key != NULL) { /* string indices */
2478  if (ZSTR_LEN(p1->key) != ZSTR_LEN(p2->key)) {
2479  return ZSTR_LEN(p1->key) > ZSTR_LEN(p2->key) ? 1 : -1;
2480  }
2481 
2482  result = memcmp(ZSTR_VAL(p1->key), ZSTR_VAL(p2->key), ZSTR_LEN(p1->key));
2483  if (result != 0) {
2484  return result;
2485  }
2486  } else {
2487  /* Mixed key types: A string key is considered as larger */
2488  return p1->key != NULL ? 1 : -1;
2489  }
2490  pData2 = &p2->val;
2491  idx2++;
2492  } else {
2493  if (p1->key == NULL) { /* numeric index */
2494  pData2 = zend_hash_index_find(ht2, p1->h);
2495  if (pData2 == NULL) {
2496  return 1;
2497  }
2498  } else { /* string index */
2499  pData2 = zend_hash_find(ht2, p1->key);
2500  if (pData2 == NULL) {
2501  return 1;
2502  }
2503  }
2504  }
2505 
2506  pData1 = &p1->val;
2507  if (Z_TYPE_P(pData1) == IS_INDIRECT) {
2508  pData1 = Z_INDIRECT_P(pData1);
2509  }
2510  if (Z_TYPE_P(pData2) == IS_INDIRECT) {
2511  pData2 = Z_INDIRECT_P(pData2);
2512  }
2513 
2514  if (Z_TYPE_P(pData1) == IS_UNDEF) {
2515  if (Z_TYPE_P(pData2) != IS_UNDEF) {
2516  return -1;
2517  }
2518  } else if (Z_TYPE_P(pData2) == IS_UNDEF) {
2519  return 1;
2520  } else {
2521  result = compar(pData1, pData2);
2522  if (result != 0) {
2523  return result;
2524  }
2525  }
2526  }
2527 
2528  return 0;
2529 }

References _zend_array::arData, _Bucket::h, IS_INDIRECT, IS_UNDEF, _Bucket::key, _zend_array::nNumOfElements, _zend_array::nNumUsed, NULL, result, _Bucket::val, Z_INDIRECT_P, Z_TYPE, Z_TYPE_P, ZEND_ASSERT(), zend_hash_find(), zend_hash_index_find(), ZSTR_LEN, and ZSTR_VAL.

Referenced by zend_hash_compare().

Here is the call graph for this function:

◆ zend_hash_copy()

ZEND_API void zend_hash_copy ( HashTable target,
HashTable source,
copy_ctor_func_t  pCopyConstructor 
)

Definition at line 1785 of file zend_hash.c.

1786 {
1787  uint32_t idx;
1788  Bucket *p;
1789  zval *new_entry, *data;
1790 
1791  IS_CONSISTENT(source);
1794 
1795  for (idx = 0; idx < source->nNumUsed; idx++) {
1796  p = source->arData + idx;
1797  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1798 
1799  /* INDIRECT element may point to UNDEF-ined slots */
1800  data = &p->val;
1801  if (Z_TYPE_P(data) == IS_INDIRECT) {
1802  data = Z_INDIRECT_P(data);
1803  if (UNEXPECTED(Z_TYPE_P(data) == IS_UNDEF)) {
1804  continue;
1805  }
1806  }
1807  if (p->key) {
1808  new_entry = zend_hash_update(target, p->key, data);
1809  } else {
1810  new_entry = zend_hash_index_update(target, p->h, data);
1811  }
1812  if (pCopyConstructor) {
1813  pCopyConstructor(new_entry);
1814  }
1815  }
1816 }

References _zend_array::arData, _Bucket::h, HT_ASSERT_RC1, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, _zend_array::nNumUsed, target, UNEXPECTED, _Bucket::val, Z_INDIRECT_P, Z_TYPE, Z_TYPE_P, zend_hash_index_update(), and zend_hash_update().

Referenced by clone_wrapper_hash(), merge_php_config(), php_stream_filter_register_factory_volatile(), php_stream_temp_set_option(), phpdbg_webdata_compress(), print_modules(), zend_ts_hash_copy(), and zend_ts_hash_copy_to_hash().

Here is the call graph for this function:

◆ zend_hash_del()

ZEND_API int zend_hash_del ( HashTable ht,
zend_string key 
)

Definition at line 1215 of file zend_hash.c.

1216 {
1217  zend_ulong h;
1218  uint32_t nIndex;
1219  uint32_t idx;
1220  Bucket *p;
1221  Bucket *prev = NULL;
1222 
1223  IS_CONSISTENT(ht);
1224  HT_ASSERT_RC1(ht);
1225 
1226  h = zend_string_hash_val(key);
1227  nIndex = h | ht->nTableMask;
1228 
1229  idx = HT_HASH(ht, nIndex);
1230  while (idx != HT_INVALID_IDX) {
1231  p = HT_HASH_TO_BUCKET(ht, idx);
1232  if ((p->key == key) ||
1233  (p->h == h &&
1234  p->key &&
1235  zend_string_equal_content(p->key, key))) {
1236  _zend_hash_del_el_ex(ht, idx, p, prev);
1237  return SUCCESS;
1238  }
1239  prev = p;
1240  idx = Z_NEXT(p->val);
1241  }
1242  return FAILURE;
1243 }

References _zend_hash_del_el_ex(), FAILURE, _Bucket::h, HT_ASSERT_RC1, HT_HASH, HT_HASH_TO_BUCKET, HT_INVALID_IDX, IS_CONSISTENT, _Bucket::key, _zend_array::nTableMask, NULL, SUCCESS, _Bucket::val, Z_NEXT, and zend_string_hash_val().

Referenced by php_unregister_url_stream_wrapper_volatile(), phpdbg_clean_watch_element(), phpdbg_compile(), phpdbg_compile_file(), phpdbg_compile_stdin(), phpdbg_delete_breakpoint(), phpdbg_register_file_handles(), phpdbg_resolve_pending_file_break_ex(), phpdbg_unwatch_parent_ht(), phpdbg_update_watch_element_watch(), phpdbg_webdata_decompress(), zend_detach_symbol_table(), zend_do_early_binding(), zend_do_traits_property_binding(), zend_lookup_class_ex(), zend_register_module_ex(), zend_restore_ini_entry(), zend_std_unset_property(), zend_symtable_del(), zend_ts_hash_del(), zend_unregister_functions(), ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(), ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(), ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_del_bucket()

ZEND_API void zend_hash_del_bucket ( HashTable ht,
Bucket p 
)

Definition at line 1208 of file zend_hash.c.

1209 {
1210  IS_CONSISTENT(ht);
1211  HT_ASSERT_RC1(ht);
1212  _zend_hash_del_el(ht, HT_IDX_TO_HASH(p - ht->arData), p);
1213 }

References _zend_hash_del_el(), _zend_array::arData, HT_ASSERT_RC1, and IS_CONSISTENT.

Here is the call graph for this function:

◆ zend_hash_del_ind()

ZEND_API int zend_hash_del_ind ( HashTable ht,
zend_string key 
)

Definition at line 1245 of file zend_hash.c.

1246 {
1247  zend_ulong h;
1248  uint32_t nIndex;
1249  uint32_t idx;
1250  Bucket *p;
1251  Bucket *prev = NULL;
1252 
1253  IS_CONSISTENT(ht);
1254  HT_ASSERT_RC1(ht);
1255 
1256  h = zend_string_hash_val(key);
1257  nIndex = h | ht->nTableMask;
1258 
1259  idx = HT_HASH(ht, nIndex);
1260  while (idx != HT_INVALID_IDX) {
1261  p = HT_HASH_TO_BUCKET(ht, idx);
1262  if ((p->key == key) ||
1263  (p->h == h &&
1264  p->key &&
1265  zend_string_equal_content(p->key, key))) {
1266  if (Z_TYPE(p->val) == IS_INDIRECT) {
1267  zval *data = Z_INDIRECT(p->val);
1268 
1269  if (UNEXPECTED(Z_TYPE_P(data) == IS_UNDEF)) {
1270  return FAILURE;
1271  } else {
1272  if (ht->pDestructor) {
1273  zval tmp;
1274  ZVAL_COPY_VALUE(&tmp, data);
1275  ZVAL_UNDEF(data);
1276  ht->pDestructor(&tmp);
1277  } else {
1278  ZVAL_UNDEF(data);
1279  }
1281  }
1282  } else {
1283  _zend_hash_del_el_ex(ht, idx, p, prev);
1284  }
1285  return SUCCESS;
1286  }
1287  prev = p;
1288  idx = Z_NEXT(p->val);
1289  }
1290  return FAILURE;
1291 }

References _zend_hash_del_el_ex(), FAILURE, _Bucket::h, HASH_FLAG_HAS_EMPTY_IND, HT_ASSERT_RC1, HT_FLAGS, HT_HASH, HT_HASH_TO_BUCKET, HT_INVALID_IDX, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, _zend_array::nTableMask, NULL, _zend_array::pDestructor, SUCCESS, tmp, UNEXPECTED, _Bucket::val, Z_INDIRECT, Z_NEXT, Z_TYPE, Z_TYPE_P, zend_string_hash_val(), ZVAL_COPY_VALUE, and ZVAL_UNDEF.

Referenced by zend_delete_global_variable(), zend_symtable_del_ind(), ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(), ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(), ZEND_UNSET_VAR_SPEC_TMPVAR_UNUSED_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_destroy()

ZEND_API void zend_hash_destroy ( HashTable ht)

Definition at line 1402 of file zend_hash.c.

1403 {
1404  Bucket *p, *end;
1405 
1406  IS_CONSISTENT(ht);
1407  HT_ASSERT(ht, GC_REFCOUNT(ht) <= 1);
1408 
1409  if (ht->nNumUsed) {
1410  p = ht->arData;
1411  end = p + ht->nNumUsed;
1412  if (ht->pDestructor) {
1413  SET_INCONSISTENT(HT_IS_DESTROYING);
1414 
1415  if (HT_HAS_STATIC_KEYS_ONLY(ht)) {
1416  if (HT_IS_WITHOUT_HOLES(ht)) {
1417  do {
1418  ht->pDestructor(&p->val);
1419  } while (++p != end);
1420  } else {
1421  do {
1422  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1423  ht->pDestructor(&p->val);
1424  }
1425  } while (++p != end);
1426  }
1427  } else if (HT_IS_WITHOUT_HOLES(ht)) {
1428  do {
1429  ht->pDestructor(&p->val);
1430  if (EXPECTED(p->key)) {
1431  zend_string_release(p->key);
1432  }
1433  } while (++p != end);
1434  } else {
1435  do {
1436  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1437  ht->pDestructor(&p->val);
1438  if (EXPECTED(p->key)) {
1439  zend_string_release(p->key);
1440  }
1441  }
1442  } while (++p != end);
1443  }
1444 
1445  SET_INCONSISTENT(HT_DESTROYED);
1446  } else {
1447  if (!HT_HAS_STATIC_KEYS_ONLY(ht)) {
1448  do {
1449  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1450  if (EXPECTED(p->key)) {
1451  zend_string_release(p->key);
1452  }
1453  }
1454  } while (++p != end);
1455  }
1456  }
1458  } else if (EXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
1459  return;
1460  }
1462 }

References _zend_array::arData, EXPECTED, GC_FLAGS, GC_REFCOUNT, HASH_FLAG_INITIALIZED, HT_ASSERT, HT_FLAGS, HT_GET_DATA_ADDR, HT_HAS_STATIC_KEYS_ONLY, HT_IS_WITHOUT_HOLES, IS_ARRAY_PERSISTENT, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nNumUsed, _zend_array::pDestructor, pefree, SET_INCONSISTENT, _Bucket::val, Z_TYPE, and zend_hash_iterators_remove().

Referenced by config_zval_dtor(), delete_internal_hashtable(), destroy_php_config(), destroy_uploaded_files_hash(), destroy_zend_class(), fcgi_shutdown(), main(), php_cli_server_dtor(), php_cli_server_request_dtor(), PHP_FUNCTION(), PHP_MSHUTDOWN_FUNCTION(), php_output_handler_reverse_conflict_register(), php_output_shutdown(), php_phpdbg_destroy_bp_file(), php_phpdbg_destroy_bp_methods(), php_shutdown_config(), php_shutdown_stream_hashes(), php_shutdown_stream_wrappers(), php_win32_core_globals_dtor(), phpdbg_delete_watch_collision(), phpdbg_destroy_watchpoints(), phpdbg_do_info_classes(), phpdbg_do_info_funcs(), phpdbg_opline_class_breaks_dtor(), phpdbg_print_symbols(), phpdbg_remove_watch_element_recursively(), phpdbg_remove_watchpoint(), phpdbg_unwatch_parent_ht(), phpdbg_xml_var_dump(), print_modules(), reverse_conflict_dtor(), rfc1867_post_handler(), sapi_globals_dtor(), shutdown_compiler(), shutdown_executor(), user_config_cache_entry_dtor(), zend_array_destroy(), zend_destroy_rsrc_list_dtors(), zend_do_traits_method_binding(), zend_file_context_end(), zend_gc_collect_cycles(), zend_generator_free_storage(), zend_ini_deactivate(), zend_ini_dtor(), zend_ini_global_shutdown(), zend_interned_strings_deactivate(), zend_interned_strings_dtor(), zend_object_std_dtor(), zend_oparray_context_end(), zend_print_zval_r_to_buf(), zend_reset_import_tables(), zend_shutdown(), zend_shutdown_constants(), zend_startup(), zend_ts_hash_destroy(), zend_vm_trace_finish(), and zend_vm_trace_init().

Here is the call graph for this function:

◆ zend_hash_discard()

ZEND_API void zend_hash_discard ( HashTable ht,
uint32_t  nNumUsed 
)

Definition at line 328 of file zend_hash.c.

329 {
330  Bucket *p, *end, *arData;
331  uint32_t nIndex;
332 
333  arData = ht->arData;
334  p = arData + ht->nNumUsed;
335  end = arData + nNumUsed;
336  ht->nNumUsed = nNumUsed;
337  while (p != end) {
338  p--;
339  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
340  ht->nNumOfElements--;
341  /* Collision pointers always directed from higher to lower buckets */
342  nIndex = p->h | ht->nTableMask;
343  HT_HASH_EX(arData, nIndex) = Z_NEXT(p->val);
344  }
345 }

References _zend_array::arData, _Bucket::h, HT_HASH_EX, IS_UNDEF, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, UNEXPECTED, _Bucket::val, Z_NEXT, and Z_TYPE.

Referenced by shutdown_executor().

◆ zend_hash_do_resize()

static void zend_hash_do_resize ( HashTable ht)
static

Definition at line 1023 of file zend_hash.c.

1024 {
1025 
1026  IS_CONSISTENT(ht);
1027  HT_ASSERT_RC1(ht);
1028 
1029  if (ht->nNumUsed > ht->nNumOfElements + (ht->nNumOfElements >> 5)) { /* additional term is there to amortize the cost of compaction */
1030  zend_hash_rehash(ht);
1031  } else if (ht->nTableSize < HT_MAX_SIZE) { /* Let's double the table size */
1032  void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
1033  uint32_t nSize = ht->nTableSize + ht->nTableSize;
1034  Bucket *old_buckets = ht->arData;
1035 
1036  ht->nTableSize = nSize;
1037  new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
1039  HT_SET_DATA_ADDR(ht, new_data);
1040  memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
1041  pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
1042  zend_hash_rehash(ht);
1043  } else {
1044  zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket) + sizeof(uint32_t), sizeof(Bucket));
1045  }
1046 }

References _zend_array::arData, E_ERROR, GC_FLAGS, HT_ASSERT_RC1, HT_GET_DATA_ADDR, HT_SET_DATA_ADDR, HT_SIZE_EX, HT_SIZE_TO_MASK, IS_ARRAY_PERSISTENT, IS_CONSISTENT, memcpy, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, pefree, pemalloc, zend_error_noreturn, and zend_hash_rehash().

Here is the call graph for this function:

◆ zend_hash_exists()

◆ zend_hash_extend()

ZEND_API void zend_hash_extend ( HashTable ht,
uint32_t  nSize,
zend_bool  packed 
)

Definition at line 294 of file zend_hash.c.

295 {
296  HT_ASSERT_RC1(ht);
297  if (nSize == 0) return;
298  if (UNEXPECTED(!(HT_FLAGS(ht) & HASH_FLAG_INITIALIZED))) {
299  if (nSize > ht->nTableSize) {
300  ht->nTableSize = zend_hash_check_size(nSize);
301  }
302  zend_hash_real_init(ht, packed);
303  } else {
304  if (packed) {
306  if (nSize > ht->nTableSize) {
307  ht->nTableSize = zend_hash_check_size(nSize);
309  }
310  } else {
312  if (nSize > ht->nTableSize) {
313  void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
314  Bucket *old_buckets = ht->arData;
315  nSize = zend_hash_check_size(nSize);
316  ht->nTableSize = nSize;
317  new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
319  HT_SET_DATA_ADDR(ht, new_data);
320  memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
321  pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
322  zend_hash_rehash(ht);
323  }
324  }
325  }
326 }

References _zend_array::arData, GC_FLAGS, HASH_FLAG_INITIALIZED, HASH_FLAG_PACKED, HT_ASSERT_RC1, HT_FLAGS, HT_GET_DATA_ADDR, HT_MIN_MASK, HT_SET_DATA_ADDR, HT_SIZE_EX, HT_SIZE_TO_MASK, HT_USED_SIZE, IS_ARRAY_PERSISTENT, memcpy, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, pefree, pemalloc, perealloc2, UNEXPECTED, ZEND_ASSERT(), zend_hash_check_size(), zend_hash_real_init(), and zend_hash_rehash().

Referenced by zend_do_inheritance(), zend_objects_clone_members(), and zend_rebuild_symbol_table().

Here is the call graph for this function:

◆ zend_hash_find()

◆ zend_hash_find_bucket()

static Bucket* zend_hash_find_bucket ( const HashTable ht,
zend_string key,
zend_bool  known_hash 
)
inlinestatic

Definition at line 560 of file zend_hash.c.

561 {
562  zend_ulong h;
563  uint32_t nIndex;
564  uint32_t idx;
565  Bucket *p, *arData;
566 
567  if (known_hash) {
568  h = ZSTR_H(key);
569  } else {
570  h = zend_string_hash_val(key);
571  }
572  arData = ht->arData;
573  nIndex = h | ht->nTableMask;
574  idx = HT_HASH_EX(arData, nIndex);
575 
576  if (UNEXPECTED(idx == HT_INVALID_IDX)) {
577  return NULL;
578  }
579  p = HT_HASH_TO_BUCKET_EX(arData, idx);
580  if (EXPECTED(p->key == key)) { /* check for the same interned string */
581  return p;
582  }
583 
584  while (1) {
585  if (p->h == ZSTR_H(key) &&
586  EXPECTED(p->key) &&
587  zend_string_equal_content(p->key, key)) {
588  return p;
589  }
590  idx = Z_NEXT(p->val);
591  if (idx == HT_INVALID_IDX) {
592  return NULL;
593  }
594  p = HT_HASH_TO_BUCKET_EX(arData, idx);
595  if (p->key == key) { /* check for the same interned string */
596  return p;
597  }
598  }
599 }

References _zend_array::arData, EXPECTED, _Bucket::h, HT_HASH_EX, HT_INVALID_IDX, _Bucket::key, _zend_array::nTableMask, NULL, UNEXPECTED, _Bucket::val, Z_NEXT, zend_string_hash_val(), and ZSTR_H.

Referenced by _zend_hash_add_or_update_i(), _zend_hash_find_known_hash(), zend_hash_exists(), and zend_hash_find().

Here is the call graph for this function:

◆ zend_hash_get_current_data_ex()

ZEND_API zval* zend_hash_get_current_data_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2327 of file zend_hash.c.

2328 {
2329  uint32_t idx;
2330  Bucket *p;
2331 
2332  IS_CONSISTENT(ht);
2333  idx = _zend_hash_get_valid_pos(ht, *pos);
2334  if (idx < ht->nNumUsed) {
2335  p = ht->arData + idx;
2336  return &p->val;
2337  } else {
2338  return NULL;
2339  }
2340 }

References _zend_hash_get_valid_pos(), _zend_array::arData, IS_CONSISTENT, NULL, and _Bucket::val.

Referenced by phpdbg_array_intersect(), phpdbg_dump_backtrace(), and zend_hash_get_current_data_ptr_ex().

Here is the call graph for this function:

◆ zend_hash_get_current_key_ex()

ZEND_API int zend_hash_get_current_key_ex ( const HashTable ht,
zend_string **  str_index,
zend_ulong num_index,
HashPosition pos 
)

Definition at line 2269 of file zend_hash.c.

2270 {
2271  uint32_t idx;
2272  Bucket *p;
2273 
2274  IS_CONSISTENT(ht);
2275  idx = _zend_hash_get_valid_pos(ht, *pos);
2276  if (idx < ht->nNumUsed) {
2277  p = ht->arData + idx;
2278  if (p->key) {
2279  *str_index = p->key;
2280  return HASH_KEY_IS_STRING;
2281  } else {
2282  *num_index = p->h;
2283  return HASH_KEY_IS_LONG;
2284  }
2285  }
2286  return HASH_KEY_NON_EXISTENT;
2287 }

References _zend_hash_get_valid_pos(), _zend_array::arData, _Bucket::h, HASH_KEY_IS_LONG, HASH_KEY_IS_STRING, HASH_KEY_NON_EXISTENT, IS_CONSISTENT, and _Bucket::key.

Here is the call graph for this function:

◆ zend_hash_get_current_key_type_ex()

ZEND_API int zend_hash_get_current_key_type_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2308 of file zend_hash.c.

2309 {
2310  uint32_t idx;
2311  Bucket *p;
2312 
2313  IS_CONSISTENT(ht);
2314  idx = _zend_hash_get_valid_pos(ht, *pos);
2315  if (idx < ht->nNumUsed) {
2316  p = ht->arData + idx;
2317  if (p->key) {
2318  return HASH_KEY_IS_STRING;
2319  } else {
2320  return HASH_KEY_IS_LONG;
2321  }
2322  }
2323  return HASH_KEY_NON_EXISTENT;
2324 }

References _zend_hash_get_valid_pos(), _zend_array::arData, HASH_KEY_IS_LONG, HASH_KEY_IS_STRING, HASH_KEY_NON_EXISTENT, IS_CONSISTENT, and _Bucket::key.

Here is the call graph for this function:

◆ zend_hash_get_current_key_zval_ex()

ZEND_API void zend_hash_get_current_key_zval_ex ( const HashTable ht,
zval key,
HashPosition pos 
)

Definition at line 2289 of file zend_hash.c.

2290 {
2291  uint32_t idx;
2292  Bucket *p;
2293 
2294  IS_CONSISTENT(ht);
2295  idx = _zend_hash_get_valid_pos(ht, *pos);
2296  if (idx >= ht->nNumUsed) {
2297  ZVAL_NULL(key);
2298  } else {
2299  p = ht->arData + idx;
2300  if (p->key) {
2301  ZVAL_STR_COPY(key, p->key);
2302  } else {
2303  ZVAL_LONG(key, p->h);
2304  }
2305  }
2306 }

References _zend_hash_get_valid_pos(), _zend_array::arData, _Bucket::h, IS_CONSISTENT, _Bucket::key, _zend_array::nNumUsed, ZVAL_LONG(), ZVAL_NULL(), and ZVAL_STR_COPY.

Here is the call graph for this function:

◆ zend_hash_get_current_pos()

ZEND_API HashPosition zend_hash_get_current_pos ( const HashTable ht)

Definition at line 393 of file zend_hash.c.

394 {
395  return _zend_hash_get_current_pos(ht);
396 }

References _zend_hash_get_current_pos().

Here is the call graph for this function:

◆ zend_hash_graceful_destroy()

ZEND_API void zend_hash_graceful_destroy ( HashTable ht)

Definition at line 1625 of file zend_hash.c.

1626 {
1627  uint32_t idx;
1628  Bucket *p;
1629 
1630  IS_CONSISTENT(ht);
1631  HT_ASSERT_RC1(ht);
1632 
1633  p = ht->arData;
1634  for (idx = 0; idx < ht->nNumUsed; idx++, p++) {
1635  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1636  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1637  }
1638  if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
1640  }
1641 
1642  SET_INCONSISTENT(HT_DESTROYED);
1643 }

References _zend_hash_del_el(), _zend_array::arData, GC_FLAGS, HASH_FLAG_INITIALIZED, HT_ASSERT_RC1, HT_FLAGS, HT_GET_DATA_ADDR, IS_ARRAY_PERSISTENT, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumUsed, pefree, SET_INCONSISTENT, UNEXPECTED, _Bucket::val, and Z_TYPE.

Referenced by zend_ts_hash_graceful_destroy().

Here is the call graph for this function:

◆ zend_hash_graceful_reverse_destroy()

ZEND_API void zend_hash_graceful_reverse_destroy ( HashTable ht)

Definition at line 1645 of file zend_hash.c.

1646 {
1647  uint32_t idx;
1648  Bucket *p;
1649 
1650  IS_CONSISTENT(ht);
1651  HT_ASSERT_RC1(ht);
1652 
1653  idx = ht->nNumUsed;
1654  p = ht->arData + ht->nNumUsed;
1655  while (idx > 0) {
1656  idx--;
1657  p--;
1658  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1659  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1660  }
1661 
1662  if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
1664  }
1665 
1666  SET_INCONSISTENT(HT_DESTROYED);
1667 }

References _zend_hash_del_el(), _zend_array::arData, GC_FLAGS, HASH_FLAG_INITIALIZED, HT_ASSERT_RC1, HT_FLAGS, HT_GET_DATA_ADDR, IS_ARRAY_PERSISTENT, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumUsed, pefree, SET_INCONSISTENT, UNEXPECTED, _Bucket::val, and Z_TYPE.

Referenced by shutdown_executor(), zend_destroy_modules(), and zend_destroy_rsrc_list().

Here is the call graph for this function:

◆ zend_hash_index_add()

ZEND_API zval* zend_hash_index_add ( HashTable ht,
zend_ulong  h,
zval pData 
)

Definition at line 998 of file zend_hash.c.

999 {
1000  return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_ADD);
1001 }

References _zend_hash_index_add_or_update_i(), and HASH_ADD.

Referenced by init_opcode_serialiser(), zend_compile_func_in_array(), zend_compile_switch(), zend_hash_index_add_empty_element(), zend_hash_index_add_mem(), zend_hash_index_add_or_update(), zend_hash_index_add_ptr(), zend_hash_merge(), and zif_get_object_vars().

Here is the call graph for this function:

◆ zend_hash_index_add_empty_element()

ZEND_API zval* zend_hash_index_add_empty_element ( HashTable ht,
zend_ulong  h 
)

Definition at line 872 of file zend_hash.c.

873 {
874  zval dummy;
875 
876  ZVAL_NULL(&dummy);
877  return zend_hash_index_add(ht, h, &dummy);
878 }

References zend_hash_index_add(), and ZVAL_NULL().

Referenced by phpdbg_queue_element_for_recreation(), and phpdbg_watchpoint_segfault_handler().

Here is the call graph for this function:

◆ zend_hash_index_add_new()

◆ zend_hash_index_add_or_update()

ZEND_API zval* zend_hash_index_add_or_update ( HashTable ht,
zend_ulong  h,
zval pData,
uint32_t  flag 
)

Definition at line 980 of file zend_hash.c.

981 {
982  if (flag == HASH_ADD) {
983  return zend_hash_index_add(ht, h, pData);
984  } else if (flag == (HASH_ADD|HASH_ADD_NEW)) {
985  return zend_hash_index_add_new(ht, h, pData);
986  } else if (flag == (HASH_ADD|HASH_ADD_NEXT)) {
987  ZEND_ASSERT(h == ht->nNextFreeElement);
988  return zend_hash_next_index_insert(ht, pData);
989  } else if (flag == (HASH_ADD|HASH_ADD_NEW|HASH_ADD_NEXT)) {
990  ZEND_ASSERT(h == ht->nNextFreeElement);
991  return zend_hash_next_index_insert_new(ht, pData);
992  } else {
993  ZEND_ASSERT(flag == HASH_UPDATE);
994  return zend_hash_index_update(ht, h, pData);
995  }
996 }

References HASH_ADD, HASH_ADD_NEW, HASH_ADD_NEXT, HASH_UPDATE, _zend_array::nNextFreeElement, ZEND_ASSERT(), zend_hash_index_add(), zend_hash_index_add_new(), zend_hash_index_update(), zend_hash_next_index_insert(), and zend_hash_next_index_insert_new().

Here is the call graph for this function:

◆ zend_hash_index_del()

ZEND_API int zend_hash_index_del ( HashTable ht,
zend_ulong  h 
)

Definition at line 1367 of file zend_hash.c.

1368 {
1369  uint32_t nIndex;
1370  uint32_t idx;
1371  Bucket *p;
1372  Bucket *prev = NULL;
1373 
1374  IS_CONSISTENT(ht);
1375  HT_ASSERT_RC1(ht);
1376 
1377  if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
1378  if (h < ht->nNumUsed) {
1379  p = ht->arData + h;
1380  if (Z_TYPE(p->val) != IS_UNDEF) {
1381  _zend_hash_del_el_ex(ht, HT_IDX_TO_HASH(h), p, NULL);
1382  return SUCCESS;
1383  }
1384  }
1385  return FAILURE;
1386  }
1387  nIndex = h | ht->nTableMask;
1388 
1389  idx = HT_HASH(ht, nIndex);
1390  while (idx != HT_INVALID_IDX) {
1391  p = HT_HASH_TO_BUCKET(ht, idx);
1392  if ((p->h == h) && (p->key == NULL)) {
1393  _zend_hash_del_el_ex(ht, idx, p, prev);
1394  return SUCCESS;
1395  }
1396  prev = p;
1397  idx = Z_NEXT(p->val);
1398  }
1399  return FAILURE;
1400 }

References _zend_hash_del_el_ex(), _zend_array::arData, FAILURE, _Bucket::h, HASH_FLAG_PACKED, HT_ASSERT_RC1, HT_FLAGS, HT_HASH, HT_HASH_TO_BUCKET, HT_INVALID_IDX, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nTableMask, NULL, SUCCESS, _Bucket::val, Z_NEXT, and Z_TYPE.

Referenced by php_cli_server_close_connection(), phpdbg_automatic_dequeue_free(), phpdbg_delete_breakpoint(), phpdbg_delete_watch_collision(), phpdbg_remove_watch_element(), phpdbg_watch_efree(), zend_generator_add_child(), zend_list_delete(), zend_list_free(), zend_symtable_del(), zend_symtable_del_ind(), zend_symtable_str_del(), zend_symtable_str_del_ind(), zend_ts_hash_index_del(), ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(), ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(), ZEND_UNSET_DIM_SPEC_CV_TMPVAR_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(), ZEND_UNSET_DIM_SPEC_VAR_TMPVAR_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_index_exists()

◆ zend_hash_index_find()

ZEND_API zval* zend_hash_index_find ( const HashTable ht,
zend_ulong  h 
)

Definition at line 2140 of file zend_hash.c.

2141 {
2142  Bucket *p;
2143 
2144  IS_CONSISTENT(ht);
2145 
2146  if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
2147  if (h < ht->nNumUsed) {
2148  p = ht->arData + h;
2149  if (Z_TYPE(p->val) != IS_UNDEF) {
2150  return &p->val;
2151  }
2152  }
2153  return NULL;
2154  }
2155 
2156  p = zend_hash_index_find_bucket(ht, h);
2157  return p ? &p->val : NULL;
2158 }

References _zend_array::arData, HASH_FLAG_PACKED, HT_FLAGS, IS_CONSISTENT, IS_UNDEF, NULL, _Bucket::val, Z_TYPE, and zend_hash_index_find_bucket().

Referenced by php_autoglobal_merge(), PHP_FUNCTION(), phpdbg_dequeue_elements_for_recreation(), zend_eval_const_expr(), zend_find_array_dim_slow(), zend_get_opcode_handler_func(), zend_hash_compare_impl(), zend_hash_index_find_deref(), zend_hash_index_find_ptr(), zend_init_dynamic_call_array(), zend_is_callable_impl(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CONST_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_CV_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMPVAR_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CONST_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_CV_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMPVAR_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CONST_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_CV_HANDLER(), ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMPVAR_TMPVAR_HANDLER(), zend_serialize_opcode_handler(), ZEND_SWITCH_LONG_SPEC_CONST_CONST_HANDLER(), ZEND_SWITCH_LONG_SPEC_TMPVARCV_CONST_HANDLER(), zend_symtable_find(), zend_symtable_find_ind(), zend_symtable_str_find(), zend_ts_hash_index_find(), and ZEND_VM_COLD_CONSTCONST_HANDLER().

Here is the call graph for this function:

◆ zend_hash_index_find_bucket()

static Bucket* zend_hash_index_find_bucket ( const HashTable ht,
zend_ulong  h 
)
inlinestatic

Definition at line 624 of file zend_hash.c.

625 {
626  uint32_t nIndex;
627  uint32_t idx;
628  Bucket *p, *arData;
629 
630  arData = ht->arData;
631  nIndex = h | ht->nTableMask;
632  idx = HT_HASH_EX(arData, nIndex);
633  while (idx != HT_INVALID_IDX) {
634  ZEND_ASSERT(idx < HT_IDX_TO_HASH(ht->nTableSize));
635  p = HT_HASH_TO_BUCKET_EX(arData, idx);
636  if (p->h == h && !p->key) {
637  return p;
638  }
639  idx = Z_NEXT(p->val);
640  }
641  return NULL;
642 }

References _zend_array::arData, _Bucket::h, HT_HASH_EX, HT_INVALID_IDX, _Bucket::key, _zend_array::nTableMask, _zend_array::nTableSize, NULL, _Bucket::val, Z_NEXT, and ZEND_ASSERT().

Referenced by _zend_hash_index_add_or_update_i(), _zend_hash_index_find(), zend_hash_index_exists(), and zend_hash_index_find().

Here is the call graph for this function:

◆ zend_hash_index_update()

ZEND_API zval* zend_hash_index_update ( HashTable ht,
zend_ulong  h,
zval pData 
)

Definition at line 1008 of file zend_hash.c.

1009 {
1010  return _zend_hash_index_add_or_update_i(ht, h, pData, HASH_UPDATE);
1011 }

References _zend_hash_index_add_or_update_i(), and HASH_UPDATE.

Referenced by _php_import_environment_variables(), add_get_index_double(), add_get_index_long(), add_get_index_str(), add_get_index_string(), add_get_index_stringl(), add_index_bool(), add_index_double(), add_index_long(), add_index_null(), add_index_resource(), add_index_str(), add_index_string(), add_index_stringl(), add_index_zval(), array_set_zval_key(), object_properties_load(), php_autoglobal_merge(), php_register_variable_ex(), phpdbg_oplog_fill_executable(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(), zend_ast_add_array_element(), zend_fetch_dimension_address_inner(), zend_hash_copy(), zend_hash_index_add_or_update(), zend_hash_index_update_ptr(), zend_hash_merge(), zend_proptable_to_symtable(), zend_symtable_str_update(), zend_symtable_str_update_ind(), zend_symtable_update(), zend_symtable_update_ind(), zend_try_ct_eval_array(), zend_ts_hash_index_update(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_internal_pointer_end_ex()

ZEND_API void zend_hash_internal_pointer_end_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2201 of file zend_hash.c.

2202 {
2203  uint32_t idx;
2204 
2205  IS_CONSISTENT(ht);
2206  HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
2207 
2208  idx = ht->nNumUsed;
2209  while (idx > 0) {
2210  idx--;
2211  if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
2212  *pos = idx;
2213  return;
2214  }
2215  }
2216  *pos = ht->nNumUsed;
2217 }

References _zend_array::arData, GC_REFCOUNT, HT_ASSERT, IS_CONSISTENT, IS_UNDEF, _zend_array::nInternalPointer, _zend_array::nNumUsed, _Bucket::val, and Z_TYPE.

Referenced by phpdbg_watch_parent_ht().

◆ zend_hash_internal_pointer_reset_ex()

ZEND_API void zend_hash_internal_pointer_reset_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2190 of file zend_hash.c.

2191 {
2192  IS_CONSISTENT(ht);
2193  HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
2194  *pos = _zend_hash_get_valid_pos(ht, 0);
2195 }

References _zend_hash_get_valid_pos(), GC_REFCOUNT, HT_ASSERT, IS_CONSISTENT, and _zend_array::nInternalPointer.

Referenced by phpdbg_array_intersect_init(), and phpdbg_dump_backtrace().

Here is the call graph for this function:

◆ zend_hash_iterator_add()

ZEND_API uint32_t zend_hash_iterator_add ( HashTable ht,
HashPosition  pos 
)

Definition at line 398 of file zend_hash.c.

399 {
400  HashTableIterator *iter = EG(ht_iterators);
401  HashTableIterator *end = iter + EG(ht_iterators_count);
402  uint32_t idx;
403 
404  if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
406  }
407  while (iter != end) {
408  if (iter->ht == NULL) {
409  iter->ht = ht;
410  iter->pos = pos;
411  idx = iter - EG(ht_iterators);
412  if (idx + 1 > EG(ht_iterators_used)) {
413  EG(ht_iterators_used) = idx + 1;
414  }
415  return idx;
416  }
417  iter++;
418  }
419  if (EG(ht_iterators) == EG(ht_iterators_slots)) {
420  EG(ht_iterators) = emalloc(sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
421  memcpy(EG(ht_iterators), EG(ht_iterators_slots), sizeof(HashTableIterator) * EG(ht_iterators_count));
422  } else {
423  EG(ht_iterators) = erealloc(EG(ht_iterators), sizeof(HashTableIterator) * (EG(ht_iterators_count) + 8));
424  }
425  iter = EG(ht_iterators) + EG(ht_iterators_count);
426  EG(ht_iterators_count) += 8;
427  iter->ht = ht;
428  iter->pos = pos;
429  memset(iter + 1, 0, sizeof(HashTableIterator) * 7);
430  idx = iter - EG(ht_iterators);
431  EG(ht_iterators_used) = idx + 1;
432  return idx;
433 }

References EG(), emalloc, erealloc, EXPECTED, _HashTableIterator::ht, HT_INC_ITERATORS_COUNT, HT_ITERATORS_OVERFLOW, memcpy, NULL, and _HashTableIterator::pos.

Referenced by ZEND_FE_RESET_R_SPEC_CONST_HANDLER(), ZEND_FE_RESET_R_SPEC_CV_HANDLER(), ZEND_FE_RESET_R_SPEC_TMP_HANDLER(), ZEND_FE_RESET_R_SPEC_VAR_HANDLER(), ZEND_FE_RESET_RW_SPEC_CONST_HANDLER(), ZEND_FE_RESET_RW_SPEC_CV_HANDLER(), ZEND_FE_RESET_RW_SPEC_TMP_HANDLER(), ZEND_FE_RESET_RW_SPEC_VAR_HANDLER(), ZEND_VM_COLD_CONST_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_iterator_del()

ZEND_API void zend_hash_iterator_del ( uint32_t  idx)

Definition at line 476 of file zend_hash.c.

477 {
478  HashTableIterator *iter = EG(ht_iterators) + idx;
479 
480  ZEND_ASSERT(idx != (uint32_t)-1);
481 
482  if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
483  && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
484  ZEND_ASSERT(HT_ITERATORS_COUNT(iter->ht) != 0);
485  HT_DEC_ITERATORS_COUNT(iter->ht);
486  }
487  iter->ht = NULL;
488 
489  if (idx == EG(ht_iterators_used) - 1) {
490  while (idx > 0 && EG(ht_iterators)[idx - 1].ht == NULL) {
491  idx--;
492  }
493  EG(ht_iterators_used) = idx;
494  }
495 }

References EG(), EXPECTED, _HashTableIterator::ht, HT_DEC_ITERATORS_COUNT, HT_ITERATORS_COUNT, HT_ITERATORS_OVERFLOW, HT_POISONED_PTR, NULL, and ZEND_ASSERT().

Referenced by cleanup_live_vars(), ZEND_FE_FREE_SPEC_TMPVAR_HANDLER(), and ZEND_VM_HOT_HANDLER().

Here is the call graph for this function:

◆ zend_hash_iterator_pos()

ZEND_API HashPosition zend_hash_iterator_pos ( uint32_t  idx,
HashTable ht 
)

Definition at line 435 of file zend_hash.c.

436 {
437  HashTableIterator *iter = EG(ht_iterators) + idx;
438 
439  ZEND_ASSERT(idx != (uint32_t)-1);
440  if (UNEXPECTED(iter->ht != ht)) {
441  if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
442  && EXPECTED(!HT_ITERATORS_OVERFLOW(iter->ht))) {
443  HT_DEC_ITERATORS_COUNT(iter->ht);
444  }
445  if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
447  }
448  iter->ht = ht;
449  iter->pos = _zend_hash_get_current_pos(ht);
450  }
451  return iter->pos;
452 }

References _zend_hash_get_current_pos(), EG(), EXPECTED, _HashTableIterator::ht, HT_DEC_ITERATORS_COUNT, HT_INC_ITERATORS_COUNT, HT_ITERATORS_OVERFLOW, HT_POISONED_PTR, _HashTableIterator::pos, UNEXPECTED, and ZEND_ASSERT().

Referenced by ZEND_FE_FETCH_R_SPEC_VAR_HANDLER(), ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_iterator_pos_ex()

ZEND_API HashPosition zend_hash_iterator_pos_ex ( uint32_t  idx,
zval array 
)

Definition at line 454 of file zend_hash.c.

455 {
456  HashTable *ht = Z_ARRVAL_P(array);
457  HashTableIterator *iter = EG(ht_iterators) + idx;
458 
459  ZEND_ASSERT(idx != (uint32_t)-1);
460  if (UNEXPECTED(iter->ht != ht)) {
461  if (EXPECTED(iter->ht) && EXPECTED(iter->ht != HT_POISONED_PTR)
462  && EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
463  HT_DEC_ITERATORS_COUNT(iter->ht);
464  }
465  SEPARATE_ARRAY(array);
466  ht = Z_ARRVAL_P(array);
467  if (EXPECTED(!HT_ITERATORS_OVERFLOW(ht))) {
469  }
470  iter->ht = ht;
471  iter->pos = _zend_hash_get_current_pos(ht);
472  }
473  return iter->pos;
474 }

References _zend_hash_get_current_pos(), EG(), EXPECTED, _HashTableIterator::ht, HT_DEC_ITERATORS_COUNT, HT_INC_ITERATORS_COUNT, HT_ITERATORS_OVERFLOW, HT_POISONED_PTR, _HashTableIterator::pos, SEPARATE_ARRAY, UNEXPECTED, Z_ARRVAL_P, and ZEND_ASSERT().

Referenced by ZEND_FE_FETCH_RW_SPEC_VAR_HANDLER(), and ZEND_VM_HANDLER().

Here is the call graph for this function:

◆ zend_hash_iterators_advance()

ZEND_API void zend_hash_iterators_advance ( HashTable ht,
HashPosition  step 
)

Definition at line 547 of file zend_hash.c.

548 {
549  HashTableIterator *iter = EG(ht_iterators);
550  HashTableIterator *end = iter + EG(ht_iterators_used);
551 
552  while (iter != end) {
553  if (iter->ht == ht) {
554  iter->pos += step;
555  }
556  iter++;
557  }
558 }

References EG(), _HashTableIterator::ht, and _HashTableIterator::pos.

Here is the call graph for this function:

◆ zend_hash_iterators_lower_pos()

ZEND_API HashPosition zend_hash_iterators_lower_pos ( HashTable ht,
HashPosition  start 
)

Definition at line 517 of file zend_hash.c.

518 {
519  HashTableIterator *iter = EG(ht_iterators);
520  HashTableIterator *end = iter + EG(ht_iterators_used);
521  HashPosition res = ht->nNumUsed;
522 
523  while (iter != end) {
524  if (iter->ht == ht) {
525  if (iter->pos >= start && iter->pos < res) {
526  res = iter->pos;
527  }
528  }
529  iter++;
530  }
531  return res;
532 }

References EG(), _HashTableIterator::ht, _zend_array::nNumUsed, _HashTableIterator::pos, and start.

Referenced by zend_hash_rehash().

Here is the call graph for this function:

◆ zend_hash_iterators_remove()

static void zend_hash_iterators_remove ( HashTable ht)
inlinestatic

Definition at line 510 of file zend_hash.c.

511 {
512  if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
514  }
515 }

References _zend_hash_iterators_remove(), HT_HAS_ITERATORS, and UNEXPECTED.

Referenced by zend_array_destroy(), and zend_hash_destroy().

Here is the call graph for this function:

◆ zend_hash_merge()

ZEND_API void zend_hash_merge ( HashTable target,
HashTable source,
copy_ctor_func_t  pCopyConstructor,
zend_bool  overwrite 
)

Definition at line 1998 of file zend_hash.c.

1999 {
2000  uint32_t idx;
2001  Bucket *p;
2002  zval *t;
2003 
2004  IS_CONSISTENT(source);
2007 
2008  if (overwrite) {
2009  for (idx = 0; idx < source->nNumUsed; idx++) {
2010  p = source->arData + idx;
2011  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
2012  if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) &&
2014  continue;
2015  }
2016  if (p->key) {
2018  if (pCopyConstructor) {
2019  pCopyConstructor(t);
2020  }
2021  } else {
2022  t = zend_hash_index_update(target, p->h, &p->val);
2023  if (pCopyConstructor) {
2024  pCopyConstructor(t);
2025  }
2026  }
2027  }
2028  } else {
2029  for (idx = 0; idx < source->nNumUsed; idx++) {
2030  p = source->arData + idx;
2031  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
2032  if (UNEXPECTED(Z_TYPE(p->val) == IS_INDIRECT) &&
2034  continue;
2035  }
2036  if (p->key) {
2038  if (t && pCopyConstructor) {
2039  pCopyConstructor(t);
2040  }
2041  } else {
2042  t = zend_hash_index_add(target, p->h, &p->val);
2043  if (t && pCopyConstructor) {
2044  pCopyConstructor(t);
2045  }
2046  }
2047  }
2048  }
2049 }

References _zend_hash_add_or_update_i(), _zend_array::arData, _Bucket::h, HASH_ADD, HASH_UPDATE, HASH_UPDATE_INDIRECT, HT_ASSERT_RC1, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, _zend_array::nNumUsed, target, UNEXPECTED, _Bucket::val, Z_INDIRECT, Z_TYPE, Z_TYPE_P, zend_hash_index_add(), and zend_hash_index_update().

Referenced by add_function_array(), and zend_ts_hash_merge().

Here is the call graph for this function:

◆ zend_hash_merge_ex()

ZEND_API void zend_hash_merge_ex ( HashTable target,
HashTable source,
copy_ctor_func_t  pCopyConstructor,
merge_checker_func_t  pMergeSource,
void *  pParam 
)

Definition at line 2062 of file zend_hash.c.

2063 {
2064  uint32_t idx;
2065  Bucket *p;
2066  zval *t;
2067 
2068  IS_CONSISTENT(source);
2071 
2072  for (idx = 0; idx < source->nNumUsed; idx++) {
2073  p = source->arData + idx;
2074  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
2075  if (zend_hash_replace_checker_wrapper(target, &p->val, p, pParam, pMergeSource)) {
2076  t = zend_hash_update(target, p->key, &p->val);
2077  if (pCopyConstructor) {
2078  pCopyConstructor(t);
2079  }
2080  }
2081  }
2082 }

References _zend_array::arData, HT_ASSERT_RC1, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nNumUsed, target, UNEXPECTED, _Bucket::val, Z_TYPE, zend_hash_replace_checker_wrapper(), and zend_hash_update().

Referenced by merge_php_config(), and zend_ts_hash_merge_ex().

Here is the call graph for this function:

◆ zend_hash_minmax()

ZEND_API zval* zend_hash_minmax ( const HashTable ht,
compare_func_t  compar,
uint32_t  flag 
)

Definition at line 2561 of file zend_hash.c.

2562 {
2563  uint32_t idx;
2564  Bucket *p, *res;
2565 
2566  IS_CONSISTENT(ht);
2567 
2568  if (ht->nNumOfElements == 0 ) {
2569  return NULL;
2570  }
2571 
2572  idx = 0;
2573  while (1) {
2574  if (idx == ht->nNumUsed) {
2575  return NULL;
2576  }
2577  if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) break;
2578  idx++;
2579  }
2580  res = ht->arData + idx;
2581  for (; idx < ht->nNumUsed; idx++) {
2582  p = ht->arData + idx;
2583  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
2584 
2585  if (flag) {
2586  if (compar(res, p) < 0) { /* max */
2587  res = p;
2588  }
2589  } else {
2590  if (compar(res, p) > 0) { /* min */
2591  res = p;
2592  }
2593  }
2594  }
2595  return &res->val;
2596 }

References _zend_array::arData, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumOfElements, _zend_array::nNumUsed, NULL, UNEXPECTED, _Bucket::val, and Z_TYPE.

Referenced by zend_ts_hash_minmax().

◆ zend_hash_move_backwards_ex()

ZEND_API int zend_hash_move_backwards_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2245 of file zend_hash.c.

2246 {
2247  uint32_t idx = *pos;
2248 
2249  IS_CONSISTENT(ht);
2250  HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
2251 
2252  if (idx < ht->nNumUsed) {
2253  while (idx > 0) {
2254  idx--;
2255  if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
2256  *pos = idx;
2257  return SUCCESS;
2258  }
2259  }
2260  *pos = ht->nNumUsed;
2261  return SUCCESS;
2262  } else {
2263  return FAILURE;
2264  }
2265 }

References _zend_array::arData, FAILURE, GC_REFCOUNT, HT_ASSERT, IS_CONSISTENT, IS_UNDEF, _zend_array::nInternalPointer, _zend_array::nNumUsed, SUCCESS, _Bucket::val, and Z_TYPE.

◆ zend_hash_move_forward_ex()

ZEND_API int zend_hash_move_forward_ex ( HashTable ht,
HashPosition pos 
)

Definition at line 2220 of file zend_hash.c.

2221 {
2222  uint32_t idx;
2223 
2224  IS_CONSISTENT(ht);
2225  HT_ASSERT(ht, &ht->nInternalPointer != pos || GC_REFCOUNT(ht) == 1);
2226 
2227  idx = _zend_hash_get_valid_pos(ht, *pos);
2228  if (idx < ht->nNumUsed) {
2229  while (1) {
2230  idx++;
2231  if (idx >= ht->nNumUsed) {
2232  *pos = ht->nNumUsed;
2233  return SUCCESS;
2234  }
2235  if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) {
2236  *pos = idx;
2237  return SUCCESS;
2238  }
2239  }
2240  } else {
2241  return FAILURE;
2242  }
2243 }

References _zend_hash_get_valid_pos(), _zend_array::arData, FAILURE, GC_REFCOUNT, HT_ASSERT, IS_CONSISTENT, IS_UNDEF, _zend_array::nInternalPointer, _zend_array::nNumUsed, SUCCESS, _Bucket::val, and Z_TYPE.

Referenced by phpdbg_array_intersect(), and phpdbg_dump_backtrace().

Here is the call graph for this function:

◆ zend_hash_next_index_insert()

ZEND_API zval* zend_hash_next_index_insert ( HashTable ht,
zval pData 
)

Definition at line 1013 of file zend_hash.c.

1014 {
1016 }

References _zend_hash_index_add_or_update_i(), HASH_ADD, HASH_ADD_NEXT, and _zend_array::nNextFreeElement.

Referenced by add_next_index_bool(), add_next_index_double(), add_next_index_long(), add_next_index_null(), add_next_index_resource(), add_next_index_str(), add_next_index_string(), add_next_index_stringl(), add_next_index_zval(), if(), php_build_argv(), php_ini_parser_cb(), php_register_variable_ex(), phpdbg_webdata_compress(), phpdbg_webdata_decompress(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_CV_UNUSED_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CONST_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_CV_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_TMPVAR_OP_DATA_VAR_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CONST_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_CV_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_TMP_HANDLER(), ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_OP_DATA_VAR_HANDLER(), zend_ast_add_array_element(), zend_binary_assign_op_dim_helper_SPEC_CV_CONST(), zend_binary_assign_op_dim_helper_SPEC_CV_CV(), zend_binary_assign_op_dim_helper_SPEC_CV_TMPVAR(), zend_binary_assign_op_dim_helper_SPEC_CV_UNUSED(), zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(), zend_binary_assign_op_dim_helper_SPEC_VAR_CV(), zend_binary_assign_op_dim_helper_SPEC_VAR_TMPVAR(), zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(), zend_fetch_dimension_address(), zend_hash_index_add_or_update(), zend_hash_next_index_insert_mem(), zend_hash_next_index_insert_ptr(), zend_register_list_destructors_ex(), zend_try_ct_eval_array(), zend_ts_hash_next_index_insert(), ZEND_VM_HANDLER(), and ZEND_VM_HELPER().

Here is the call graph for this function:

◆ zend_hash_next_index_insert_new()

ZEND_API zval* zend_hash_next_index_insert_new ( HashTable ht,
zval pData 
)

Definition at line 1018 of file zend_hash.c.

1019 {
1021 }

References _zend_hash_index_add_or_update_i(), HASH_ADD, HASH_ADD_NEW, HASH_ADD_NEXT, and _zend_array::nNextFreeElement.

Referenced by zend_copy_parameters_array(), zend_fetch_debug_backtrace(), zend_hash_index_add_or_update(), and zif_get_class_methods().

Here is the call graph for this function:

◆ zend_hash_packed_grow()

static void zend_hash_packed_grow ( HashTable ht)
static

Definition at line 229 of file zend_hash.c.

230 {
231  HT_ASSERT_RC1(ht);
232  if (ht->nTableSize >= HT_MAX_SIZE) {
233  zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
234  }
235  ht->nTableSize += ht->nTableSize;
237 }

References E_ERROR, GC_FLAGS, HT_ASSERT_RC1, HT_GET_DATA_ADDR, HT_MIN_MASK, HT_SET_DATA_ADDR, HT_SIZE_EX, HT_USED_SIZE, IS_ARRAY_PERSISTENT, _zend_array::nTableSize, perealloc2, and zend_error_noreturn.

Referenced by _zend_hash_index_add_or_update_i().

◆ zend_hash_packed_to_hash()

ZEND_API void zend_hash_packed_to_hash ( HashTable ht)

Definition at line 263 of file zend_hash.c.

264 {
265  void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
266  Bucket *old_buckets = ht->arData;
267  uint32_t nSize = ht->nTableSize;
268 
269  HT_ASSERT_RC1(ht);
270  HT_FLAGS(ht) &= ~HASH_FLAG_PACKED;
271  new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
273  HT_SET_DATA_ADDR(ht, new_data);
274  memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
275  pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
276  zend_hash_rehash(ht);
277 }

References _zend_array::arData, GC_FLAGS, HASH_FLAG_PACKED, HT_ASSERT_RC1, HT_FLAGS, HT_GET_DATA_ADDR, HT_SET_DATA_ADDR, HT_SIZE_EX, HT_SIZE_TO_MASK, IS_ARRAY_PERSISTENT, memcpy, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, pefree, pemalloc, and zend_hash_rehash().

Referenced by _zend_hash_add_or_update_i(), _zend_hash_index_add_or_update_i(), _zend_hash_str_add_or_update_i(), and zend_hash_sort_ex().

Here is the call graph for this function:

◆ zend_hash_real_init()

ZEND_API void zend_hash_real_init ( HashTable ht,
zend_bool  packed 
)

Definition at line 239 of file zend_hash.c.

240 {
241  IS_CONSISTENT(ht);
242 
243  HT_ASSERT_RC1(ht);
244  zend_hash_real_init_ex(ht, packed);
245 }

References HT_ASSERT_RC1, IS_CONSISTENT, and zend_hash_real_init_ex().

Referenced by init_opcode_serialiser(), and zend_hash_extend().

Here is the call graph for this function:

◆ zend_hash_real_init_ex()

static void zend_hash_real_init_ex ( HashTable ht,
int  packed 
)
inlinestatic

Definition at line 167 of file zend_hash.c.

168 {
169  HT_ASSERT_RC1(ht);
171  if (packed) {
173  } else {
175  }
176 }

References HASH_FLAG_INITIALIZED, HT_ASSERT_RC1, HT_FLAGS, ZEND_ASSERT(), zend_hash_real_init_mixed_ex(), and zend_hash_real_init_packed_ex().

Referenced by zend_hash_real_init().

Here is the call graph for this function:

◆ zend_hash_real_init_mixed()

◆ zend_hash_real_init_mixed_ex()

static void zend_hash_real_init_mixed_ex ( HashTable ht)
inlinestatic

Definition at line 127 of file zend_hash.c.

128 {
129  uint32_t nSize = ht->nTableSize;
130 
131  ht->nTableMask = HT_SIZE_TO_MASK(nSize);
135  Bucket *arData = ht->arData;
136 
137 #ifdef __SSE2__
138  __m128i xmm0 = _mm_setzero_si128();
139  xmm0 = _mm_cmpeq_epi8(xmm0, xmm0);
140  _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -16), xmm0);
141  _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -12), xmm0);
142  _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -8), xmm0);
143  _mm_storeu_si128((__m128i*)&HT_HASH_EX(arData, -4), xmm0);
144 #else
145  HT_HASH_EX(arData, -16) = -1;
146  HT_HASH_EX(arData, -15) = -1;
147  HT_HASH_EX(arData, -14) = -1;
148  HT_HASH_EX(arData, -13) = -1;
149  HT_HASH_EX(arData, -12) = -1;
150  HT_HASH_EX(arData, -11) = -1;
151  HT_HASH_EX(arData, -10) = -1;
152  HT_HASH_EX(arData, -9) = -1;
153  HT_HASH_EX(arData, -8) = -1;
154  HT_HASH_EX(arData, -7) = -1;
155  HT_HASH_EX(arData, -6) = -1;
156  HT_HASH_EX(arData, -5) = -1;
157  HT_HASH_EX(arData, -4) = -1;
158  HT_HASH_EX(arData, -3) = -1;
159  HT_HASH_EX(arData, -2) = -1;
160  HT_HASH_EX(arData, -1) = -1;
161 #endif
162  } else {
163  HT_HASH_RESET(ht);
164  }
165 }

References _zend_array::arData, EXPECTED, GC_FLAGS, HASH_FLAG_INITIALIZED, HT_FLAGS, HT_HASH_EX, HT_HASH_RESET, HT_MIN_SIZE, HT_SET_DATA_ADDR, HT_SIZE_EX, HT_SIZE_TO_MASK, IS_ARRAY_PERSISTENT, _zend_array::nTableMask, _zend_array::nTableSize, and pemalloc.

Referenced by zend_hash_real_init_ex(), and zend_hash_real_init_mixed().

◆ zend_hash_real_init_packed()

ZEND_API void zend_hash_real_init_packed ( HashTable ht)

Definition at line 247 of file zend_hash.c.

248 {
249  IS_CONSISTENT(ht);
250 
251  HT_ASSERT_RC1(ht);
253 }

References HT_ASSERT_RC1, IS_CONSISTENT, and zend_hash_real_init_packed_ex().

Referenced by debug_backtrace_get_args(), ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(), ZEND_FUNC_GET_ARGS_SPEC_CONST_UNUSED_HANDLER(), ZEND_FUNC_GET_ARGS_SPEC_UNUSED_UNUSED_HANDLER(), ZEND_RECV_VARIADIC_SPEC_UNUSED_HANDLER(), ZEND_VM_HANDLER(), and zif_func_get_args().

Here is the call graph for this function:

◆ zend_hash_real_init_packed_ex()

◆ zend_hash_rehash()

ZEND_API int zend_hash_rehash ( HashTable ht)

Definition at line 1048 of file zend_hash.c.

1049 {
1050  Bucket *p;
1051  uint32_t nIndex, i;
1052 
1053  IS_CONSISTENT(ht);
1054 
1055  if (UNEXPECTED(ht->nNumOfElements == 0)) {
1056  if (HT_FLAGS(ht) & HASH_FLAG_INITIALIZED) {
1057  ht->nNumUsed = 0;
1058  HT_HASH_RESET(ht);
1059  }
1060  return SUCCESS;
1061  }
1062 
1063  HT_HASH_RESET(ht);
1064  i = 0;
1065  p = ht->arData;
1066  if (HT_IS_WITHOUT_HOLES(ht)) {
1067  do {
1068  nIndex = p->h | ht->nTableMask;
1069  Z_NEXT(p->val) = HT_HASH(ht, nIndex);
1070  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i);
1071  p++;
1072  } while (++i < ht->nNumUsed);
1073  } else {
1074  uint32_t old_num_used = ht->nNumUsed;
1075  do {
1076  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) {
1077  uint32_t j = i;
1078  Bucket *q = p;
1079 
1080  if (EXPECTED(!HT_HAS_ITERATORS(ht))) {
1081  while (++i < ht->nNumUsed) {
1082  p++;
1083  if (EXPECTED(Z_TYPE_INFO(p->val) != IS_UNDEF)) {
1084  ZVAL_COPY_VALUE(&q->val, &p->val);
1085  q->h = p->h;
1086  nIndex = q->h | ht->nTableMask;
1087  q->key = p->key;
1088  Z_NEXT(q->val) = HT_HASH(ht, nIndex);
1089  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j);
1090  if (UNEXPECTED(ht->nInternalPointer == i)) {
1091  ht->nInternalPointer = j;
1092  }
1093  q++;
1094  j++;
1095  }
1096  }
1097  } else {
1098  uint32_t iter_pos = zend_hash_iterators_lower_pos(ht, 0);
1099 
1100  while (++i < ht->nNumUsed) {
1101  p++;
1102  if (EXPECTED(Z_TYPE_INFO(p->val) != IS_UNDEF)) {
1103  ZVAL_COPY_VALUE(&q->val, &p->val);
1104  q->h = p->h;
1105  nIndex = q->h | ht->nTableMask;
1106  q->key = p->key;
1107  Z_NEXT(q->val) = HT_HASH(ht, nIndex);
1108  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(j);
1109  if (UNEXPECTED(ht->nInternalPointer == i)) {
1110  ht->nInternalPointer = j;
1111  }
1112  if (UNEXPECTED(i >= iter_pos)) {
1113  do {
1114  zend_hash_iterators_update(ht, iter_pos, j);
1115  iter_pos = zend_hash_iterators_lower_pos(ht, iter_pos + 1);
1116  } while (iter_pos < i);
1117  }
1118  q++;
1119  j++;
1120  }
1121  }
1122  }
1123  ht->nNumUsed = j;
1124  break;
1125  }
1126  nIndex = p->h | ht->nTableMask;
1127  Z_NEXT(p->val) = HT_HASH(ht, nIndex);
1128  HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(i);
1129  p++;
1130  } while (++i < ht->nNumUsed);
1131 
1132  /* Migrate pointer to one past the end of the array to the new one past the end, so that
1133  * newly inserted elements are picked up correctly. */
1134  if (UNEXPECTED(HT_HAS_ITERATORS(ht))) {
1135  _zend_hash_iterators_update(ht, old_num_used, ht->nNumUsed);
1136  }
1137  }
1138  return SUCCESS;
1139 }

References _zend_hash_iterators_update(), _zend_array::arData, EXPECTED, _Bucket::h, HASH_FLAG_INITIALIZED, HT_FLAGS, HT_HAS_ITERATORS, HT_HASH, HT_HASH_RESET, HT_IS_WITHOUT_HOLES, IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nInternalPointer, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, SUCCESS, UNEXPECTED, _Bucket::val, Z_NEXT, Z_TYPE, Z_TYPE_INFO, zend_hash_iterators_lower_pos(), zend_hash_iterators_update(), and ZVAL_COPY_VALUE.

Referenced by zend_hash_do_resize(), zend_hash_extend(), zend_hash_packed_to_hash(), zend_hash_sort_ex(), and zend_ts_hash_rehash().

Here is the call graph for this function:

◆ zend_hash_replace_checker_wrapper()

static zend_bool zend_hash_replace_checker_wrapper ( HashTable target,
zval source_data,
Bucket p,
void *  pParam,
merge_checker_func_t  merge_checker_func 
)
static

Definition at line 2052 of file zend_hash.c.

2053 {
2054  zend_hash_key hash_key;
2055 
2056  hash_key.h = p->h;
2057  hash_key.key = p->key;
2058  return merge_checker_func(target, source_data, &hash_key, pParam);
2059 }

References _zend_hash_key::h, _Bucket::h, _zend_hash_key::key, _Bucket::key, and target.

Referenced by zend_hash_merge_ex().

◆ zend_hash_reverse_apply()

ZEND_API void zend_hash_reverse_apply ( HashTable ht,
apply_func_t  apply_func 
)

Definition at line 1758 of file zend_hash.c.

1759 {
1760  uint32_t idx;
1761  Bucket *p;
1762  int result;
1763 
1764  IS_CONSISTENT(ht);
1765 
1766  idx = ht->nNumUsed;
1767  while (idx > 0) {
1768  idx--;
1769  p = ht->arData + idx;
1770  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
1771 
1772  result = apply_func(&p->val);
1773 
1775  HT_ASSERT_RC1(ht);
1776  _zend_hash_del_el(ht, HT_IDX_TO_HASH(idx), p);
1777  }
1778  if (result & ZEND_HASH_APPLY_STOP) {
1779  break;
1780  }
1781  }
1782 }

References _zend_hash_del_el(), _zend_array::arData, HT_ASSERT_RC1, IS_CONSISTENT, IS_UNDEF, _zend_array::nNumUsed, result, UNEXPECTED, _Bucket::val, Z_TYPE, ZEND_HASH_APPLY_REMOVE, and ZEND_HASH_APPLY_STOP.

Referenced by shutdown_destructors(), shutdown_executor(), zend_close_rsrc_list(), zend_deactivate_modules(), zend_post_deactivate_modules(), and zend_ts_hash_reverse_apply().

Here is the call graph for this function:

◆ zend_hash_sort_ex()

ZEND_API int zend_hash_sort_ex ( HashTable ht,
sort_func_t  sort,
compare_func_t  compar,
zend_bool  renumber 
)

Definition at line 2385 of file zend_hash.c.

2386 {
2387  Bucket *p;
2388  uint32_t i, j;
2389 
2390  IS_CONSISTENT(ht);
2391  HT_ASSERT_RC1(ht);
2392 
2393  if (!(ht->nNumOfElements>1) && !(renumber && ht->nNumOfElements>0)) { /* Doesn't require sorting */
2394  return SUCCESS;
2395  }
2396 
2397  if (HT_IS_WITHOUT_HOLES(ht)) {
2398  i = ht->nNumUsed;
2399  } else {
2400  for (j = 0, i = 0; j < ht->nNumUsed; j++) {
2401  p = ht->arData + j;
2402  if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
2403  if (i != j) {
2404  ht->arData[i] = *p;
2405  }
2406  i++;
2407  }
2408  }
2409 
2410  sort((void *)ht->arData, i, sizeof(Bucket), compar,
2413 
2414  ht->nNumUsed = i;
2415  ht->nInternalPointer = 0;
2416 
2417  if (renumber) {
2418  for (j = 0; j < i; j++) {
2419  p = ht->arData + j;
2420  p->h = j;
2421  if (p->key) {
2422  zend_string_release(p->key);
2423  p->key = NULL;
2424  }
2425  }
2426 
2427  ht->nNextFreeElement = i;
2428  }
2429  if (HT_FLAGS(ht) & HASH_FLAG_PACKED) {
2430  if (!renumber) {
2432  }
2433  } else {
2434  if (renumber) {
2435  void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
2436  Bucket *old_buckets = ht->arData;
2437 
2440  ht->nTableMask = HT_MIN_MASK;
2441  HT_SET_DATA_ADDR(ht, new_data);
2442  memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
2443  pefree(old_data, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
2445  } else {
2446  zend_hash_rehash(ht);
2447  }
2448  }
2449 
2450  return SUCCESS;
2451 }

References _zend_array::arData, GC_FLAGS, _Bucket::h, HASH_FLAG_PACKED, HASH_FLAG_STATIC_KEYS, HT_ASSERT_RC1, HT_FLAGS, HT_GET_DATA_ADDR, HT_HASH_RESET_PACKED, HT_IS_WITHOUT_HOLES, HT_MIN_MASK, HT_SET_DATA_ADDR, HT_SIZE_EX, IS_ARRAY_PERSISTENT, IS_CONSISTENT, IS_UNDEF, _Bucket::key, memcpy, _zend_array::nInternalPointer, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _zend_array::nTableMask, _zend_array::nTableSize, NULL, pefree, pemalloc, SUCCESS, UNEXPECTED, _Bucket::val, Z_TYPE, zend_hash_bucket_packed_swap(), zend_hash_bucket_renum_swap(), zend_hash_bucket_swap(), zend_hash_packed_to_hash(), and zend_hash_rehash().

Referenced by zend_startup_modules(), and zend_ts_hash_sort().

Here is the call graph for this function:

◆ zend_hash_str_add()

ZEND_API zval* zend_hash_str_add ( HashTable ht,
const char *  str,
size_t  len,
zval pData 
)

Definition at line 858 of file zend_hash.c.

859 {
860  zend_ulong h = zend_hash_func(str, len);
861 
862  return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD);
863 }

References _zend_hash_str_add_or_update_i(), HASH_ADD, len, and zend_hash_func().

Referenced by zend_hash_str_add_empty_element(), zend_hash_str_add_mem(), zend_hash_str_add_or_update(), and zend_hash_str_add_ptr().

Here is the call graph for this function:

◆ zend_hash_str_add_empty_element()

ZEND_API zval* zend_hash_str_add_empty_element ( HashTable ht,
const char *  str,
size_t  len 
)

Definition at line 888 of file zend_hash.c.

889 {
890  zval dummy;
891 
892  ZVAL_NULL(&dummy);
893  return zend_hash_str_add(ht, str, len, &dummy);
894 }

References len, zend_hash_str_add(), and ZVAL_NULL().

Referenced by add_protected_variable().

Here is the call graph for this function:

◆ zend_hash_str_add_new()

ZEND_API zval* zend_hash_str_add_new ( HashTable ht,
const char *  str,
size_t  len,
zval pData 
)

Definition at line 865 of file zend_hash.c.

866 {
867  zend_ulong h = zend_hash_func(str, len);
868 
869  return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_ADD_NEW);
870 }

References _zend_hash_str_add_or_update_i(), HASH_ADD_NEW, len, and zend_hash_func().

Referenced by zend_hash_str_add_new_mem(), zend_hash_str_add_new_ptr(), zend_hash_str_add_or_update(), zend_vm_trace(), zif_get_defined_functions(), and zif_get_object_vars().

Here is the call graph for this function:

◆ zend_hash_str_add_or_update()

ZEND_API zval* zend_hash_str_add_or_update ( HashTable ht,
const char *  str,
size_t  len,
zval pData,
uint32_t  flag 
)

Definition at line 830 of file zend_hash.c.

831 {
832  if (flag == HASH_ADD) {
833  return zend_hash_str_add(ht, str, len, pData);
834  } else if (flag == HASH_ADD_NEW) {
835  return zend_hash_str_add_new(ht, str, len, pData);
836  } else if (flag == HASH_UPDATE) {
837  return zend_hash_str_update(ht, str, len, pData);
838  } else {
840  return zend_hash_str_update_ind(ht, str, len, pData);
841  }
842 }

References HASH_ADD, HASH_ADD_NEW, HASH_UPDATE, HASH_UPDATE_INDIRECT, len, ZEND_ASSERT(), zend_hash_str_add(), zend_hash_str_add_new(), zend_hash_str_update(), and zend_hash_str_update_ind().

Here is the call graph for this function:

◆ zend_hash_str_del()

ZEND_API int zend_hash_str_del ( HashTable ht,
const char *  str,
size_t  len 
)

Definition at line 1337 of file zend_hash.c.

1338 {
1339  zend_ulong h;
1340  uint32_t nIndex;
1341  uint32_t idx;
1342  Bucket *p;
1343  Bucket *prev = NULL;
1344 
1345  IS_CONSISTENT(ht);
1346  HT_ASSERT_RC1(ht);
1347 
1348  h = zend_inline_hash_func(str, len);
1349  nIndex = h | ht->nTableMask;
1350 
1351  idx = HT_HASH(ht, nIndex);
1352  while (idx != HT_INVALID_IDX) {
1353  p = HT_HASH_TO_BUCKET(ht, idx);
1354  if ((p->h == h)
1355  && p->key
1356  && (ZSTR_LEN(p->key) == len)
1357  && !memcmp(ZSTR_VAL(p->key), str, len)) {
1358  _zend_hash_del_el_ex(ht, idx, p, prev);
1359  return SUCCESS;
1360  }
1361  prev = p;
1362  idx = Z_NEXT(p->val);
1363  }
1364  return FAILURE;
1365 }

References _zend_hash_del_el_ex(), FAILURE, _Bucket::h, HT_ASSERT_RC1, HT_HASH, HT_HASH_TO_BUCKET, HT_INVALID_IDX, IS_CONSISTENT, _Bucket::key, len, _zend_array::nTableMask, NULL, SUCCESS, _Bucket::val, Z_NEXT, ZSTR_LEN, and ZSTR_VAL.

Referenced by check_http_proxy(), php_stream_filter_unregister_factory(), php_stream_tidy_wrapper_error_log(), php_stream_xport_unregister(), php_unregister_url_stream_wrapper(), phpdbg_delete_breakpoint(), phpdbg_webdata_compress(), sapi_unregister_post_entry(), zend_symtable_str_del(), and zif_create_function().

Here is the call graph for this function:

◆ zend_hash_str_del_ind()

ZEND_API int zend_hash_str_del_ind ( HashTable ht,
const char *  str,
size_t  len 
)

Definition at line 1293 of file zend_hash.c.

1294 {
1295  zend_ulong h;
1296  uint32_t nIndex;
1297  uint32_t idx;
1298  Bucket *p;
1299  Bucket *prev = NULL;
1300 
1301  IS_CONSISTENT(ht);
1302  HT_ASSERT_RC1(ht);
1303 
1304  h = zend_inline_hash_func(str, len);
1305  nIndex = h | ht->nTableMask;
1306 
1307  idx = HT_HASH(ht, nIndex);
1308  while (idx != HT_INVALID_IDX) {
1309  p = HT_HASH_TO_BUCKET(ht, idx);
1310  if ((p->h == h)
1311  && p->key
1312  && (ZSTR_LEN(p->key) == len)
1313  && !memcmp(ZSTR_VAL(p->key), str, len)) {
1314  if (Z_TYPE(p->val) == IS_INDIRECT) {
1315  zval *data = Z_INDIRECT(p->val);
1316 
1317  if (UNEXPECTED(Z_TYPE_P(data) == IS_UNDEF)) {
1318  return FAILURE;
1319  } else {
1320  if (ht->pDestructor) {
1321  ht->pDestructor(data);
1322  }
1323  ZVAL_UNDEF(data);
1325  }
1326  } else {
1327  _zend_hash_del_el_ex(ht, idx, p, prev);
1328  }
1329  return SUCCESS;
1330  }
1331  prev = p;
1332  idx = Z_NEXT(p->val);
1333  }
1334  return FAILURE;
1335 }

References _zend_hash_del_el_ex(), FAILURE, _Bucket::h, HASH_FLAG_HAS_EMPTY_IND, HT_ASSERT_RC1, HT_FLAGS, HT_HASH, HT_HASH_TO_BUCKET, HT_INVALID_IDX, IS_CONSISTENT, IS_INDIRECT, IS_UNDEF, _Bucket::key, len, _zend_array::nTableMask, NULL, _zend_array::pDestructor, SUCCESS, UNEXPECTED, _Bucket::val, Z_INDIRECT, Z_NEXT, Z_TYPE, Z_TYPE_P, ZSTR_LEN, ZSTR_VAL, and ZVAL_UNDEF.

Referenced by zend_symtable_str_del_ind().

Here is the call graph for this function:

◆ zend_hash_str_exists()

ZEND_API zend_bool zend_hash_str_exists ( const HashTable ht,
const char *  str,
size_t  len 
)

Definition at line 2128 of file zend_hash.c.

2129 {
2130  zend_ulong h;
2131  Bucket *p;
2132 
2133  IS_CONSISTENT(ht);
2134 
2135  h = zend_inline_hash_func(str, len);
2136  p = zend_hash_str_find_bucket(ht, str, len, h);
2137  return p ? 1 : 0;
2138 }

References IS_CONSISTENT, len, and zend_hash_str_find_bucket().

Referenced by check_http_proxy(), is_protected_variable(), phpdbg_call_register(), phpdbg_do_register(), phpdbg_set_breakpoint_file(), phpdbg_set_breakpoint_method(), phpdbg_set_breakpoint_symbol(), and zend_symtable_str_exists().

Here is the call graph for this function:

◆ zend_hash_str_find()

ZEND_API zval* zend_hash_str_find ( const HashTable ht,
const char *  str,
size_t  len 
)

◆ zend_hash_str_find_bucket()

static Bucket* zend_hash_str_find_bucket ( const HashTable ht,
const char *  str,
size_t  len,
zend_ulong  h 
)
inlinestatic

Definition at line 601 of file zend_hash.c.

602 {
603  uint32_t nIndex;
604  uint32_t idx;
605  Bucket *p, *arData;
606 
607  arData = ht->arData;
608  nIndex = h | ht->nTableMask;
609  idx = HT_HASH_EX(arData, nIndex);
610  while (idx != HT_INVALID_IDX) {
611  ZEND_ASSERT(idx < HT_IDX_TO_HASH(ht->nTableSize));
612  p = HT_HASH_TO_BUCKET_EX(arData, idx);
613  if ((p->h == h)
614  && p->key
615  && (ZSTR_LEN(p->key) == len)
616  && !memcmp(ZSTR_VAL(p->key), str, len)) {
617  return p;
618  }
619  idx = Z_NEXT(p->val);
620  }
621  return NULL;
622 }

References _zend_array::arData, _Bucket::h, HT_HASH_EX, HT_INVALID_IDX, _Bucket::key, len, _zend_array::nTableMask, _zend_array::nTableSize, NULL, _Bucket::val, Z_NEXT, ZEND_ASSERT(), ZSTR_LEN, and ZSTR_VAL.

Referenced by _zend_hash_str_add_or_update_i(), zend_hash_str_exists(), and zend_hash_str_find().

Here is the call graph for this function:

◆ zend_hash_str_update()

ZEND_API zval* zend_hash_str_update ( HashTable ht,
const char *  str,
size_t  len,
zval pData 
)

Definition at line 844 of file zend_hash.c.

845 {
846  zend_ulong h = zend_hash_func(str, len);
847 
848  return _zend_hash_str_add_or_update_i(ht, str, len, h, pData, HASH_UPDATE);
849 }

References _zend_hash_str_add_or_update_i(), HASH_UPDATE, len, and zend_hash_func().

Referenced by check_http_proxy(), do_cli(), LoadDirectory(), php_ini_parser_cb(), php_init_config(), php_stream_context_set_option(), zend_closure_get_debug_info(), zend_hash_str_add_or_update(), zend_hash_str_update_ptr(), zend_set_hash_symbol(), zend_set_local_var_str(), zend_symtable_str_update(), and zend_ts_hash_str_update().

Here is the call graph for this function:

◆ zend_hash_str_update_ind()

ZEND_API zval* zend_hash_str_update_ind ( HashTable ht,
const char *  str,
size_t  len,
zval pData 
)

Definition at line 851 of file zend_hash.c.

852 {
853  zend_ulong h = zend_hash_func(str, len);
854 
856 }

References _zend_hash_str_add_or_update_i(), HASH_UPDATE, HASH_UPDATE_INDIRECT, len, and zend_hash_func().

Referenced by php_error_cb(), php_verror(), zend_hash_str_add_or_update(), zend_set_local_var_str(), and zend_symtable_str_update_ind().

Here is the call graph for this function:

◆ zend_hash_to_packed()

ZEND_API void zend_hash_to_packed ( HashTable ht)

◆ zend_hash_update()

ZEND_API zval* zend_hash_update ( HashTable ht,
zend_string key,
zval pData 
)

Definition at line 815 of file zend_hash.c.

816 {
817  return _zend_hash_add_or_update_i(ht, key, pData, HASH_UPDATE);
818 }

References _zend_hash_add_or_update_i(), and HASH_UPDATE.

Referenced by object_properties_load(), php_auto_globals_create_cookie(), php_auto_globals_create_env(), php_auto_globals_create_files(), php_auto_globals_create_get(), php_auto_globals_create_globals(), php_auto_globals_create_post(), php_auto_globals_create_request(), php_auto_globals_create_server(), php_autoglobal_merge(), php_build_argv(), php_ini_parser_cb(), phpdbg_print_symbols(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(), ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(), zend_closure_bind_var(), zend_closure_get_debug_info(), zend_compile_static_var_common(), zend_detach_symbol_table(), zend_fetch_dimension_address_inner(), zend_fetch_var_address_helper_SPEC_CONST_UNUSED(), zend_fetch_var_address_helper_SPEC_CV_UNUSED(), zend_fetch_var_address_helper_SPEC_TMPVAR_UNUSED(), zend_hash_add_or_update(), zend_hash_copy(), zend_hash_merge_ex(), zend_hash_update_ptr(), zend_proptable_to_symtable(), zend_register_persistent_resource_ex(), zend_set_local_var(), zend_std_get_property_ptr_ptr(), zend_symtable_to_proptable(), zend_symtable_update(), zend_try_ct_eval_array(), zend_ts_hash_update(), ZEND_VM_HANDLER(), and ZEND_VM_HELPER().

Here is the call graph for this function:

◆ zend_hash_update_ind()

ZEND_API zval* zend_hash_update_ind ( HashTable ht,
zend_string key,
zval pData 
)

Definition at line 820 of file zend_hash.c.

821 {
823 }

References _zend_hash_add_or_update_i(), HASH_UPDATE, and HASH_UPDATE_INDIRECT.

Referenced by php_register_variable_quick(), zend_hash_add_or_update(), zend_set_local_var(), and zend_symtable_update_ind().

Here is the call graph for this function:

◆ zend_proptable_to_symtable()

ZEND_API HashTable* zend_proptable_to_symtable ( HashTable ht,
zend_bool  always_duplicate 
)

Definition at line 2694 of file zend_hash.c.

2695 {
2696  zend_ulong num_key;
2697  zend_string *str_key;
2698  zval *zv;
2699 
2700  ZEND_HASH_FOREACH_STR_KEY(ht, str_key) {
2701  /* The `str_key &&` here might seem redundant: property tables should
2702  * only have string keys. Unfortunately, this isn't true, at the very
2703  * least because of ArrayObject, which stores a symtable where the
2704  * property table should be.
2705  */
2706  if (str_key && ZEND_HANDLE_NUMERIC(str_key, num_key)) {
2707  goto convert;
2708  }
2710 
2711  if (always_duplicate) {
2712  return zend_array_dup(ht);
2713  }
2714 
2715  if (EXPECTED(!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE))) {
2716  GC_ADDREF(ht);
2717  }
2718 
2719  return ht;
2720 
2721 convert:
2722  {
2724 
2725  ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, str_key, zv) {
2726  do {
2727  if (Z_OPT_REFCOUNTED_P(zv)) {
2728  if (Z_ISREF_P(zv) && Z_REFCOUNT_P(zv) == 1) {
2729  zv = Z_REFVAL_P(zv);
2730  if (!Z_OPT_REFCOUNTED_P(zv)) {
2731  break;
2732  }
2733  }
2734  Z_ADDREF_P(zv);
2735  }
2736  } while (0);
2737  /* Again, thank ArrayObject for `!str_key ||`. */
2738  if (!str_key || ZEND_HANDLE_NUMERIC(str_key, num_key)) {
2739  zend_hash_index_update(new_ht, num_key, zv);
2740  } else {
2741  zend_hash_update(new_ht, str_key, zv);
2742  }
2744 
2745  return new_ht;
2746  }
2747 }

References EXPECTED, GC_ADDREF, GC_FLAGS, IS_ARRAY_IMMUTABLE, Z_ADDREF_P, Z_ISREF_P, Z_OPT_REFCOUNTED_P, Z_REFCOUNT_P, Z_REFVAL_P, zend_array_dup(), ZEND_HANDLE_NUMERIC, ZEND_HASH_FOREACH_END, ZEND_HASH_FOREACH_KEY_VAL, ZEND_HASH_FOREACH_STR_KEY, zend_hash_index_update(), zend_hash_num_elements, zend_hash_update(), and zend_new_array.

Referenced by convert_to_array(), ZEND_CAST_SPEC_CONST_HANDLER(), ZEND_CAST_SPEC_CV_HANDLER(), ZEND_CAST_SPEC_TMP_HANDLER(), ZEND_CAST_SPEC_VAR_HANDLER(), ZEND_VM_COLD_CONST_HANDLER(), and zif_get_object_vars().

Here is the call graph for this function:

◆ zend_symtable_clean()

ZEND_API void zend_symtable_clean ( HashTable ht)

Definition at line 1586 of file zend_hash.c.

1587 {
1588  Bucket *p, *end;
1589 
1590  IS_CONSISTENT(ht);
1591  HT_ASSERT_RC1(ht);
1592 
1593  if (ht->nNumUsed) {
1594  p = ht->arData;
1595  end = p + ht->nNumUsed;
1596  if (HT_HAS_STATIC_KEYS_ONLY(ht)) {
1597  do {
1599  } while (++p != end);
1600  } else if (HT_IS_WITHOUT_HOLES(ht)) {
1601  do {
1603  if (EXPECTED(p->key)) {
1604  zend_string_release(p->key);
1605  }
1606  } while (++p != end);
1607  } else {
1608  do {
1609  if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF)) {
1611  if (EXPECTED(p->key)) {
1612  zend_string_release(p->key);
1613  }
1614  }
1615  } while (++p != end);
1616  }
1617  HT_HASH_RESET(ht);
1618  }
1619  ht->nNumUsed = 0;
1620  ht->nNumOfElements = 0;
1621  ht->nNextFreeElement = 0;
1622  ht->nInternalPointer = 0;
1623 }

References _zend_array::arData, EXPECTED, HT_ASSERT_RC1, HT_HAS_STATIC_KEYS_ONLY, HT_HASH_RESET, HT_IS_WITHOUT_HOLES, i_zval_ptr_dtor(), IS_CONSISTENT, IS_UNDEF, _Bucket::key, _zend_array::nInternalPointer, _zend_array::nNextFreeElement, _zend_array::nNumOfElements, _zend_array::nNumUsed, _Bucket::val, Z_TYPE, and ZEND_FILE_LINE_CC.

Referenced by zend_clean_and_cache_symbol_table().

Here is the call graph for this function:

◆ zend_symtable_to_proptable()

ZEND_API HashTable* zend_symtable_to_proptable ( HashTable ht)

Definition at line 2641 of file zend_hash.c.

2642 {
2643  zend_ulong num_key;
2644  zend_string *str_key;
2645  zval *zv;
2646 
2647  if (UNEXPECTED(HT_IS_PACKED(ht))) {
2648  goto convert;
2649  }
2650 
2651  ZEND_HASH_FOREACH_STR_KEY(ht, str_key) {
2652  if (!str_key) {
2653  goto convert;
2654  }
2656 
2657  if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
2658  GC_ADDREF(ht);
2659  }
2660 
2661  return ht;
2662 
2663 convert:
2664  {
2666 
2667  ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, str_key, zv) {
2668  if (!str_key) {
2669  str_key = zend_long_to_str(num_key);
2670  zend_string_delref(str_key);
2671  }
2672  do {
2673  if (Z_OPT_REFCOUNTED_P(zv)) {
2674  if (Z_ISREF_P(zv) && Z_REFCOUNT_P(zv) == 1) {
2675  zv = Z_REFVAL_P(zv);
2676  if (!Z_OPT_REFCOUNTED_P(zv)) {
2677  break;
2678  }
2679  }
2680  Z_ADDREF_P(zv);
2681  }
2682  } while (0);
2683  zend_hash_update(new_ht, str_key, zv);
2685 
2686  return new_ht;
2687  }
2688 }

References GC_ADDREF, GC_FLAGS, HT_IS_PACKED, IS_ARRAY_IMMUTABLE, UNEXPECTED, Z_ADDREF_P, Z_ISREF_P, Z_OPT_REFCOUNTED_P, Z_REFCOUNT_P, Z_REFVAL_P, ZEND_HASH_FOREACH_END, ZEND_HASH_FOREACH_KEY_VAL, ZEND_HASH_FOREACH_STR_KEY, zend_hash_num_elements, zend_hash_update(), zend_long_to_str(), zend_new_array, and zend_string_delref().

Referenced by convert_to_object(), ZEND_CAST_SPEC_CONST_HANDLER(), ZEND_CAST_SPEC_CV_HANDLER(), ZEND_CAST_SPEC_TMP_HANDLER(), ZEND_CAST_SPEC_VAR_HANDLER(), and ZEND_VM_COLD_CONST_HANDLER().

Here is the call graph for this function:

Variable Documentation

◆ uninitialized_bucket

const uint32_t uninitialized_bucket[-((uint32_t) -2)]
static
Initial value:
=
{ ((uint32_t) -1) , ((uint32_t) -1) }

Definition at line 178 of file zend_hash.c.

Referenced by _zend_hash_init_int(), and zend_array_dup().

◆ zend_empty_array

const ZEND_API HashTable zend_empty_array
Initial value:
= {
.gc.refcount = 2,
.gc.u.type_info = 7 | ( (1<<6) << 0 ),
.u.flags = (1<<4) ,
.nTableMask = ((uint32_t) -2) ,
.arData = (Bucket*)&uninitialized_bucket[2],
.nNumUsed = 0,
.nNumOfElements = 0,
.nTableSize = 8 ,
.nInternalPointer = 0,
.nNextFreeElement = 0,
.pDestructor = zval_ptr_dtor
}

Definition at line 181 of file zend_hash.c.

zval_ptr_dtor
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
zend_hash_find
ZEND_API zval * zend_hash_find(const HashTable *ht, zend_string *key)
Definition: zend_hash.c:2086
ZEND_LONG_MAX
#define ZEND_LONG_MAX
Definition: zend_long.h:44
MIN
#define MIN(a, b)
Definition: php_http_parser.c:27
_zend_hash_add_or_update_i
static zval * _zend_hash_add_or_update_i(HashTable *ht, zend_string *key, zval *pData, uint32_t flag)
Definition: zend_hash.c:644
zend_hash_compare_impl
static int zend_hash_compare_impl(HashTable *ht1, HashTable *ht2, compare_func_t compar, zend_bool ordered)
Definition: zend_hash.c:2453
ZVAL_PTR_DTOR
#define ZVAL_PTR_DTOR
Definition: zend_variables.h:93
HT_MIN_MASK
#define HT_MIN_MASK
Definition: zend_types.h:276
HT_POISONED_PTR
#define HT_POISONED_PTR
Definition: zend_hash.c:39
HT_INVALID_IDX
#define HT_INVALID_IDX
Definition: zend_types.h:274
_zend_hash_key::h
zend_ulong h
Definition: zend_hash.h:84
_zend_array
Definition: zend_types.h:237
zend_string_delref
static uint32_t zend_string_delref(zend_string *s)
Definition: zend_string.h:123
zend_hash_str_update
ZEND_API zval * zend_hash_str_update(HashTable *ht, const char *str, size_t len, zval *pData)
Definition: zend_hash.c:844
ZEND_ASSERT
ZEND_ASSERT(fbc->type==ZEND_INTERNAL_FUNCTION)
_zend_hash_get_current_pos
static HashPosition _zend_hash_get_current_pos(const HashTable *ht)
Definition: zend_hash.c:388
ZEND_HASH_FOREACH_KEY_VAL
#define ZEND_HASH_FOREACH_KEY_VAL(ht, _h, _key, _val)
Definition: zend_hash.h:982
GC_REMOVE_FROM_BUFFER
#define GC_REMOVE_FROM_BUFFER(p)
Definition: zend_gc.h:56
_Bucket::key
zend_string * key
Definition: zend_types.h:232
pefree
#define pefree(ptr, persistent)
Definition: zend_alloc.h:195
zend_hash_destroy
ZEND_API void zend_hash_destroy(HashTable *ht)
Definition: zend_hash.c:1402
HT_SIZE_TO_MASK
#define HT_SIZE_TO_MASK(nTableSize)
Definition: zend_types.h:304
ZSTR_H
#define ZSTR_H(zstr)
Definition: zend_string.h:55
ZVAL_COPY_VALUE
#define ZVAL_COPY_VALUE(z, v)
Definition: zend_types.h:1051
GC_FLAGS_SHIFT
#define GC_FLAGS_SHIFT
Definition: zend_types.h:477
zend_array_dup_element
static int zend_array_dup_element(HashTable *source, HashTable *target, uint32_t idx, Bucket *p, Bucket *q, int packed, int static_keys, int with_holes)
Definition: zend_hash.c:1819
zend_long
int32_t zend_long
Definition: zend_long.h:41
zend_hash_num_elements
#define zend_hash_num_elements(ht)
Definition: zend_hash.h:254
ZEND_HASH_APPLY_REMOVE
#define ZEND_HASH_APPLY_REMOVE
Definition: zend_hash.h:135
zend_hash_check_size
static uint32_t zend_hash_check_size(uint32_t nSize)
Definition: zend_hash.c:85
zend_hash_replace_checker_wrapper
static zend_bool zend_hash_replace_checker_wrapper(HashTable *target, zval *source_data, Bucket *p, void *pParam, merge_checker_func_t merge_checker_func)
Definition: zend_hash.c:2052
_zend_hash_init_int
static void _zend_hash_init_int(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent)
Definition: zend_hash.c:195
FAILURE
@ FAILURE
Definition: zend_types.h:54
IS_ARRAY
#define IS_ARRAY
Definition: zend_types.h:390
ZSTR_VAL
#define ZSTR_VAL(zstr)
Definition: zend_string.h:53
HT_HASH_EX
#define HT_HASH_EX(data, idx)
Definition: zend_types.h:299
GC_IS_RECURSIVE
#define GC_IS_RECURSIVE(p)
Definition: zend_types.h:562
ZEND_HASH_FOREACH_STR_KEY
#define ZEND_HASH_FOREACH_STR_KEY(ht, _key)
Definition: zend_hash.h:963
_Bucket::val
zval val
Definition: zend_types.h:230
_HashTableIterator::pos
HashPosition pos
Definition: zend_types.h:353
zend_hash_real_init_mixed_ex
static void zend_hash_real_init_mixed_ex(HashTable *ht)
Definition: zend_hash.c:127
_zend_hash_str_add_or_update_i
static zval * _zend_hash_str_add_or_update_i(HashTable *ht, const char *str, size_t len, zend_ulong h, zval *pData, uint32_t flag)
Definition: zend_hash.c:729
Z_ARRVAL_P
#define Z_ARRVAL_P(zval_p)
Definition: zend_types.h:661
GC_PERSISTENT
#define GC_PERSISTENT
Definition: zend_types.h:519
HT_HASH_TO_BUCKET
#define HT_HASH_TO_BUCKET(ht, idx)
Definition: zend_types.h:340
zend_error_noreturn
#define zend_error_noreturn
Definition: zend.h:76
zend_hash_next_index_insert
ZEND_API zval * zend_hash_next_index_insert(HashTable *ht, zval *pData)
Definition: zend_hash.c:1013
ZVAL_UNDEF
#define ZVAL_UNDEF(z)
Definition: zend_types.h:722
GC_REFCOUNT
#define GC_REFCOUNT(p)
Definition: zend_types.h:467
zend_hash_update_ind
ZEND_API zval * zend_hash_update_ind(HashTable *ht, zend_string *key, zval *pData)
Definition: zend_hash.c:820
zend_ulong
uint32_t zend_ulong
Definition: zend_long.h:42
_zend_hash_iterators_remove
static void _zend_hash_iterators_remove(HashTable *ht)
Definition: zend_hash.c:497
SUCCESS
@ SUCCESS
Definition: zend_types.h:53
ZVAL_LONG
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr))
_zend_hash_index_add_or_update_i
static zval * _zend_hash_index_add_or_update_i(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag)
Definition: zend_hash.c:896
zend_hash_bucket_renum_swap
ZEND_API void zend_hash_bucket_renum_swap(Bucket *p, Bucket *q)
Definition: zend_hash.c:2361
HT_HAS_STATIC_KEYS_ONLY
#define HT_HAS_STATIC_KEYS_ONLY(ht)
Definition: zend_hash.h:54
_Bucket::h
zend_ulong h
Definition: zend_types.h:231
_zend_array::nTableMask
uint32_t nTableMask
Definition: zend_types.h:249
GC_ADDREF
#define GC_ADDREF(p)
Definition: zend_types.h:469
zend_array_dup_packed_elements
static void zend_array_dup_packed_elements(HashTable *source, HashTable *target, int with_holes)
Definition: zend_hash.c:1873
_zend_hash_del_el
static void _zend_hash_del_el(HashTable *ht, uint32_t idx, Bucket *p)
Definition: zend_hash.c:1188
zend_hash_index_update
ZEND_API zval * zend_hash_index_update(HashTable *ht, zend_ulong h, zval *pData)
Definition: zend_hash.c:1008
zend_hash_index_find
ZEND_API zval * zend_hash_index_find(const HashTable *ht, zend_ulong h)
Definition: zend_hash.c:2140
ALLOC_HASHTABLE
#define ALLOC_HASHTABLE(ht)
Definition: zend_alloc.h:232
_zend_hash_iterators_update
ZEND_API void _zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
Definition: zend_hash.c:534
emalloc
#define emalloc(size)
Definition: zend_alloc.h:157
ZEND_HASH_FOREACH_END
#define ZEND_HASH_FOREACH_END()
Definition: zend_hash.h:918
HASH_ADD
#define HASH_ADD
Definition: zend_hash.h:31
HT_SIZE
#define HT_SIZE(ht)
Definition: zend_types.h:312
_HashTableIterator
Definition: zend_types.h:351
E_ERROR
#define E_ERROR
Definition: zend_errors.h:23
zend_hash_next_index_insert_new
ZEND_API zval * zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
Definition: zend_hash.c:1018
GC_UNPROTECT_RECURSION
#define GC_UNPROTECT_RECURSION(p)
Definition: zend_types.h:569
zend_array_dup
ZEND_API HashTable * zend_array_dup(HashTable *source)
Definition: zend_hash.c:1917
EG
EG(current_execute_data)
efree
#define efree(ptr)
Definition: zend_alloc.h:161
SEPARATE_ARRAY
#define SEPARATE_ARRAY(zv)
Definition: zend_types.h:1170
zend_hash_real_init_mixed
ZEND_API void zend_hash_real_init_mixed(HashTable *ht)
Definition: zend_hash.c:255
zend_string_hash_val
static zend_ulong zend_string_hash_val(zend_string *s)
Definition: zend_string.h:97
zend_array_dup_elements
static uint32_t zend_array_dup_elements(HashTable *source, HashTable *target, int static_keys, int with_holes)
Definition: zend_hash.c:1889
HASH_ADD_NEW
#define HASH_ADD_NEW
Definition: zend_hash.h:33
HT_IS_WITHOUT_HOLES
#define HT_IS_WITHOUT_HOLES(ht)
Definition: zend_hash.h:51
HASH_FLAG_MASK
#define HASH_FLAG_MASK
Definition: zend_hash.h:44
GC_IMMUTABLE
#define GC_IMMUTABLE
Definition: zend_types.h:518
IS_ARRAY_PERSISTENT
#define IS_ARRAY_PERSISTENT
Definition: zend_types.h:553
_zend_array::nNumUsed
uint32_t nNumUsed
Definition: zend_types.h:251
zend_string_addref
static uint32_t zend_string_addref(zend_string *s)
Definition: zend_string.h:115
HT_ASSERT
#define HT_ASSERT(ht, expr)
Definition: zend_hash.c:34
_zval_struct
Definition: zend_types.h:182
uint32_t
unsigned __int32 uint32_t
Definition: php_stdint.h:94
GC_FLAGS
#define GC_FLAGS(p)
Definition: zend_types.h:494
zend_hash_iterators_remove
static void zend_hash_iterators_remove(HashTable *ht)
Definition: zend_hash.c:510
HASH_FLAG_STATIC_KEYS
#define HASH_FLAG_STATIC_KEYS
Definition: zend_hash.h:39
zend_long_to_str
ZEND_API zend_string * zend_long_to_str(zend_long num)
Definition: zend_operators.c:2994
HT_MIN_SIZE
#define HT_MIN_SIZE
Definition: zend_types.h:277
HASH_KEY_NON_EXISTENT
#define HASH_KEY_NON_EXISTENT
Definition: zend_hash.h:28
ZSTR_IS_INTERNED
#define ZSTR_IS_INTERNED(s)
Definition: zend_string.h:69
Z_ADDREF_P
#define Z_ADDREF_P(pz)
Definition: zend_types.h:935
Z_TYPE_INFO
#define Z_TYPE_INFO(zval)
Definition: zend_types.h:426
_Bucket
Definition: zend_types.h:229
HT_INC_ITERATORS_COUNT
#define HT_INC_ITERATORS_COUNT(ht)
Definition: zend_hash.h:69
_zend_array::nNextFreeElement
zend_long nNextFreeElement
Definition: zend_types.h:255
ZVAL_NULL
ZVAL_NULL(ret)
HASH_KEY_IS_STRING
#define HASH_KEY_IS_STRING
Definition: zend_hash.h:26
ZVAL_STR_COPY
#define ZVAL_STR_COPY(z, s)
Definition: zend_types.h:779
HT_HAS_ITERATORS
#define HT_HAS_ITERATORS(ht)
Definition: zend_hash.h:65
zend_hash_func
ZEND_API zend_ulong zend_hash_func(const char *str, size_t len)
Definition: zend_string.c:54
HT_ASSERT_RC1
#define HT_ASSERT_RC1(ht)
Definition: zend_hash.c:37
_HashTableIterator::ht
HashTable * ht
Definition: zend_types.h:352
HT_ITERATORS_OVERFLOW
#define HT_ITERATORS_OVERFLOW(ht)
Definition: zend_hash.h:64
Z_INDIRECT_P
#define Z_INDIRECT_P(zval_p)
Definition: zend_types.h:711
HT_USED_SIZE
#define HT_USED_SIZE(ht)
Definition: zend_types.h:314
HT_HASH_RESET_PACKED
#define HT_HASH_RESET_PACKED(ht)
Definition: zend_types.h:336
zend_hash_find_bucket
static Bucket * zend_hash_find_bucket(const HashTable *ht, zend_string *key, zend_bool known_hash)
Definition: zend_hash.c:560
memcpy
#define memcpy(d, s, n)
Definition: php.h:249
Z_TYPE
#define Z_TYPE(zval)
Definition: zend_types.h:420
result
zval * result
Definition: zend_vm_def.h:116
zend_hash_add
ZEND_API zval * zend_hash_add(HashTable *ht, zend_string *key, zval *pData)
Definition: zend_hash.c:810
zend_hash_packed_grow
static void zend_hash_packed_grow(HashTable *ht)
Definition: zend_hash.c:229
HT_SET_DATA_ADDR
#define HT_SET_DATA_ADDR(ht, ptr)
Definition: zend_types.h:343
Z_INDIRECT
#define Z_INDIRECT(zval)
Definition: zend_types.h:710
SIZEOF_ZEND_LONG
#define SIZEOF_ZEND_LONG
Definition: zend_long.h:49
zend_hash_real_init_packed_ex
static void zend_hash_real_init_packed_ex(HashTable *ht)
Definition: zend_hash.c:120
HashPosition
uint32_t HashPosition
Definition: zend_types.h:349
Z_TYPE_INFO_P
#define Z_TYPE_INFO_P(zval_p)
Definition: zend_types.h:427
HASH_UPDATE_INDIRECT
#define HASH_UPDATE_INDIRECT
Definition: zend_hash.h:32
HASH_ADD_NEXT
#define HASH_ADD_NEXT
Definition: zend_hash.h:34
UNEXPECTED
#define UNEXPECTED(condition)
Definition: zend_portability.h:326
FREE_HASHTABLE
#define FREE_HASHTABLE(ht)
Definition: zend_alloc.h:235
HASH_UPDATE
#define HASH_UPDATE
Definition: zend_hash.h:30
HT_DEC_ITERATORS_COUNT
#define HT_DEC_ITERATORS_COUNT(ht)
Definition: zend_hash.h:71
ZEND_HASH_IF_FULL_DO_RESIZE
#define ZEND_HASH_IF_FULL_DO_RESIZE(ht)
Definition: zend_hash.c:78
target
static mach_port_name_t target
Definition: fpm_trace_mach.c:16
len
size_t len
Definition: ioutil.h:168
GC_SET_REFCOUNT
#define GC_SET_REFCOUNT(p, rc)
Definition: zend_types.h:468
IS_INDIRECT
#define IS_INDIRECT
Definition: zend_types.h:399
HASH_FLAG_INITIALIZED
#define HASH_FLAG_INITIALIZED
Definition: zend_hash.h:38
zend_array_recalc_elements
static uint32_t zend_array_recalc_elements(HashTable *ht)
Definition: zend_hash.c:347
zend_new_array
#define zend_new_array(size)
Definition: zend_hash.h:274
_zend_array::nNumOfElements
uint32_t nNumOfElements
Definition: zend_types.h:252
ZEND_HASH_APPLY_STOP
#define ZEND_HASH_APPLY_STOP
Definition: zend_hash.h:136
HT_IS_PACKED
#define HT_IS_PACKED(ht)
Definition: zend_hash.h:48
zend_hash_iterators_update
static void zend_hash_iterators_update(HashTable *ht, HashPosition from, HashPosition to)
Definition: zend_hash.h:297
zend_hash_index_add_new
ZEND_API zval * zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
Definition: zend_hash.c:1003
zend_hash_real_init_ex
static void zend_hash_real_init_ex(HashTable *ht, int packed)
Definition: zend_hash.c:167
_zend_array::pDestructor
dtor_func_t pDestructor
Definition: zend_types.h:256
_zend_hash_get_valid_pos
static HashPosition _zend_hash_get_valid_pos(const HashTable *ht, HashPosition pos)
Definition: zend_hash.c:380
erealloc
#define erealloc(ptr, size)
Definition: zend_alloc.h:165
HT_ITERATORS_COUNT
#define HT_ITERATORS_COUNT(ht)
Definition: zend_hash.h:63
i_zval_ptr_dtor
static void i_zval_ptr_dtor(zval *zval_ptr)
Definition: zend_variables.h:39
HT_SIZE_EX
#define HT_SIZE_EX(nTableSize, nTableMask)
Definition: zend_types.h:310
HASH_FLAG_HAS_EMPTY_IND
#define HASH_FLAG_HAS_EMPTY_IND
Definition: zend_hash.h:40
SET_INCONSISTENT
#define SET_INCONSISTENT(n)
Definition: zend_hash.c:75
ZSTR_LEN
#define ZSTR_LEN(zstr)
Definition: zend_string.h:54
zend_hash_iterators_lower_pos
ZEND_API HashPosition zend_hash_iterators_lower_pos(HashTable *ht, HashPosition start)
Definition: zend_hash.c:517
HT_GET_DATA_ADDR
#define HT_GET_DATA_ADDR(ht)
Definition: zend_types.h:346
ZEND_FILE_LINE_CC
#define ZEND_FILE_LINE_CC
Definition: zend_portability.h:409
IS_UNDEF
#define IS_UNDEF
Definition: zend_types.h:383
zend_hash_packed_to_hash
ZEND_API void zend_hash_packed_to_hash(HashTable *ht)
Definition: zend_hash.c:263
ZEND_HASH_FOREACH_VAL
#define ZEND_HASH_FOREACH_VAL(ht, _val)
Definition: zend_hash.h:947
zend_hash_bucket_packed_swap
ZEND_API void zend_hash_bucket_packed_swap(Bucket *p, Bucket *q)
Definition: zend_hash.c:2370
zend_hash_index_find_bucket
static Bucket * zend_hash_index_find_bucket(const HashTable *ht, zend_ulong h)
Definition: zend_hash.c:624
_zend_hash_key
Definition: zend_hash.h:83
MAX_LENGTH_OF_LONG
#define MAX_LENGTH_OF_LONG
Definition: zend_long.h:108
uninitialized_bucket
static const uint32_t uninitialized_bucket[-((uint32_t) -2)]
Definition: zend_hash.c:178
tmp
zval tmp
Definition: zend_vm_def.h:2088
Z_REFCOUNT_P
#define Z_REFCOUNT_P(pz)
Definition: zend_types.h:933
GC_COLLECTABLE
#define GC_COLLECTABLE
Definition: zend_types.h:516
zend_hash_str_update_ind
ZEND_API zval * zend_hash_str_update_ind(HashTable *ht, const char *str, size_t len, zval *pData)
Definition: zend_hash.c:851
GC_PROTECT_RECURSION
#define GC_PROTECT_RECURSION(p)
Definition: zend_types.h:565
perealloc2
#define perealloc2(ptr, size, copy_size, persistent)
Definition: zend_alloc.h:206
HASH_FLAG_PACKED
#define HASH_FLAG_PACKED
Definition: zend_hash.h:37
Z_ISREF_P
#define Z_ISREF_P(zval_p)
Definition: zend_types.h:628
HT_HASH
#define HT_HASH(ht, idx)
Definition: zend_types.h:301
zend_hash_add_new
ZEND_API zval * zend_hash_add_new(HashTable *ht, zend_string *key, zval *pData)
Definition: zend_hash.c:825
Z_NEXT
#define Z_NEXT(zval)
Definition: zend_types.h:429
_zend_array::arData
Bucket * arData
Definition: zend_types.h:250
start
restart stop start
Definition: phpdbg.init.d:112
zend_hash_bucket_swap
ZEND_API void zend_hash_bucket_swap(Bucket *p, Bucket *q)
Definition: zend_hash.c:2342
HT_FLAGS
#define HT_FLAGS(ht)
Definition: zend_hash.h:46
Z_ISUNDEF
#define Z_ISUNDEF(zval)
Definition: zend_types.h:630
Z_REFVAL_P
#define Z_REFVAL_P(zval_p)
Definition: zend_types.h:700
IS_ARRAY_IMMUTABLE
#define IS_ARRAY_IMMUTABLE
Definition: zend_types.h:552
ZEND_HANDLE_NUMERIC
#define ZEND_HANDLE_NUMERIC(key, idx)
Definition: zend_hash.h:334
EXPECTED
#define EXPECTED(condition)
Definition: zend_portability.h:325
_zend_hash_key::key
zend_string * key
Definition: zend_hash.h:85
zend_string_init
static zend_string * zend_string_init(const char *str, size_t len, int persistent)
Definition: zend_string.h:153
zend_hash_rehash
ZEND_API int zend_hash_rehash(HashTable *ht)
Definition: zend_hash.c:1048
_zend_array::nTableSize
uint32_t nTableSize
Definition: zend_types.h:253
zend_hash_real_init
ZEND_API void zend_hash_real_init(HashTable *ht, zend_bool packed)
Definition: zend_hash.c:239
IS_NULL
#define IS_NULL
Definition: zend_types.h:384
IS_CONSISTENT
#define IS_CONSISTENT(a)
Definition: zend_hash.c:74
zend_hash_index_add
ZEND_API zval * zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
Definition: zend_hash.c:998
zend_hash_str_add_new
ZEND_API zval * zend_hash_str_add_new(HashTable *ht, const char *str, size_t len, zval *pData)
Definition: zend_hash.c:865
GC_TYPE_INFO
#define GC_TYPE_INFO(p)
Definition: zend_types.h:492
HASH_KEY_IS_LONG
#define HASH_KEY_IS_LONG
Definition: zend_hash.h:27
_zend_array::nInternalPointer
uint32_t nInternalPointer
Definition: zend_types.h:254
swap_func_t
void(* swap_func_t)(void *, void *)
Definition: zend_types.h:99
Z_TYPE_P
#define Z_TYPE_P(zval_p)
Definition: zend_types.h:421
_zend_string
Definition: zend_types.h:222
zend_hash_str_find_bucket
static Bucket * zend_hash_str_find_bucket(const HashTable *ht, const char *str, size_t len, zend_ulong h)
Definition: zend_hash.c:601
HT_HASH_RESET
#define HT_HASH_RESET(ht)
Definition: zend_types.h:333
NULL
NULL
Definition: main.c:709
_zend_hash_del_el_ex
static void _zend_hash_del_el_ex(HashTable *ht, uint32_t idx, Bucket *p, Bucket *prev)
Definition: zend_hash.c:1141
Z_OPT_REFCOUNTED_P
#define Z_OPT_REFCOUNTED_P(zval_p)
Definition: zend_types.h:618
zend_hash_update
ZEND_API zval * zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
Definition: zend_hash.c:815
pemalloc
#define pemalloc(size, persistent)
Definition: zend_alloc.h:193
zend_hash_str_add
ZEND_API zval * zend_hash_str_add(HashTable *ht, const char *str, size_t len, zval *pData)
Definition: zend_hash.c:858