From: Bob Weinand Date: Mon, 18 Apr 2016 21:54:41 +0000 (+0200) Subject: Fix generator being a cycle to itself X-Git-Tag: php-7.1.0alpha1~298 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5085352464e55e92cd5bb7beeb2284b2e1b78061;p=php Fix generator being a cycle to itself --- diff --git a/Zend/tests/generators/gc_with_yield_from.phpt b/Zend/tests/generators/gc_with_yield_from.phpt new file mode 100644 index 0000000000..8c05561990 --- /dev/null +++ b/Zend/tests/generators/gc_with_yield_from.phpt @@ -0,0 +1,45 @@ +--TEST-- +Verify yield from on generators being properly cycle collected +--FILE-- +current()); +unset($gen, $gens); +print "collect\n"; +gc_collect_cycles(); +print "end\n"; + +?> +--EXPECT-- +int(1) +collect +array(4) { + [0]=> + object(Generator)#1 (0) { + } + [1]=> + object(Generator)#2 (0) { + } + [2]=> + object(Generator)#3 (0) { + } + [3]=> + object(Generator)#4 (0) { + } +} +end diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c index e2cc2382bd..33f187c96f 100644 --- a/Zend/zend_generators.c +++ b/Zend/zend_generators.c @@ -220,10 +220,10 @@ static uint32_t calc_gc_buffer_size(zend_generator *generator) /* {{{ */ /* Yield from root references */ if (generator->node.children == 0) { - zend_generator *root = generator->node.ptr.root; - while (root != generator) { + zend_generator *child = generator, *root = generator->node.ptr.root; + while (root != child) { + child = child->node.parent; size++; - root = zend_generator_get_child(&root->node, generator); } } } @@ -287,8 +287,8 @@ 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) { - ZVAL_OBJ(gc_buffer++, &child->std); child = child->node.parent; + ZVAL_OBJ(gc_buffer++, &child->std); } }