Merge branch 'PHP-8.0' into PHP-8.1

This commit is contained in:
Bob Weinand 2021-10-21 13:42:20 +02:00
commit 51a9c68ee5
7 changed files with 151 additions and 6 deletions

View file

@ -63,8 +63,7 @@ static inline void zend_weakref_unref_single(
wr->referent = NULL;
} else {
ZEND_ASSERT(tag == ZEND_WEAKREF_TAG_MAP);
zend_weakmap *wm = ptr;
zend_hash_index_del(&wm->ht, obj_addr);
zend_hash_index_del((HashTable *) ptr, obj_addr);
}
}
@ -144,6 +143,23 @@ static void zend_weakref_unregister(zend_object *object, void *payload) {
ZEND_WEAKREF_GET_PTR(payload), ZEND_WEAKREF_GET_TAG(payload), obj_addr);
}
ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData) {
zval *zv = zend_hash_index_add(ht, (zend_ulong) key, pData);
if (zv) {
zend_weakref_register(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP));
}
return zv;
}
ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key) {
zval *zv = zend_hash_index_find(ht, (zend_ulong) key);
if (zv) {
zend_weakref_unregister(key, ZEND_WEAKREF_ENCODE(ht, ZEND_WEAKREF_TAG_MAP));
return SUCCESS;
}
return FAILURE;
}
void zend_weakrefs_init(void) {
zend_hash_init(&EG(weakrefs), 8, NULL, NULL, 0);
}
@ -281,7 +297,7 @@ static void zend_weakmap_free_obj(zend_object *object)
zend_ulong obj_addr;
ZEND_HASH_FOREACH_NUM_KEY(&wm->ht, obj_addr) {
zend_weakref_unregister(
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
(zend_object *) obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
} ZEND_HASH_FOREACH_END();
zend_hash_destroy(&wm->ht);
zend_object_std_dtor(&wm->std);
@ -340,7 +356,7 @@ static void zend_weakmap_write_dimension(zend_object *object, zval *offset, zval
return;
}
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
zend_weakref_register(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
zend_hash_index_add_new(&wm->ht, (zend_ulong) obj_key, value);
}
@ -378,7 +394,7 @@ static void zend_weakmap_unset_dimension(zend_object *object, zval *offset)
return;
}
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(wm, ZEND_WEAKREF_TAG_MAP));
zend_weakref_unregister(obj_key, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
}
static int zend_weakmap_count_elements(zend_object *object, zend_long *count)

View file

@ -28,6 +28,18 @@ void zend_weakrefs_shutdown(void);
ZEND_API void zend_weakrefs_notify(zend_object *object);
ZEND_API zval *zend_weakrefs_hash_add(HashTable *ht, zend_object *key, zval *pData);
ZEND_API zend_result zend_weakrefs_hash_del(HashTable *ht, zend_object *key);
static zend_always_inline void *zend_weakrefs_hash_add_ptr(HashTable *ht, zend_object *key, void *ptr) {
zval tmp, *zv;
ZVAL_PTR(&tmp, ptr);
if ((zv = zend_weakrefs_hash_add(ht, key, &tmp))) {
return Z_PTR_P(zv);
} else {
return NULL;
}
}
END_EXTERN_C()
#endif

View file

@ -48,6 +48,7 @@ ZEND_BEGIN_MODULE_GLOBALS(zend_test)
int observer_fiber_init;
int observer_fiber_switch;
int observer_fiber_destroy;
HashTable global_weakmap;
int replace_zend_execute_ex;
int register_passes;
zend_test_fiber *active_fiber;

View file

