Skip to content

Commit d6bf375

Browse files
committed
Merge branch 'PHP-8.1'
2 parents 11927ca + 51a9c68 commit d6bf375

File tree

7 files changed

+151
-6
lines changed

7 files changed

+151
-6
lines changed

Zend/zend_weakrefs.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ static inline void zend_weakref_unref_single(
6363
wr->referent = NULL;
6464
} else {
6565
ZEND_ASSERT(tag == ZEND_WEAKREF_TAG_MAP);
66-
zend_weakmap *wm = ptr;
67-
zend_hash_index_del(&wm->ht, obj_addr);
66+
zend_hash_index_del((HashTable *) ptr, obj_addr);
6867
}
6968
}
7069

@@ -144,6 +143,23 @@ static void zend_weakref_unregister(zend_object *object, void *payload) {
144143
ZEND_WEAKREF_GET_PTR(payload), ZEND_WEAKREF_GET_TAG(payload), obj_addr);
145144
}
146145

146+
ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData) {
147+
zval *zv = zend_hash_index_add(ht, (zend_ulong) key, pData);
148+
if (zv) {
149+
zend_weakref_register(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP));
150+
}
151+
return zv;
152+
}
153+
154+
ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key) {
155+
zval *zv = zend_hash_index_find(ht, (zend_ulong) key);
156+
if (zv) {
157+
zend_weakref_unregister(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP));
158+
return SUCCESS;
159+
}
160+
return FAILURE;
161+
}
162+
147163
void zend_weakrefs_init(void) {
148164
zend_hash_init(&EG(weakrefs), 8, NULL, NULL, 0);
149165
}
@@ -276,7 +292,7 @@ static void zend_weakmap_free_obj(zend_object *object)
276292
zend_ulong obj_addr;
277293
ZEND_HASH_FOREACH_NUM_KEY(&wm->ht, obj_addr) {
278294
zend_weakref_unregister(
279-
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
295+
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
280296
} ZEND_HASH_FOREACH_END();
281297
zend_hash_destroy(&wm->ht);
282298
zend_object_std_dtor(&wm->std);
@@ -335,7 +351,7 @@ static void zend_weakmap_write_dimension(zend_object *object, zval *offset, zval
335351
return;
336352
}
337353

338-
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
354+
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
339355
zend_hash_index_add_new(&wm->ht, (zend_ulong) obj_key, value);
340356
}
341357

@@ -373,7 +389,7 @@ static void zend_weakmap_unset_dimension(zend_object *object, zval *offset)
373389
return;
374390
}
375391

376-
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
392+
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
377393
}
378394

379395
static int zend_weakmap_count_elements(zend_object *object, zend_long *count)

Zend/zend_weakrefs.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ void zend_weakrefs_shutdown(void);
2828

2929
ZEND_API void zend_weakrefs_notify(zend_object *object);
3030

31+
ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData);
32+
ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key);
33+
static zend_always_inline void *zend_weakrefs_hash_add_ptr(HashTable *ht, zend_object *key, void *ptr) {
34+
zval tmp, *zv;
35+
ZVAL_PTR(&tmp, ptr);
36+
if ((zv = zend_weakrefs_hash_add(ht, key, &tmp))) {
37+
return Z_PTR_P(zv);
38+
} else {
39+
return NULL;
40+
}
41+
}
42+
3143
END_EXTERN_C()
3244

3345
#endif

ext/zend_test/php_test.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
4848
int observer_fiber_init;
4949
int observer_fiber_switch;
5050
int observer_fiber_destroy;
51+
HashTable global_weakmap;
5152
int replace_zend_execute_ex;
5253
int register_passes;
5354
zend_test_fiber *active_fiber;

ext/zend_test/test.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "fiber.h"
2727
#include "zend_attributes.h"
2828
#include "zend_enum.h"
29+
#include "zend_weakrefs.h"
2930
#include "Zend/Optimizer/zend_optimizer.h"
3031
#include "test_arginfo.h"
3132

@@ -253,6 +254,40 @@ static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
253254
}
254255
}
255256

