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.
This commit is contained in:
Nikita Popov 2019-01-15 13:52:32 +01:00
parent 48ca2c0833
commit 97fc84ca06
2 changed files with 30 additions and 1 deletions

View File

@ -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===

View 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_free(zend_object *object);
static void iter_wrapper_dtor(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 = { static const zend_object_handlers iterator_object_handlers = {
0, 0,
@ -51,7 +52,7 @@ static const zend_object_handlers iterator_object_handlers = {
NULL, /* count */ NULL, /* count */
NULL, /* get_debug_info */ NULL, /* get_debug_info */
NULL, /* get_closure */ NULL, /* get_closure */
NULL, /* get_gc */ iter_wrapper_get_gc,
NULL, /* do_operation */ NULL, /* do_operation */
NULL /* compare */ 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_API void zend_iterator_init(zend_object_iterator *iter)
{ {
zend_object_std_init(&iter->std, &zend_iterator_class_entry); zend_object_std_init(&iter->std, &zend_iterator_class_entry);