@ -26,6 +26,7 @@
#include "fiber.h"
#include "zend_attributes.h"
#include "zend_enum.h"
#include "zend_weakrefs.h"
#include "Zend/Optimizer/zend_optimizer.h"
#include "test_arginfo.h"
@ -218,6 +219,40 @@ static ZEND_FUNCTION(zend_string_or_stdclass_or_null)
}
}
static ZEND_FUNCTION(zend_weakmap_attach)
{
zval *value;
zend_object *obj;
ZEND_PARSE_PARAMETERS_START(2, 2)
Z_PARAM_OBJ(obj)
Z_PARAM_ZVAL(value)
ZEND_PARSE_PARAMETERS_END();
if (zend_weakrefs_hash_add(&ZT_G(global_weakmap), obj, value)) {
Z_TRY_ADDREF_P(value);
RETURN_TRUE;
}
RETURN_FALSE;
}
static ZEND_FUNCTION(zend_weakmap_remove)
{
zend_object *obj;
ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_OBJ(obj)
ZEND_PARSE_PARAMETERS_END();
RETURN_BOOL(zend_weakrefs_hash_del(&ZT_G(global_weakmap), obj) == SUCCESS);
}
static ZEND_FUNCTION(zend_weakmap_dump)
{
ZEND_PARSE_PARAMETERS_NONE();
RETURN_ARR(zend_array_dup(&ZT_G(global_weakmap)));
}
/* TESTS Z_PARAM_ITERABLE and Z_PARAM_ITERABLE_OR_NULL */
static ZEND_FUNCTION(zend_iterable)
{
@ -433,11 +468,17 @@ PHP_MSHUTDOWN_FUNCTION(zend_test)
PHP_RINIT_FUNCTION(zend_test)
{
zend_hash_init(&ZT_G(global_weakmap), 8, NULL, ZVAL_PTR_DTOR, 0);
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(zend_test)
{
zend_ulong objptr;
ZEND_HASH_FOREACH_NUM_KEY(&ZT_G(global_weakmap), objptr) {
zend_weakrefs_hash_del(&ZT_G(global_weakmap), (zend_object *)(uintptr_t)objptr);
} ZEND_HASH_FOREACH_END();
zend_hash_destroy(&ZT_G(global_weakmap));
return SUCCESS;
}

View file

@ -85,6 +85,10 @@ namespace {
function zend_iterable(iterable $arg1, ?iterable $arg2 = null): void {}
function zend_weakmap_attach(object $object, mixed $value): bool {}
function zend_weakmap_remove(object $object): bool {}
function zend_weakmap_dump(): array {}
function zend_get_unit_enum(): ZendTestUnitEnum {}
}

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: 53832c784e59195e8ef41710c1e4e778f396c99b */
* Stub hash: ccdf8346a4df871bf8ed0acb4fe11d2b3c933bd7 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_test_array_return, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
@ -51,6 +51,17 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_iterable, 0, 1, IS_VOID, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, arg2, IS_ITERABLE, 1, "null")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_attach, 0, 2, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_zend_weakmap_remove, 0, 1, _IS_BOOL, 0)
ZEND_ARG_TYPE_INFO(0, object, IS_OBJECT, 0)
ZEND_END_ARG_INFO()
#define arginfo_zend_weakmap_dump arginfo_zend_test_array_return
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_zend_get_unit_enum, 0, 0, ZendTestUnitEnum, 0)
ZEND_END_ARG_INFO()
@ -94,6 +105,9 @@ static ZEND_FUNCTION(zend_string_or_object_or_null);
static ZEND_FUNCTION(zend_string_or_stdclass);
static ZEND_FUNCTION(zend_string_or_stdclass_or_null);
static ZEND_FUNCTION(zend_iterable);
static ZEND_FUNCTION(zend_weakmap_attach);
static ZEND_FUNCTION(zend_weakmap_remove);
static ZEND_FUNCTION(zend_weakmap_dump);
static ZEND_FUNCTION(zend_get_unit_enum);
static ZEND_FUNCTION(namespaced_func);
static ZEND_METHOD(_ZendTestClass, is_object);
@ -121,6 +135,9 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(zend_string_or_stdclass, arginfo_zend_string_or_stdclass)
ZEND_FE(zend_string_or_stdclass_or_null, arginfo_zend_string_or_stdclass_or_null)
ZEND_FE(zend_iterable, arginfo_zend_iterable)
ZEND_FE(zend_weakmap_attach, arginfo_zend_weakmap_attach)
ZEND_FE(zend_weakmap_remove, arginfo_zend_weakmap_remove)
ZEND_FE(zend_weakmap_dump, arginfo_zend_weakmap_dump)
ZEND_FE(zend_get_unit_enum, arginfo_zend_get_unit_enum)
ZEND_NS_FE("ZendTestNS2\\ZendSubNS", namespaced_func, arginfo_ZendTestNS2_ZendSubNS_namespaced_func)
ZEND_FE_END

View file

@ -0,0 +1,54 @@
--TEST--
Test internal weakmap API
--EXTENSIONS--
zend_test
--FILE--
<?php
$id1 = new \stdClass;
$id2 = new \stdClass;
var_dump(zend_weakmap_attach($id1, 1));
var_dump(zend_weakmap_attach($id1, 3));
var_dump(zend_weakmap_attach($id2, 2));
var_dump(zend_weakmap_dump());
unset($id1);
var_dump(zend_weakmap_dump());
var_dump(zend_weakmap_remove($id2));
var_dump(zend_weakmap_remove($id2));
var_dump(zend_weakmap_dump());
var_dump(zend_weakmap_attach($id2, $id2));
var_dump(zend_weakmap_dump());
?>
--EXPECTF--
bool(true)
bool(false)
bool(true)
array(2) {
[%d]=>
int(1)
[%d]=>
int(2)
}
array(1) {
[%d]=>
int(2)
}
bool(true)
bool(false)
array(0) {
}
bool(true)
array(1) {
[%d]=>
object(stdClass)#2 (0) {
}
}