mirror of
https://github.com/php/php-src.git
synced 2024-09-30 14:26:12 +00:00
Merge branch 'PHP-7.0' of git.php.net:/php-src into PHP-7.0
* 'PHP-7.0' of git.php.net:/php-src: Fixed bug #71980
This commit is contained in:
commit
d242a8fb68
2
NEWS
2
NEWS
@ -24,6 +24,8 @@ PHP NEWS
|
||||
. Fixed bug #69537 (__debugInfo with empty string for key gives error).
|
||||
(krakjoe)
|
||||
. Fixed bug #62059 (ArrayObject and isset are not friends). (Nikita)
|
||||
. Fixed bug #71980 (Decorated/Nested Generator is Uncloseable in Finally).
|
||||
(Nikita)
|
||||
|
||||
- Curl:
|
||||
. Fixed bug #71831 (CURLOPT_NOPROXY applied as long instead of string).
|
||||
|
43
Zend/tests/bug71980.phpt
Normal file
43
Zend/tests/bug71980.phpt
Normal file
@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
Bug #71980: Decorated/Nested Generator is Uncloseable in Finally
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
class Dtor {
|
||||
public function __destruct() {
|
||||
echo "Dtor\n";
|
||||
}
|
||||
}
|
||||
|
||||
function gen1() {
|
||||
try {
|
||||
foreach ([42, new Dtor] as $value) {
|
||||
yield $value;
|
||||
}
|
||||
} finally {
|
||||
echo "Finally\n";
|
||||
}
|
||||
}
|
||||
|
||||
function gen2() {
|
||||
try {
|
||||
var_dump(new Dtor, yield);
|
||||
} finally {
|
||||
echo "Finally\n";
|
||||
}
|
||||
}
|
||||
|
||||
$gen = gen1();
|
||||
$gen->rewind();
|
||||
unset($gen);
|
||||
|
||||
$gen = gen2();
|
||||
$gen->rewind();
|
||||
unset($gen);
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Dtor
|
||||
Finally
|
||||
Dtor
|
||||
Finally
|
@ -31,7 +31,8 @@ static zend_object_handlers zend_generator_handlers;
|
||||
|
||||
static zend_object *zend_generator_create(zend_class_entry *class_type);
|
||||
|
||||
static void zend_generator_cleanup_unfinished_execution(zend_generator *generator) /* {{{ */
|
||||
static void zend_generator_cleanup_unfinished_execution(
|
||||
zend_generator *generator, uint32_t catch_op_num) /* {{{ */
|
||||
{
|
||||
zend_execute_data *execute_data = generator->execute_data;
|
||||
|
||||
@ -47,7 +48,7 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
|
||||
EG(vm_stack_end) = generator->stack->end;
|
||||
EG(vm_stack) = generator->stack;
|
||||
|
||||
zend_cleanup_unfinished_execution(execute_data, op_num, 0);
|
||||
zend_cleanup_unfinished_execution(execute_data, op_num, catch_op_num);
|
||||
|
||||
generator->stack = EG(vm_stack);
|
||||
generator->stack->top = EG(vm_stack_top);
|
||||
@ -85,7 +86,7 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
|
||||
/* Some cleanups are only necessary if the generator was closed
|
||||
* before it could finish execution (reach a return statement). */
|
||||
if (UNEXPECTED(!finished_execution)) {
|
||||
zend_generator_cleanup_unfinished_execution(generator);
|
||||
zend_generator_cleanup_unfinished_execution(generator, 0);
|
||||
}
|
||||
|
||||
/* Free closure object */
|
||||
@ -151,8 +152,11 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
|
||||
/* If a finally block was found we jump directly to it and
|
||||
* resume the generator. */
|
||||
if (finally_op_num) {
|
||||
zval *fast_call = ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[finally_op_end].op1.var);
|
||||
zval *fast_call;
|
||||
|
||||
zend_generator_cleanup_unfinished_execution(generator, finally_op_num);
|
||||
|
||||
fast_call = ZEND_CALL_VAR(ex, ex->func->op_array.opcodes[finally_op_end].op1.var);
|
||||
Z_OBJ_P(fast_call) = EG(exception);
|
||||
EG(exception) = NULL;
|
||||
fast_call->u2.lineno = (uint32_t)-1;
|
||||
|
Loading…
Reference in New Issue
Block a user