Skip to content

Commit 51a9c68

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
2 parents 17aae13 + 471102e commit 51a9c68

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
}
@@ -281,7 +297,7 @@ static void zend_weakmap_free_obj(zend_object *object)
281297
zend_ulong obj_addr;
282298
ZEND_HASH_FOREACH_NUM_KEY(&wm->ht, obj_addr) {
283299
zend_weakref_unregister(
284-
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
300+
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
285301
} ZEND_HASH_FOREACH_END();
286302
zend_hash_destroy(&wm->ht);
287303
zend_object_std_dtor(&wm->std);
@@ -340,7 +356,7 @@ static void zend_weakmap_write_dimension(zend_object *object, zval *offset, zval
340356
return;
341357
}
342358

343-
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
359+
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
344360
zend_hash_index_add_new(&wm->ht, (zend_ulong) obj_key, value);
345361
}
346362

@@ -378,7 +394,7 @@ static void zend_weakmap_unset_dimension(zend_object *object, zval *offset)
378394
return;
379395
}
380396

381-
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
397+
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
382398
}
383399

384400
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

@@ -218,6 +219,40 @@ static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
218219
}
219220
}
220221

222+
static ZEND_FUNCTION(zend_weakmap_attach)
223+
{
224+
zval *value;
225+
zend_object *obj;
226+
227+
ZEND_PARSE_PARAMETERS_START(2, 2)
228+
Z_PARAM_OBJ(obj)
229+
Z_PARAM_ZVAL(value)
230+
ZEND_PARSE_PARAMETERS_END();
231+
232+
if (zend_weakrefs_hash_add(&ZT_G(global_weakmap), obj, value)) {
233+
Z_TRY_ADDREF_P(value);
234+
RETURN_TRUE;
235+
}
236+
RETURN_FALSE;
237+
}
238+
239+
static ZEND_FUNCTION(zend_weakmap_remove)
240+
{
241+
zend_object *obj;
242+
243+
ZEND_PARSE_PARAMETERS_START(1, 1)
244+
Z_PARAM_OBJ(obj)
245+
ZEND_PARSE_PARAMETERS_END();
246+
247+
RETURN_BOOL(zend_weakrefs_hash_del(&ZT_G(global_weakmap), obj) == SUCCESS);
248+
}
249+
250+
static ZEND_FUNCTION(zend_weakmap_dump)
251+
{
252+
ZEND_PARSE_PARAMETERS_NONE();
253+
RETURN_ARR(zend_array_dup(&ZT_G(global_weakmap)));
254+
}
255+
221256
/* TESTS Z_PARAM_ITERABLE and Z_PARAM_ITERABLE_OR_NULL */
222257
static ZEND_FUNCTION(zend_iterable)
223258
{
@@ -433,11 +468,17 @@ PHP_MSHUTDOWN_FUNCTION(zend_test)
433468

434469
PHP_RINIT_FUNCTION(zend_test)
435470
{
471+
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
436472
return SUCCESS;
437473
}
438474

439475
PHP_RSHUTDOWN_FUNCTION(zend_test)
440476
{
477+
zend_ulong objptr;
478+
ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), objptr) {
479+
zend_weakrefs_hash_del(&ZT_G(global_weakmap), (zend_object *)(uintptr_t)objptr);
480+
} ZEND_HASH_FOREACH_END();
481+
zend_hash_destroy(&ZT_G(global_weakmap));
441482
return SUCCESS;
442483
}
443484

ext/zend_test/test.stub.php

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

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

88+
function zend_weakmap_attach(object $object, mixed $value): bool {}
89+
function zend_weakmap_remove(object $object): bool {}
90+
function zend_weakmap_dump(): array {}
91+
8892
function zend_get_unit_enum(): ZendTestUnitEnum {}
8993
}
9094

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: 53832c784e59195e8ef41710c1e4e778f396c99b */
2+
* Stub hash: ccdf8346a4df871bf8ed0acb4fe11d2b3c933bd7 */
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()
@@ -51,6 +51,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable, 0, 1, IS_VOID, 0)
5151
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_ITERABLE, 1, "null")
5252
ZEND_END_ARG_INFO()
5353

54+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_attach, 0, 2, _IS_BOOL, 0)
55+
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
56+
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
57+
ZEND_END_ARG_INFO()
58+
59+
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_remove, 0, 1, _IS_BOOL, 0)
60+
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
61+
ZEND_END_ARG_INFO()
62+
63+
#define arginfo_zend_weakmap_dump arginfo_zend_test_array_return
64+
5465
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0)
5566
ZEND_END_ARG_INFO()
5667

@@ -94,6 +105,9 @@ static ZEND_FUNCTION(zend_string_or_object_or_null);
94105
static ZEND_FUNCTION(zend_string_or_stdclass);
95106
static ZEND_FUNCTION(zend_string_or_stdclass_or_null);
96107
static ZEND_FUNCTION(zend_iterable);
108+
static ZEND_FUNCTION(zend_weakmap_attach);
109+
static ZEND_FUNCTION(zend_weakmap_remove);
110+
static ZEND_FUNCTION(zend_weakmap_dump);
97111
static ZEND_FUNCTION(zend_get_unit_enum);
98112
static ZEND_FUNCTION(namespaced_func);
99113
static ZEND_METHOD(_ZendTestClass, is_object);
@@ -121,6 +135,9 @@ static const zend_function_entry ext_functions[] = {
121135
ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass)
122136
ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null)
123137
ZEND_FE(zend_iterable, arginfo_zend_iterable)
138+
ZEND_FE(zend_weakmap_attach, arginfo_zend_weakmap_attach)
139+
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
140+
ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump)
124141
ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum)
125142
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
126143
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)