Skip to content

Commit 271bc68

Browse files
committed
Add iterator get_gc function for generators
Closes GH-5787.
1 parent 312201d commit 271bc68

File tree

2 files changed

+42
-1
lines changed

2 files changed

+42
-1
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
A generator iterator wrapper involved in a cycle should not leak
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public function method() {
8+
$this->gen1 = (function () {
9+
yield 1;
10+
yield 2;
11+
yield 3;
12+
})();
13+
$gen2 = function() {
14+
foreach ($this->gen1 as $x) {
15+
echo "$x\n";
16+
yield $x;
17+
}
18+
};
19+
$this->gen2 = $gen2();
20+
foreach ($this->gen2 as $x) {
21+
if ($x == 2) {
22+
break;
23+
}
24+
}
25+
}
26+
}
27+
(new Test)->method();
28+
gc_collect_cycles();
29+
30+
?>
31+
--EXPECT--
32+
1
33+
2

Zend/zend_generators.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,14 @@ static void zend_generator_iterator_rewind(zend_object_iterator *iterator) /* {{
10871087
}
10881088
/* }}} */
10891089

1090+
static HashTable *zend_generator_iterator_get_gc(
1091+
zend_object_iterator *iterator, zval **table, int *n)
1092+
{
1093+
*table = &iterator->data;
1094+
*n = 1;
1095+
return NULL;
1096+
}
1097+
10901098
static const zend_object_iterator_funcs zend_generator_iterator_functions = {
10911099
zend_generator_iterator_dtor,
10921100
zend_generator_iterator_valid,
@@ -1095,7 +1103,7 @@ static const zend_object_iterator_funcs zend_generator_iterator_functions = {
10951103
zend_generator_iterator_move_forward,
10961104
zend_generator_iterator_rewind,
10971105
NULL,
1098-
NULL, /* get_gc */
1106+
zend_generator_iterator_get_gc,
10991107
};
11001108

11011109
zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref) /* {{{ */

0 commit comments

Comments
 (0)