summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-01-13 11:06:46 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-01-13 11:06:46 +0100
commitcf70e1910b5079b4698ee2aeffe8201e429ea26a (patch)
treec080ba3f73334395d342e3fd211c45babfbd0ebd
parentd00f52b6a9a021979925da907230a4290224ab69 (diff)
parent8c07170ddbe28d8cc31e71f0ceb94fc4ac329657 (diff)
downloadphp-git-cf70e1910b5079b4698ee2aeffe8201e429ea26a.tar.gz
Merge branch 'PHP-7.1' into PHP-7.2
-rw-r--r--Zend/tests/generators/gc_with_root_parent_mismatch.phpt27
-rw-r--r--Zend/zend_generators.c14
2 files changed, 34 insertions, 7 deletions
diff --git a/Zend/tests/generators/gc_with_root_parent_mismatch.phpt b/Zend/tests/generators/gc_with_root_parent_mismatch.phpt
new file mode 100644
index 0000000000..ee388b1c76
--- /dev/null
+++ b/Zend/tests/generators/gc_with_root_parent_mismatch.phpt
@@ -0,0 +1,27 @@
+--TEST--
+Generator GC when the yield from parent chain does not reach the root
+--FILE--
+<?php
+
+function root() {
+ yield 1;
+ yield 2;
+}
+
+function delegate($gen) {
+ yield from $gen;
+}
+
+$gen = delegate(delegate(root()));
+$gen1 = delegate(delegate($gen));
+$gen2 = delegate(delegate($gen));
+var_dump($gen1->current());
+var_dump($gen2->current());
+$gen1->next();
+$gen1->next();
+gc_collect_cycles();
+
+?>
+--EXPECT--
+int(1)
+int(1)
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 54675f7b43..3eb022b78b 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -276,9 +276,9 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */
/* Yield from root references */
if (generator->node.children == 0) {
- zend_generator *child = generator, *root = generator->node.ptr.root;
- while (root != child) {
- child = child->node.parent;
+ zend_generator *root = generator->node.ptr.root;
+ while (root != generator) {
+ root = zend_generator_get_child(&root->node, generator);
size++;
}
}
@@ -341,10 +341,10 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
}
if (generator->node.children == 0) {
- zend_generator *child = generator, *root = generator->node.ptr.root;
- while (root != child) {
- child = child->node.parent;
- ZVAL_OBJ(gc_buffer++, &child->std);
+ zend_generator *root = generator->node.ptr.root;
+ while (root != generator) {
+ ZVAL_OBJ(gc_buffer++, &root->std);
+ root = zend_generator_get_child(&root->node, generator);
}
}