]> granicus.if.org Git - php/commitdiff
Add dummy get_gc handler for iterator wrapper
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 15 Jan 2019 12:52:32 +0000 (13:52 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 15 Jan 2019 12:52:32 +0000 (13:52 +0100)
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.

Zend/tests/generators/gc_with_iterator_in_foreach.phpt [new file with mode: 0644]
Zend/zend_iterators.c

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 (file)
index 0000000..ed13c2b
--- /dev/null
@@ -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===
index 81606ef6eb52429acb91988cbeaef485357ea346..d1f74888b70d41913a401e2abc669ce9cfdb5ee0 100644 (file)
@@ -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);