Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ PHP NEWS
. Added PHP_BUILD_PROVIDER constant. (timwolla)
. Fixed bug GH-19305 (Operands may be being released during comparison).
(Arnaud)
. Fixed bug GH-19306 (Generator can be resumed while fetching next value from
delegated Generator). (Arnaud)

- Curl:
. Add support for CURLINFO_CONN_ID in curl_getinfo() (thecaliskan)
Expand Down
40 changes: 40 additions & 0 deletions Zend/tests/gh19306.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
GH-19306: Generator suspended in yield from may be resumed
--FILE--
<?php

class It implements IteratorAggregate
{
public function getIterator(): Generator
{
yield "";
Fiber::suspend();
}
}
function g()
{
yield from new It();
}
$a = g();
$fiber = new Fiber(function () use ($a) {
echo "Fiber start\n";
$a->next();
echo "Fiber return\n";
});
$fiber->start();
echo "Fiber suspended\n";
try {
$a->next();
} catch (Throwable $t) {
echo $t->getMessage(), "\n";
}
echo "Destroying fiber\n";
$fiber = null;
echo "Shutdown\n";
?>
--EXPECT--
Fiber start
Fiber suspended
Cannot resume an already running generator
Destroying fiber
Shutdown
5 changes: 3 additions & 2 deletions Zend/zend_generators.c
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,8 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
orig_generator->execute_fake.prev_execute_data = original_execute_data;
}

generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;

/* Ensure this is run after executor_data swap to have a proper stack trace */
if (UNEXPECTED(!Z_ISUNDEF(generator->values))) {
if (EXPECTED(zend_generator_get_next_delegated_value(generator) == SUCCESS)) {
Expand All @@ -794,7 +796,7 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
EG(jit_trace_num) = original_jit_trace_num;

orig_generator->flags &= ~(ZEND_GENERATOR_DO_INIT | ZEND_GENERATOR_IN_FIBER);
generator->flags &= ~ZEND_GENERATOR_IN_FIBER;
generator->flags &= ~(ZEND_GENERATOR_CURRENTLY_RUNNING | ZEND_GENERATOR_IN_FIBER);
return;
}
/* If there are no more delegated values, resume the generator
Expand All @@ -817,7 +819,6 @@ ZEND_API void zend_generator_resume(zend_generator *orig_generator) /* {{{ */
* account for the following increment */
|| (generator->flags & ZEND_GENERATOR_FORCED_CLOSE));
generator->execute_data->opline++;
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
if (!ZEND_OBSERVER_ENABLED) {
zend_execute_ex(generator->execute_data);
} else {
Expand Down
1 change: 1 addition & 0 deletions ext/opcache/tests/zzz_basic_logging.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ opcache.log_verbosity_level=4
opcache.huge_code_pages=0
opcache.preload=
opcache.interned_strings_buffer=8
opcache.blacklist_filename=
--EXTENSIONS--
opcache
--SKIPIF--
Expand Down