summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2019-01-15 13:52:32 +0100
committerNikita Popov <nikita.ppv@gmail.com>2019-01-15 13:52:32 +0100
commit97fc84ca06188ded308cc5a92cf487f0a562fb75 (patch)
treeaabde75646bf7daf3e5b4510c3daa11945841ba7
parent48ca2c08339eeec3eb13b317deb17c6a80e0af82 (diff)
downloadphp-git-97fc84ca06188ded308cc5a92cf487f0a562fb75.tar.gz
Add dummy get_gc handler for iterator wrapper
get_gc is assumed to be non-NULL in master, and get_gc can be called on the iterator wrapper if during generator GC, so we need to define this handler. For now it's just a dummy, though for full support we'd have to also add a get_gc iterator handler that is called here.
-rw-r--r--Zend/tests/generators/gc_with_iterator_in_foreach.phpt21
-rw-r--r--Zend/zend_iterators.c10
2 files changed, 30 insertions, 1 deletions
diff --git a/Zend/tests/generators/gc_with_iterator_in_foreach.phpt b/Zend/tests/generators/gc_with_iterator_in_foreach.phpt
new file mode 100644
index 0000000000..ed13c2be96
--- /dev/null
+++ b/Zend/tests/generators/gc_with_iterator_in_foreach.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Generator GC triggered with live iterator in foreach
+--FILE--
+<?php
+
+function gen($iter, &$gen) {
+ foreach ($iter as $v) {
+ yield;
+ }
+}
+
+$iter = new ArrayIterator([1, 2, 3]);
+$gen = gen($iter, $gen);
+$gen->next();
+unset($gen);
+gc_collect_cycles();
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c
index 81606ef6eb..d1f74888b7 100644
--- a/Zend/zend_iterators.c
+++ b/Zend/zend_iterators.c
@@ -24,6 +24,7 @@ static zend_class_entry zend_iterator_class_entry;
static void iter_wrapper_free(zend_object *object);
static void iter_wrapper_dtor(zend_object *object);
+static HashTable *iter_wrapper_get_gc(zval *object, zval **table, int *n);
static const zend_object_handlers iterator_object_handlers = {
0,
@@ -51,7 +52,7 @@ static const zend_object_handlers iterator_object_handlers = {
NULL, /* count */
NULL, /* get_debug_info */
NULL, /* get_closure */
- NULL, /* get_gc */
+ iter_wrapper_get_gc,
NULL, /* do_operation */
NULL /* compare */
};
@@ -71,6 +72,13 @@ static void iter_wrapper_dtor(zend_object *object)
{
}
+static HashTable *iter_wrapper_get_gc(zval *object, zval **table, int *n) {
+ /* TODO: We need a get_gc iterator handler */
+ *table = NULL;
+ *n = 0;
+ return NULL;
+}
+
ZEND_API void zend_iterator_init(zend_object_iterator *iter)
{
zend_object_std_init(&iter->std, &zend_iterator_class_entry);