diff options
| author | Bob Weinand <bobwei9@hotmail.com> | 2016-04-18 23:54:41 +0200 |
|---|---|---|
| committer | Bob Weinand <bobwei9@hotmail.com> | 2016-04-18 23:55:16 +0200 |
| commit | 5085352464e55e92cd5bb7beeb2284b2e1b78061 (patch) | |
| tree | 821398aefb88e2ca15723db032c9f985f1dde7d5 | |
| parent | ea1f30057b50b24c83750b8d5410108b7ba65180 (diff) | |
| download | php-git-5085352464e55e92cd5bb7beeb2284b2e1b78061.tar.gz | |
Fix generator being a cycle to itself
| -rw-r--r-- | Zend/tests/generators/gc_with_yield_from.phpt | 45 | ||||
| -rw-r--r-- | Zend/zend_generators.c | 8 |
2 files changed, 49 insertions, 4 deletions
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-- +<?php + +function root() { + global $gens; // create cyclic reference to root + try { + yield 1; + } finally { + var_dump($gens); + } +} + +function gen($x) { + global $gens; + yield from $gens[] = $x ? gen(--$x) : root(); +} + +$gen = $gens[] = gen(2); +var_dump($gen->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); } } |
