mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix several issues and allow rewind only at/before first yield
* Trying to resume a generator while it is already running now throws a fatal error. * Trying to use yield in finally while the generator is being force-closed (by GC) throws a fatal error. * Rewinding after the first yield now throws an Exception
This commit is contained in:
parent
4d8edda341
commit
f53225a99e
8 changed files with 269 additions and 13 deletions
|
@ -0,0 +1,17 @@
|
|||
--TEST--
|
||||
It is not possible to resume an already running generator
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
$gen = yield;
|
||||
$gen->next();
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
$gen->send($gen);
|
||||
$gen->next();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Cannot resume an already running generator in %s on line %d
|
|
@ -0,0 +1,29 @@
|
|||
--TEST--
|
||||
yield cannot be used in a finally block when the generator is force-closed
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
try {
|
||||
echo "before yield\n";
|
||||
yield;
|
||||
echo "after yield\n";
|
||||
} finally {
|
||||
echo "before yield in finally\n";
|
||||
yield;
|
||||
echo "after yield in finally\n";
|
||||
}
|
||||
|
||||
echo "after finally\n";
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
$gen->rewind();
|
||||
unset($gen);
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
before yield
|
||||
before yield in finally
|
||||
|
||||
Fatal error: Cannot yield from finally in a force-closed generator in %s on line %d
|
43
Zend/tests/generators/generator_rewind.phpt
Normal file
43
Zend/tests/generators/generator_rewind.phpt
Normal file
|
@ -0,0 +1,43 @@
|
|||
--TEST--
|
||||
A generator can only be rewinded before or at the first yield
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
echo "before yield\n";
|
||||
yield;
|
||||
echo "after yield\n";
|
||||
yield;
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
$gen->rewind();
|
||||
$gen->rewind();
|
||||
$gen->next();
|
||||
|
||||
try {
|
||||
$gen->rewind();
|
||||
} catch (Exception $e) {
|
||||
echo "\n", $e, "\n\n";
|
||||
}
|
||||
|
||||
function gen2() {
|
||||
echo "in generator\n";
|
||||
|
||||
if (false) yield;
|
||||
}
|
||||
|
||||
$gen = gen2();
|
||||
$gen->rewind();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
before yield
|
||||
after yield
|
||||
|
||||
exception 'Exception' with message 'Cannot rewind a generator that was already run' in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): Generator->rewind()
|
||||
#1 {main}
|
||||
|
||||
in generator
|
29
Zend/tests/generators/yield_in_finally.phpt
Normal file
29
Zend/tests/generators/yield_in_finally.phpt
Normal file
|
@ -0,0 +1,29 @@
|
|||
--TEST--
|
||||
yield can be used in finally (apart from forced closes)
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
function gen() {
|
||||
try {
|
||||
echo "before return\n";
|
||||
return;
|
||||
echo "after return\n";
|
||||
} finally {
|
||||
echo "before yield\n";
|
||||
yield "yielded value";
|
||||
echo "after yield\n";
|
||||
}
|
||||
|
||||
echo "after finally\n";
|
||||
}
|
||||
|
||||
$gen = gen();
|
||||
var_dump($gen->current());
|
||||
$gen->next();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
before return
|
||||
before yield
|
||||
string(%d) "yielded value"
|
||||
after yield
|
|
@ -31,11 +31,13 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio
|
|||
{
|
||||
if (generator->execute_data) {
|
||||
zend_execute_data *execute_data = generator->execute_data;
|
||||
zend_op_array *op_array = execute_data->op_array;
|
||||
|
||||
if (!finished_execution) {
|
||||
zend_op_array *op_array = execute_data->op_array;
|
||||
if (op_array->has_finally_block) {
|
||||
zend_uint op_num = execute_data->opline - op_array->opcodes;
|
||||
/* -1 required because we want the last run opcode, not the
|
||||
* next to-be-run one. */
|
||||
zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
|
||||
zend_uint finally_op_num = 0;
|
||||
|
||||
/* Find next finally block */
|
||||
|
@ -59,6 +61,7 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio
|
|||
if (finally_op_num) {
|
||||
execute_data->opline = &op_array->opcodes[finally_op_num];
|
||||
execute_data->leaving = ZEND_RETURN;
|
||||
generator->flags |= ZEND_GENERATOR_FORCED_CLOSE;
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
return;
|
||||
}
|
||||
|
@ -66,7 +69,7 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio
|
|||
}
|
||||
|
||||
if (!execute_data->symbol_table) {
|
||||
zend_free_compiled_variables(execute_data->CVs, execute_data->op_array->last_var);
|
||||
zend_free_compiled_variables(execute_data->CVs, op_array->last_var);
|
||||
} else {
|
||||
zend_clean_and_cache_symbol_table(execute_data->symbol_table TSRMLS_CC);
|
||||
}
|
||||
|
@ -83,8 +86,9 @@ void zend_generator_close(zend_generator *generator, zend_bool finished_executio
|
|||
* a return statement) we have to free loop variables manually, as
|
||||
* we don't know whether the SWITCH_FREE / FREE opcodes have run */
|
||||
if (!finished_execution) {
|
||||
zend_op_array *op_array = execute_data->op_array;
|
||||
zend_uint op_num = execute_data->opline - op_array->opcodes;
|
||||
/* -1 required because we want the last run opcode, not the
|
||||
* next to-be-run one. */
|
||||
zend_uint op_num = execute_data->opline - op_array->opcodes - 1;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < op_array->last_brk_cont; ++i) {
|
||||
|
@ -411,6 +415,13 @@ void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */
|
|||
return;
|
||||
}
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_CURRENTLY_RUNNING) {
|
||||
zend_error(E_ERROR, "Cannot resume an already running generator");
|
||||
}
|
||||
|
||||
/* Drop the AT_FIRST_YIELD flag */
|
||||
generator->flags &= ~ZEND_GENERATOR_AT_FIRST_YIELD;
|
||||
|
||||
{
|
||||
/* Backup executor globals */
|
||||
zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr);
|
||||
|
@ -455,7 +466,9 @@ void zend_generator_resume(zend_generator *generator TSRMLS_DC) /* {{{ */
|
|||
generator->execute_data->prev_execute_data->prev_execute_data = original_execute_data;
|
||||
|
||||
/* Resume execution */
|
||||
generator->flags |= ZEND_GENERATOR_CURRENTLY_RUNNING;
|
||||
execute_ex(generator->execute_data TSRMLS_CC);
|
||||
generator->flags &= ~ZEND_GENERATOR_CURRENTLY_RUNNING;
|
||||
|
||||
/* Restore executor globals */
|
||||
EG(return_value_ptr_ptr) = original_return_value_ptr_ptr;
|
||||
|
@ -489,6 +502,17 @@ static void zend_generator_ensure_initialized(zend_generator *generator TSRMLS_D
|
|||
{
|
||||
if (!generator->value) {
|
||||
zend_generator_resume(generator TSRMLS_CC);
|
||||
generator->flags |= ZEND_GENERATOR_AT_FIRST_YIELD;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_generator_rewind(zend_generator *generator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
if (!(generator->flags & ZEND_GENERATOR_AT_FIRST_YIELD)) {
|
||||
zend_throw_exception(NULL, "Cannot rewind a generator that was already run", 0 TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -505,10 +529,7 @@ ZEND_METHOD(Generator, rewind)
|
|||
|
||||
generator = (zend_generator *) zend_object_store_get_object(getThis() TSRMLS_CC);
|
||||
|
||||
zend_generator_ensure_initialized(generator TSRMLS_CC);
|
||||
|
||||
/* Generators aren't rewindable, so rewind() only has to make sure that
|
||||
* the generator is initialized, nothing more */
|
||||
zend_generator_rewind(generator TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -721,13 +742,21 @@ static void zend_generator_iterator_move_forward(zend_object_iterator *iterator
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static void zend_generator_iterator_rewind(zend_object_iterator *iterator TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_generator *generator = (zend_generator *) iterator->data;
|
||||
|
||||
zend_generator_rewind(generator TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_object_iterator_funcs zend_generator_iterator_functions = {
|
||||
zend_generator_iterator_dtor,
|
||||
zend_generator_iterator_valid,
|
||||
zend_generator_iterator_get_data,
|
||||
zend_generator_iterator_get_key,
|
||||
zend_generator_iterator_move_forward,
|
||||
NULL
|
||||
zend_generator_iterator_rewind
|
||||
};
|
||||
|
||||
zend_object_iterator *zend_generator_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC) /* {{{ */
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#define ZEND_GENERATORS_H
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
extern ZEND_API zend_class_entry *zend_ce_generator;
|
||||
END_EXTERN_C()
|
||||
|
||||
typedef struct _zend_generator {
|
||||
zend_object std;
|
||||
|
@ -46,17 +48,20 @@ typedef struct _zend_generator {
|
|||
temp_variable *send_target;
|
||||
/* Largest used integer key for auto-incrementing keys */
|
||||
long largest_used_integer_key;
|
||||
|
||||
/* ZEND_GENERATOR_* flags */
|
||||
zend_uchar flags;
|
||||
} zend_generator;
|
||||
|
||||
extern ZEND_API zend_class_entry *zend_ce_generator;
|
||||
static const zend_uchar ZEND_GENERATOR_CURRENTLY_RUNNING = 0x1;
|
||||
static const zend_uchar ZEND_GENERATOR_FORCED_CLOSE = 0x2;
|
||||
static const zend_uchar ZEND_GENERATOR_AT_FIRST_YIELD = 0x4;
|
||||
|
||||
void zend_register_generator_ce(TSRMLS_D);
|
||||
zval *zend_generator_create_zval(zend_op_array *op_array TSRMLS_DC);
|
||||
void zend_generator_close(zend_generator *generator, zend_bool finished_execution TSRMLS_DC);
|
||||
void zend_generator_resume(zend_generator *generator TSRMLS_DC);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -5402,6 +5402,10 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
|
|
@ -4209,6 +4209,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -4899,6 +4903,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -5914,6 +5922,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -6624,6 +6636,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -7373,6 +7389,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -9436,6 +9456,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -10126,6 +10150,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -11141,6 +11169,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -11717,6 +11749,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -12404,6 +12440,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -16326,6 +16366,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -18405,6 +18449,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -20864,6 +20912,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -22001,6 +22053,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -24129,6 +24185,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -25616,6 +25676,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -26925,6 +26989,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -28234,6 +28302,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -28654,6 +28726,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -29960,6 +30036,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -33481,6 +33561,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -35429,6 +35513,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -37756,6 +37844,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -38752,6 +38844,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
@ -40748,6 +40844,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
|||
/* The generator object is stored in return_value_ptr_ptr */
|
||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||
|
||||
if (generator->flags & ZEND_GENERATOR_FORCED_CLOSE) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot yield from finally in a force-closed generator");
|
||||
}
|
||||
|
||||
/* Destroy the previously yielded value */
|
||||
if (generator->value) {
|
||||
zval_ptr_dtor(&generator->value);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue