Skip to content

Commit 3b4492b

Browse files
committed
Allow by-ref assign to WeakMap even if object is not yet in the map
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.
1 parent 5e50f8d commit 3b4492b

File tree

2 files changed

+28
-8
lines changed

2 files changed

+28
-8
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--TEST--
2+
By-ref assign of WeakMap dimension
3+
--FILE--
4+
<?php
5+
$obj = new stdClass;
6+
$map = new WeakMap;
7+
$int = 0;
8+
$map[$obj] =& $int;
9+
$int++;
10+
var_dump($map[$obj]);
11+
?>
12+
--EXPECT--
13+
int(1)

Zend/zend_weakrefs.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -370,18 +370,25 @@ static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int
370370
zend_weakmap *wm = zend_weakmap_from(object);
371371
zend_object *obj_addr = Z_OBJ_P(offset);
372372
zval *zv = zend_hash_index_find(&wm->ht, zend_object_to_weakref_key(obj_addr));
373-
if (zv == NULL) {
374-
if (type != BP_VAR_IS) {
375-
zend_throw_error(NULL,
376-
"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
373+
if (type == BP_VAR_W || type == BP_VAR_RW) {
374+
if (zv == NULL) {
375+
zval value;
376+
zend_weakref_register(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));
377+
ZVAL_NULL(&value);
378+
zv = zend_hash_index_add_new(&wm->ht, zend_object_to_weakref_key(obj_addr), &value);
379+
}
380+
ZVAL_MAKE_REF(zv);
381+
} else {
382+
if (zv == NULL) {
383+
if (type != BP_VAR_IS) {
384+
zend_throw_error(NULL,
385+
"Object %s#%d not contained in WeakMap", ZSTR_VAL(obj_addr->ce->name), obj_addr->handle);
386+
return NULL;
387+
}
377388
return NULL;
378389
}
379-
return NULL;
380390
}
381391

382-
if (type == BP_VAR_W || type == BP_VAR_RW) {
383-
ZVAL_MAKE_REF(zv);
384-
}
385392
return zv;
386393
}
387394

0 commit comments

Comments
 (0)