49#define ZEND_WEAKREF_TAG_REF 0
50#define ZEND_WEAKREF_TAG_MAP 1
51#define ZEND_WEAKREF_TAG_HT 2
52#define ZEND_WEAKREF_GET_TAG(p) (((uintptr_t) (p)) & 3)
53#define ZEND_WEAKREF_GET_PTR(p) ((void *) (((uintptr_t) (p)) & ~3))
54#define ZEND_WEAKREF_ENCODE(p, t) ((void *) (((uintptr_t) (p)) | (t)))
61#define zend_weakref_from(o) ((zend_weakref*)(((char*) o) - XtOffsetOf(zend_weakref, std)))
62#define zend_weakref_fetch(z) zend_weakref_from(Z_OBJ_P(z))
64#define zend_weakmap_from(o) ((zend_weakmap*)(((char*) o) - XtOffsetOf(zend_weakmap, std)))
65#define zend_weakmap_fetch(z) zend_weakmap_from(Z_OBJ_P(z))
67static inline void zend_weakref_unref_single(
81static void zend_weakref_unref(
zend_object *
object,
void *tagged_ptr) {
87 zend_weakref_unref_single(
93 zend_weakref_unref_single(
ptr, tag,
object);
97static void zend_weakref_register(
zend_object *
object,
void *payload) {
100 zend_ulong obj_key = zend_object_to_weakref_key(
object);
110 zend_hash_index_add_new_ptr(
ht, (
zend_ulong) payload, payload);
117 zend_hash_index_add_new_ptr(
ht, (
zend_ulong) tagged_ptr, tagged_ptr);
118 zend_hash_index_add_new_ptr(
ht, (
zend_ulong) payload, payload);
123static void zend_weakref_unregister(
zend_object *
object,
void *payload,
bool weakref_free) {
124 zend_ulong obj_key = zend_object_to_weakref_key(
object);
125 void *tagged_ptr = zend_hash_index_find_ptr(&
EG(weakrefs), obj_key);
126 ZEND_ASSERT(tagged_ptr &&
"Weakref not registered?");
137 zend_weakref_unref_single(
ptr, tag,
object);
147 void *old_payload = zend_hash_index_find_ptr(
ht, (
zend_ulong) payload);
148 ZEND_ASSERT(old_payload &&
"Weakref not registered?");
152 if (zend_hash_num_elements(
ht) == 0) {
161 zend_weakref_unref_single(
195 const zend_ulong obj_key = zend_object_to_weakref_key(
object);
196 void *tagged_ptr = zend_hash_index_find_ptr(&
EG(weakrefs), obj_key);
198 ZEND_ASSERT(tagged_ptr &&
"Tracking of the IS_OBJ_WEAKLY_REFERENCE flag should be precise");
201 zend_weakref_unref(
object, tagged_ptr);
218 void *tagged_ptr = zend_hash_index_find_ptr(&
EG(weakrefs), zend_object_to_weakref_key(referent));
295 zend_throw_error(
NULL,
"Direct instantiation of WeakReference is not allowed, use WeakReference::create instead");
329static void zend_weakmap_free_obj(
zend_object *
object)
337 zend_weakref_unregister(
390 zend_ulong obj_key = zend_object_to_weakref_key(obj_addr);
425 return i_zend_is_true(
zv);
440 if (!zend_hash_index_exists(&wm->
ht, zend_object_to_weakref_key(obj_addr))) {
451 *
count = zend_hash_num_elements(&wm->
ht);
469 zend_object *obj = zend_weakref_key_to_object(obj_key);
474 add_assoc_object(&pair,
"key", obj);
476 add_assoc_zval(&pair,
"value",
val);
490 zend_get_gc_buffer_add_zval(gc_buffer,
val);
492 zend_get_gc_buffer_use(gc_buffer, table,
n);
504 zend_get_gc_buffer_add_obj(gc_buffer,
key);
505 zend_get_gc_buffer_add_ptr(gc_buffer,
val);
507 zend_get_gc_buffer_use(gc_buffer, table,
n);
517 zend_get_gc_buffer_add_ptr(gc_buffer,
val);
519 zend_get_gc_buffer_use(gc_buffer, table,
n);
526 const zend_ulong obj_key = zend_object_to_weakref_key(
object);
527 void *tagged_ptr = zend_hash_index_find_ptr(&
EG(weakrefs), obj_key);
529 ZEND_ASSERT(tagged_ptr &&
"Tracking of the IS_OBJ_WEAKLY_REFERENCE flag should be precise");
541 zend_get_gc_buffer_add_ptr(gc_buffer,
zv);
542 zend_get_gc_buffer_add_obj(gc_buffer, &wm->
std);
549 zend_get_gc_buffer_add_ptr(gc_buffer,
zv);
550 zend_get_gc_buffer_add_obj(gc_buffer, &wm->
std);
553 zend_get_gc_buffer_use(gc_buffer, table,
n);
561 const zend_ulong obj_key = zend_object_to_weakref_key(
object);
562 void *tagged_ptr = zend_hash_index_find_ptr(&
EG(weakrefs), obj_key);
564 ZEND_ASSERT(tagged_ptr &&
"Tracking of the IS_OBJ_WEAKLY_REFERENCE flag should be precise");
576 zend_get_gc_buffer_add_ptr(gc_buffer,
zv);
583 zend_get_gc_buffer_add_ptr(gc_buffer,
zv);
586 zend_get_gc_buffer_use(gc_buffer, table,
n);
593 zend_object *new_object = zend_weakmap_create_object(zend_ce_weakmap);
601 zend_weakref_register(
610 return &
EG(ht_iterators)[iter->
ht_iter].pos;
625 return zend_hash_has_more_elements_ex(&wm->
ht,
pos);
673 zend_weakmap_iterator_dtor,
674 zend_weakmap_iterator_valid,
675 zend_weakmap_iterator_get_current_data,
676 zend_weakmap_iterator_get_current_key,
677 zend_weakmap_iterator_move_forward,
678 zend_weakmap_iterator_rewind,
690 iter->
it.
funcs = &zend_weakmap_iterator_funcs;
775 zend_weakref_handlers.free_obj = zend_weakref_free;
776 zend_weakref_handlers.get_debug_info = zend_weakref_get_debug_info;
777 zend_weakref_handlers.clone_obj =
NULL;
781 zend_ce_weakmap->create_object = zend_weakmap_create_object;
782 zend_ce_weakmap->get_iterator = zend_weakmap_get_iterator;
783 zend_ce_weakmap->default_object_handlers = &zend_weakmap_handlers;
787 zend_weakmap_handlers.free_obj = zend_weakmap_free_obj;
788 zend_weakmap_handlers.read_dimension = zend_weakmap_read_dimension;
789 zend_weakmap_handlers.write_dimension = zend_weakmap_write_dimension;
790 zend_weakmap_handlers.has_dimension = zend_weakmap_has_dimension;
791 zend_weakmap_handlers.unset_dimension = zend_weakmap_unset_dimension;
792 zend_weakmap_handlers.count_elements = zend_weakmap_count_elements;
793 zend_weakmap_handlers.get_properties_for = zend_weakmap_get_properties_for;
795 zend_weakmap_handlers.clone_obj = zend_weakmap_clone_obj;
count(Countable|array $value, int $mode=COUNT_NORMAL)
unsigned const char * pos
unsigned char key[REFLECTION_KEY_LEN]
const zend_object_iterator_funcs * funcs
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format,...)
ZEND_API ZEND_COLD void zend_type_error(const char *format,...)
ZEND_API zend_result object_init_ex(zval *arg, zend_class_entry *class_type)
ZEND_API zend_result zend_parse_parameters(uint32_t num_args, const char *type_spec,...)
#define ZEND_PARSE_PARAMETERS_END()
#define ZEND_PARSE_PARAMETERS_NONE()
#define zend_parse_parameters_none()
#define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args)
#define RETVAL_OBJ_COPY(r)
#define ZEND_METHOD(classname, name)
#define Z_PARAM_OBJ(dest)
#define FREE_HASHTABLE(ht)
#define ALLOC_HASHTABLE(ht)
ZEND_API zend_get_gc_buffer * zend_get_gc_buffer_create(void)
ZEND_API void ZEND_FASTCALL zend_hash_destroy(HashTable *ht)
ZEND_API zend_result ZEND_FASTCALL zend_hash_move_forward_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_next_index_insert_new(HashTable *ht, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API uint32_t ZEND_FASTCALL zend_hash_iterator_add(HashTable *ht, HashPosition pos)
ZEND_API int ZEND_FASTCALL zend_hash_get_current_key_ex(const HashTable *ht, zend_string **str_index, zend_ulong *num_index, const HashPosition *pos)
ZEND_API void ZEND_FASTCALL zend_hash_internal_pointer_reset_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_lookup(HashTable *ht, zend_ulong h)
ZEND_API zval *ZEND_FASTCALL zend_hash_get_current_data_ex(HashTable *ht, HashPosition *pos)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_add_new(HashTable *ht, zend_ulong h, zval *pData)
ZEND_API zend_result ZEND_FASTCALL zend_hash_index_del(HashTable *ht, zend_ulong h)
ZEND_API void ZEND_FASTCALL zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_func_t pCopyConstructor)
ZEND_API zval *ZEND_FASTCALL zend_hash_update(HashTable *ht, zend_string *key, zval *pData)
ZEND_API zval *ZEND_FASTCALL zend_hash_index_find(const HashTable *ht, zend_ulong h)
ZEND_API void ZEND_FASTCALL zend_hash_iterator_del(uint32_t idx)
#define zend_hash_init(ht, nSize, pHashFunction, pDestructor, persistent)
#define ZEND_HASH_MAP_FOREACH_VAL(ht, _val)
#define HASH_KEY_NON_EXISTENT
#define ZEND_HASH_MAP_FOREACH_PTR(ht, _ptr)
#define zend_new_array(size)
#define ZEND_HASH_MAP_FOREACH_NUM_KEY(ht, _h)
#define ZEND_HASH_FOREACH_END()
#define ZEND_HASH_MAP_FOREACH_NUM_KEY_VAL(ht, _h, _val)
ZEND_API zend_class_entry * zend_ce_countable
ZEND_API zend_class_entry * zend_ce_arrayaccess
ZEND_API zend_class_entry * zend_ce_aggregate
ZEND_API zend_result zend_create_internal_iterator_zval(zval *return_value, zval *obj)
ZEND_API void zend_iterator_init(zend_object_iterator *iter)
struct _zend_object_iterator zend_object_iterator
struct _zend_object_iterator_funcs zend_object_iterator_funcs
struct _zend_string zend_string
enum _zend_prop_purpose zend_prop_purpose
@ ZEND_PROP_PURPOSE_DEBUG
#define zend_get_std_object_handlers()
ZEND_API void ZEND_FASTCALL zend_object_std_init(zend_object *object, zend_class_entry *ce)
ZEND_API void zend_object_std_dtor(zend_object *object)
#define zend_always_inline
#define XtOffsetOf(s_type, field)
struct _zend_class_entry zend_class_entry
struct _zend_object zend_object
#define Z_TRY_ADDREF_P(pz)
struct _zend_array HashTable
#define ZVAL_MAKE_REF(zv)
#define ZVAL_OBJ_COPY(z, o)
ZEND_RESULT_CODE zend_result
#define IS_OBJ_WEAKLY_REFERENCED
struct _zend_object_handlers zend_object_handlers
#define GC_DEL_FLAGS(p, flags)
#define ZVAL_COPY_VALUE(z, v)
#define GC_ADD_FLAGS(p, flags)
ZEND_API void zval_ptr_dtor(zval *zval_ptr)
ZEND_API void zval_add_ref(zval *p)
ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key)
#define zend_weakref_fetch(z)
#define ZEND_WEAKREF_TAG_HT
#define zend_weakmap_fetch(z)
void zend_weakrefs_notify(zend_object *object)
struct _zend_weakmap_iterator zend_weakmap_iterator
HashTable * zend_weakmap_get_gc(zend_object *object, zval **table, int *n)
HashTable * zend_weakmap_get_object_entry_gc(zend_object *object, zval **table, int *n)
#define ZEND_WEAKREF_TAG_REF
ZEND_API zval * zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData)
struct _zend_weakmap zend_weakmap
void zend_weakrefs_shutdown(void)
HashTable * zend_weakmap_get_key_entry_gc(zend_object *object, zval **table, int *n)
#define ZEND_WEAKREF_ENCODE(p, t)
#define ZEND_WEAKREF_TAG_MAP
#define ZEND_WEAKREF_GET_PTR(p)
#define ZEND_WEAKREF_GET_TAG(p)
#define zend_weakref_from(o)
#define zend_weakmap_from(o)
struct _zend_weakref zend_weakref
void zend_register_weakref_ce(void)
HashTable * zend_weakmap_get_object_key_entry_gc(zend_object *object, zval **table, int *n)
HashTable * zend_weakmap_get_entry_gc(zend_object *object, zval **table, int *n)
void zend_weakrefs_init(void)
zend_class_entry * zend_ce_weakref