mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Allow by-ref assign to WeakMap even if object is not yet in the map (#20097)
Previously this failed as the read_dimension which is invoked by ref-assign does not contain the logic to add the key, so it was required to first write the value using a normal assignment and then thereafter use the reference assignment. This solves it by adding the necessary logic to assign references directly.
This commit is contained in:
2
NEWS
2
NEWS
@@ -5,6 +5,8 @@ PHP NEWS
|
||||
- Core:
|
||||
. Added first-class callable cache to share instances for the duration of the
|
||||
request. (ilutov)
|
||||
. It is now possible to use reference assign on WeakMap without the key
|
||||
needing to be present beforehand. (nielsdos)
|
||||
|
||||
- Intl:
|
||||
. Added IntlNumberRangeFormatter class to format an interval of two numbers
|
||||
|
||||
@@ -23,6 +23,10 @@ PHP 8.6 UPGRADE NOTES
|
||||
2. New Features
|
||||
========================================
|
||||
|
||||
- Core:
|
||||
. It is now possible to use reference assign on WeakMap without the key
|
||||
needing to be present beforehand.
|
||||
|
||||
- Intl:
|
||||
. Added IntlNumberRangeFormatter class to format an interval of two numbers with a given skeleton, locale, IntlNumberRangeFormatter::COLLAPSE_AUTO, IntlNumberRangeFormatter::COLLAPSE_NONE, IntlNumberRangeFormatter::COLLAPSE_UNIT, IntlNumberRangeFormatter::COLLAPSE_ALL collapse and
|
||||
IntlNumberRangeFormatter::IDENTITY_FALLBACK_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY_OR_SINGLE_VALUE, IntlNumberRangeFormatter::IDENTITY_FALLBACK_APPROXIMATELY and
|
||||
|
||||
13
Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt
Normal file
13
Zend/tests/weakrefs/weakmap_by_ref_dimension_assign.phpt
Normal file
@@ -0,0 +1,13 @@
|
||||
--TEST--
|
||||
By-ref assign of WeakMap dimension
|
||||
--FILE--
|
||||
<?php
|
||||
$obj = new stdClass;
|
||||
$map = new WeakMap;
|
||||
$int = 0;
|
||||
$map[$obj] =& $int;
|
||||
$int++;
|
||||
var_dump($map[$obj]);
|
||||
?>
|
||||
--EXPECT--
|
||||
int(1)
|
||||
@@ -370,18 +370,25 @@ static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int
|
||||
zend_weakmap *wm = zend_weakmap_from(object);
|
||||
zend_object *obj_addr = Z_OBJ_P(offset);
|
||||
zval *zv = zend_hash_index_find(&wm->ht, zend_object_to_weakref_key(obj_addr));
|
||||
if (zv == NULL) {
|
||||
if (type != BP_VAR_IS) {
|
||||
zend_throw_error(NULL,
|
||||
"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
|
||||
if (type == BP_VAR_W || type == BP_VAR_RW) {
|
||||
if (zv == NULL) {
|
||||
zval value;
|
||||
zend_weakref_register(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
|
||||
ZVAL_NULL(&value);
|
||||
zv = zend_hash_index_add_new(&wm->ht, zend_object_to_weakref_key(obj_addr), &value);
|
||||
}
|
||||
ZVAL_MAKE_REF(zv);
|
||||
} else {
|
||||
if (zv == NULL) {
|
||||
if (type != BP_VAR_IS) {
|
||||
zend_throw_error(NULL,
|
||||
"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (type == BP_VAR_W || type == BP_VAR_RW) {
|
||||
ZVAL_MAKE_REF(zv);
|
||||
}
|
||||
return zv;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user