Add iterator get_gc function for generators

Closes GH-5787.
This commit is contained in:
Nikita Popov 2020-07-01 12:03:13 +02:00
parent 312201dce4
commit 271bc689ea
2 changed files with 42 additions and 1 deletions

View file

@ -0,0 +1,33 @@
--TEST--
A generator iterator wrapper involved in a cycle should not leak
--FILE--
<?php
class Test {
public function method() {
$this->gen1 = (function () {
yield 1;
yield 2;
yield 3;
})();
$gen2 = function() {
foreach ($this->gen1 as $x) {
echo "$x\n";
yield $x;
}
};
$this->gen2 = $gen2();
foreach ($this->gen2 as $x) {
if ($x == 2) {
break;
}
}
}
}
(new Test)->method();
gc_collect_cycles();
?>
--EXPECT--
1
2

View file

@ -1087,6 +1087,14 @@ static void zend_generator_iterator_rewind(zend_object_iterator *iterator) /* {{
}
/* }}} */
static HashTable *zend_generator_iterator_get_gc(
zend_object_iterator *iterator, zval **table, int *n)
{
*table = &iterator->data;
*n = 1;
return NULL;
}
static const zend_object_iterator_funcs zend_generator_iterator_functions = {
zend_generator_iterator_dtor,
zend_generator_iterator_valid,
@ -1095,7 +1103,7 @@ static const zend_object_iterator_funcs zend_generator_iterator_functions = {
zend_generator_iterator_move_forward,
zend_generator_iterator_rewind,
NULL,
NULL, /* get_gc */
zend_generator_iterator_get_gc,
};
zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref) /* {{{ */