257+
static ZEND_FUNCTION(zend_weakmap_attach)
258+
{
259+
zval *value;
260+
zend_object *obj;
261+
262+
ZEND_PARSE_PARAMETERS_START(2, 2)
263+
Z_PARAM_OBJ(obj)
264+
Z_PARAM_ZVAL(value)
265+
ZEND_PARSE_PARAMETERS_END();
266+
267+
if (zend_weakrefs_hash_add(&ZT_G(global_weakmap), obj, value)) {
268+
Z_TRY_ADDREF_P(value);
269+
RETURN_TRUE;
270+
}
271+
RETURN_FALSE;
272+
}
273+
274+
static ZEND_FUNCTION(zend_weakmap_remove)
275+
{
276+
zend_object *obj;
277+
278+
ZEND_PARSE_PARAMETERS_START(1, 1)
279+
Z_PARAM_OBJ(obj)
280+
ZEND_PARSE_PARAMETERS_END();
281+
282+
RETURN_BOOL(zend_weakrefs_hash_del(&ZT_G(global_weakmap), obj) == SUCCESS);
283+
}
284+
285+
static ZEND_FUNCTION(zend_weakmap_dump)
286+
{
287+
ZEND_PARSE_PARAMETERS_NONE();
288+
RETURN_ARR(zend_array_dup(&ZT_G(global_weakmap)));
289+
}
290+
256291
/* TESTS Z_PARAM_ITERABLE and Z_PARAM_ITERABLE_OR_NULL */
257292
static ZEND_FUNCTION(zend_iterable)
258293
{
@@ -468,11 +503,17 @@ PHP_MSHUTDOWN_FUNCTION(zend_test)
468503

469504
PHP_RINIT_FUNCTION(zend_test)
470505
{
506+
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
471507
return SUCCESS;
472508
}
473509

474510
PHP_RSHUTDOWN_FUNCTION(zend_test)
475511
{
512+
zend_ulong objptr;
513+
ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), objptr) {
514+
zend_weakrefs_hash_del(&ZT_G(global_weakmap), (zend_object *)(uintptr_t)objptr);
515+
} ZEND_HASH_FOREACH_END();
516+
zend_hash_destroy(&ZT_G(global_weakmap));
476517
return SUCCESS;
477518
}
478519

ext/zend_test/test.stub.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ function zend_string_or_stdclass_or_null($param): stdClass|string|null {}
8787

8888
function zend_iterable(iterable $arg1, ?iterable $arg2 = null): void {}
8989

90+
function zend_weakmap_attach(object $object, mixed $value): bool {}
91+
function zend_weakmap_remove(object $object): bool {}
92+
function zend_weakmap_dump(): array {}
93+
9094
function zend_get_unit_enum(): ZendTestUnitEnum {}
9195
}
9296

ext/zend_test/test_arginfo.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: f5566ec4bffa9878e1c5eaba0c2ceeff4435c8d3 */
2+
* Stub hash: 7326163f8ce5340c12e74af72d47a8926eb39786 */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
55
ZEND_END_ARG_INFO()
@@ -57,6 +57,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable, 0, 1, IS_VOID, 0)
5757
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_ITERABLE, 1, "null")
5858
ZEND_END_ARG_INFO()
5959

60+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_attach, 0, 2, _IS_BOOL, 0)
61+
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
62+
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
63+
ZEND_END_ARG_INFO()
64+
65+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_remove, 0, 1, _IS_BOOL, 0)
66+
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
67+
ZEND_END_ARG_INFO()
68+
69+
#define arginfo_zend_weakmap_dump arginfo_zend_test_array_return
70+
6071
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0)
6172
ZEND_END_ARG_INFO()
6273

@@ -101,6 +112,9 @@ static ZEND_FUNCTION(zend_string_or_object_or_null);
101112
static ZEND_FUNCTION(zend_string_or_stdclass);
102113
static ZEND_FUNCTION(zend_string_or_stdclass_or_null);
103114
static ZEND_FUNCTION(zend_iterable);
115+
static ZEND_FUNCTION(zend_weakmap_attach);
116+
static ZEND_FUNCTION(zend_weakmap_remove);
117+
static ZEND_FUNCTION(zend_weakmap_dump);
104118
static ZEND_FUNCTION(zend_get_unit_enum);
105119
static ZEND_FUNCTION(namespaced_func);
106120
static ZEND_METHOD(_ZendTestClass, is_object);
@@ -129,6 +143,9 @@ static const zend_function_entry ext_functions[] = {
129143
ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass)
130144
ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null)
131145
ZEND_FE(zend_iterable, arginfo_zend_iterable)
146+
ZEND_FE(zend_weakmap_attach, arginfo_zend_weakmap_attach)
147+
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
148+
ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump)
132149
ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum)
133150
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
134151
ZEND_FE_END

ext/zend_test/tests/zend_weakmap.phpt

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
Test internal weakmap API
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
8+
$id1 = new \stdClass;
9+
$id2 = new \stdClass;
10+
11+
var_dump(zend_weakmap_attach($id1, 1));
12+
var_dump(zend_weakmap_attach($id1, 3));
13+
var_dump(zend_weakmap_attach($id2, 2));
14+
15+
var_dump(zend_weakmap_dump());
16+
17+
unset($id1);
18+
19+
var_dump(zend_weakmap_dump());
20+
21+
var_dump(zend_weakmap_remove($id2));
22+
var_dump(zend_weakmap_remove($id2));
23+
24+
var_dump(zend_weakmap_dump());
25+
26+
var_dump(zend_weakmap_attach($id2, $id2));
27+
28+
var_dump(zend_weakmap_dump());
29+
30+
?>
31+
--EXPECTF--
32+
bool(true)
33+
bool(false)
34+
bool(true)
35+
array(2) {
36+
[%d]=>
37+
int(1)
38+
[%d]=>
39+
int(2)
40+
}
41+
array(1) {
42+
[%d]=>
43+
int(2)
44+
}
45+
bool(true)
46+
bool(false)
47+
array(0) {
48+
}
49+
bool(true)
50+
array(1) {
51+
[%d]=>
52+
object(stdClass)#2 (0) {
53+
}
54+
}

0 commit comments

Comments
 (0)