Skip to content

Implement WeakMap #4882

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 173 additions & 0 deletions Zend/tests/weakrefs/weakmap_basic_map_behavior.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
--TEST--
Basic WeakMap behavior (as a map)
--FILE--
<?php

$map = new WeakMap;
var_dump(count($map));

$obj = new stdClass;
$obj->value = 1;
$obj2 = new stdClass;
$obj2->value = 2;

$map[$obj] = $obj2;
var_dump(count($map));
var_dump($map);
var_dump(isset($map[$obj]));
var_dump(!empty($map[$obj]));
var_dump($map[$obj]);

$map[$obj] = 42;
var_dump($map);
var_dump(isset($map[$obj]));
var_dump(!empty($map[$obj]));
var_dump($map[$obj]);

$map[$obj] = false;
var_dump($map);
var_dump(isset($map[$obj]));
var_dump(!empty($map[$obj]));
var_dump($map[$obj]);

$map[$obj] = null;
var_dump($map);
var_dump(isset($map[$obj]));
var_dump(!empty($map[$obj]));
var_dump($map[$obj]);

unset($map[$obj]);
var_dump($map);
var_dump(isset($map[$obj]));
var_dump(!empty($map[$obj]));
try {
var_dump($map[$obj]);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

echo "\nIndirect modification:\n";
$map[$obj] = [];
$map[$obj][] = 42;
$map[$obj2] = 41;
$map[$obj2]++;
var_dump($map);

echo "\nMethods:\n";
var_dump($map->offsetSet($obj2, 43));
var_dump($map->offsetGet($obj2));
var_dump($map->offsetExists($obj2));
var_dump($map->count());
var_dump($map->offsetUnset($obj2));
var_dump($map->count());

?>
--EXPECT--
int(0)
int(1)
object(WeakMap)#1 (1) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (1) {
["value"]=>
int(1)
}
["value"]=>
object(stdClass)#3 (1) {
["value"]=>
int(2)
}
}
}
bool(true)
bool(true)
object(stdClass)#3 (1) {
["value"]=>
int(2)
}
object(WeakMap)#1 (1) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (1) {
["value"]=>
int(1)
}
["value"]=>
int(42)
}
}
bool(true)
bool(true)
int(42)
object(WeakMap)#1 (1) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (1) {
["value"]=>
int(1)
}
["value"]=>
bool(false)
}
}
bool(true)
bool(false)
bool(false)
object(WeakMap)#1 (1) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (1) {
["value"]=>
int(1)
}
["value"]=>
NULL
}
}
bool(false)
bool(false)
NULL
object(WeakMap)#1 (0) {
}
bool(false)
bool(false)
Object stdClass#2 not contained in WeakMap

Indirect modification:
object(WeakMap)#1 (2) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (1) {
["value"]=>
int(1)
}
["value"]=>
array(1) {
[0]=>
int(42)
}
}
[1]=>
array(2) {
["key"]=>
object(stdClass)#3 (1) {
["value"]=>
int(2)
}
["value"]=>
int(42)
}
}

Methods:
NULL
int(43)
bool(true)
int(2)
NULL
int(1)
96 changes: 96 additions & 0 deletions Zend/tests/weakrefs/weakmap_error_conditions.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
--TEST--
WeakMap error conditions
--FILE--
<?php

$map = new WeakMap;
try {
$map[1] = 2;
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump($map[1]);
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
isset($map[1]);
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}
try {
unset($map[1]);
} catch (TypeError $e) {
echo $e->getMessage(), "\n";
}

try {
$map[] = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
$map[][1] = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump($map[new stdClass]);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

try {
$map->prop = 1;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
var_dump($map->prop);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
$r =& $map->prop;
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
isset($map->prop);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
try {
unset($map->prop);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}

try {
serialize($map);
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}
try {
unserialize('C:7:"WeakMap":0:{}');
} catch (Exception $e) {
echo $e->getMessage(), "\n";
}

?>
--EXPECT--
WeakMap key must be an object
WeakMap key must be an object
WeakMap key must be an object
WeakMap key must be an object
Cannot append to WeakMap
Cannot append to WeakMap
Object stdClass#2 not contained in WeakMap
WeakMap objects do not support properties
WeakMap objects do not support properties
WeakMap objects do not support property references
WeakMap objects do not support properties
WeakMap objects do not support properties
Serialization of 'WeakMap' is not allowed
Unserialization of 'WeakMap' is not allowed
80 changes: 80 additions & 0 deletions Zend/tests/weakrefs/weakmap_iteration.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
--TEST--
WeakMap iteration
--FILE--
<?php

$map = new WeakMap;

echo "\nEmpty loop:\n";
foreach ($map as $key => $value) {
var_dump($key, $value);
}

echo "\nSimple loop:\n";
$obj0 = new stdClass;
$obj1 = new stdClass;
$obj2 = new stdClass;
$map[$obj0] = 0;
$map[$obj1] = 1;
$map[$obj2] = 2;
foreach ($map as $key => $value) {
var_dump($key, $value);
}

echo "\nObject removed during loop:\n";
foreach ($map as $key => $value) {
if (isset($obj1) && $key === $obj1) unset($obj1);
var_dump($key, $value);
}

echo "\nBy reference iteration:\n";
foreach ($map as $key => &$value) {
$value++;
}
var_dump($map);

?>
--EXPECT--
Empty loop:

Simple loop:
object(stdClass)#2 (0) {
}
int(0)
object(stdClass)#3 (0) {
}
int(1)
object(stdClass)#4 (0) {
}
int(2)

Object removed during loop:
object(stdClass)#2 (0) {
}
int(0)
object(stdClass)#3 (0) {
}
int(1)
object(stdClass)#4 (0) {
}
int(2)

By reference iteration:
object(WeakMap)#1 (2) {
[0]=>
array(2) {
["key"]=>
object(stdClass)#2 (0) {
}
["value"]=>
&int(1)
}
[1]=>
array(2) {
["key"]=>
object(stdClass)#4 (0) {
}
["value"]=>
&int(3)
}
}
Loading