com php-src: Avoid op_num = -1 in unfinished ge nerator cleanup: Zend/tests/generators/aborted_yield_ during_nested_fcalls.phpt
Zend/tests/generators/aborted _yield_during_switch.phpt Zend/zend_generators.c
| From: | Nikita Popov | Date: | Tue, 23 Jun 2015 18:17:30 +0000 |
| Subject: | com php-src: Avoid op_num = -1 in unfinished ge nerator cleanup: Zend/tests/generators/aborted_yield_ during_nested_fcalls.phpt Zend/tests/generators/aborted _yield_during_switch.phpt Zend/zend_generators.c |
||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-87482@lists.php.net to get a copy of this message | ||
Commit: ea5c66ec9310430111b48d4589e56cea5c0b5ab0
Author: Nikita Popov <nikic@php.net> Tue, 23 Jun 2015 20:13:25 +0200
Parents: f4d08d8e5cb413f4d70a1f64f16b6b0ce1808e21
Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=ea5c66ec9310430111b48d4589e56cea5c0b5ab0
Log:
Avoid op_num = -1 in unfinished generator cleanup
Also add two tests showing that the -1 substraction in the
computation of op_num is really necessary.
Changed paths:
A Zend/tests/generators/aborted_yield_during_nested_fcalls.phpt
A Zend/tests/generators/aborted_yield_during_switch.phpt
M Zend/zend_generators.c
Diff:
diff --git a/Zend/tests/generators/aborted_yield_during_nested_fcalls.phpt
b/Zend/tests/generators/aborted_yield_during_nested_fcalls.phpt
new file mode 100644
index 0000000..9d3bea3
--- /dev/null
+++ b/Zend/tests/generators/aborted_yield_during_nested_fcalls.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Aborted yield during nested calls
+--FILE--
+<?php
+
+function func() {}
+
+function gen($x) {
+ func(func($x, $x, func($x, yield)));
+}
+
+$gen = gen("x");
+$gen->rewind();
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/tests/generators/aborted_yield_during_switch.phpt
b/Zend/tests/generators/aborted_yield_during_switch.phpt
new file mode 100644
index 0000000..1b1d6a1
--- /dev/null
+++ b/Zend/tests/generators/aborted_yield_during_switch.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Aborted yield during switch
+--FILE--
+<?php
+
+function gen($x) {
+ switch ($x."y") {
+ default:
+ yield;
+ }
+}
+
+$gen = gen("x");
+$gen->rewind();
+
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 6a04ebd..96592fa 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -34,15 +34,16 @@ static zend_object *zend_generator_create(zend_class_entry *class_type);
static void zend_generator_cleanup_unfinished_execution(zend_generator *generator) /* {{{ */
{
zend_execute_data *execute_data = generator->execute_data;
- /* -1 required because we want the last run opcode, not the next to-be-run one. */
- uint32_t op_num = execute_data->opline - execute_data->func->op_array.opcodes - 1;
if (generator->send_target) {
- if (Z_REFCOUNTED_P(generator->send_target)) Z_DELREF_P(generator->send_target);
+ Z_TRY_DELREF_P(generator->send_target);
generator->send_target = NULL;
}
- {
+ if (execute_data->opline != execute_data->func->op_array.opcodes) {
+ /* -1 required because we want the last run opcode, not the next to-be-run one. */
+ uint32_t op_num = execute_data->opline - execute_data->func->op_array.opcodes - 1;
+
/* There may be calls to zend_vm_stack_free_call_frame(), which modifies the VM stack
* globals, so need to load/restore those. */
zend_vm_stack original_stack = EG(vm_stack);