summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2015-11-25 23:10:06 +0100
committerBob Weinand <bobwei9@hotmail.com>2015-11-25 23:10:06 +0100
commit39b616ac23f8287a64c4003718ae3ee9648a367f (patch)
treeb06818fd1197ddce8b1d3bc3fe1df1b34eb09efe
parenteaa94390b3401ac531afe410378c24b998067a48 (diff)
parent2de8915dead83fbefcb50288f5ff1c20c9967510 (diff)
downloadphp-git-39b616ac23f8287a64c4003718ae3ee9648a367f.tar.gz
Merge branch 'PHP-7.0'
-rw-r--r--Zend/tests/generators/throw_into_yield_from_array.phpt43
-rw-r--r--Zend/zend_generators.c6
2 files changed, 49 insertions, 0 deletions
diff --git a/Zend/tests/generators/throw_into_yield_from_array.phpt b/Zend/tests/generators/throw_into_yield_from_array.phpt
new file mode 100644
index 0000000000..b1571f6639
--- /dev/null
+++ b/Zend/tests/generators/throw_into_yield_from_array.phpt
@@ -0,0 +1,43 @@
+--TEST--
+Throwing into a generator yielding from an array/iterator
+--FILE--
+<?php
+
+$data = [1, 2, 3];
+
+function yielditer($arr) {
+ foreach($arr as $val) {
+ yield $val;
+ }
+}
+
+function yf($in) {
+ yield from $in;
+}
+
+function test($g) {
+ var_dump($g->current());
+ try {
+ $g->throw(new Exception("Exception!"));
+ } catch (Exception $e) {
+ echo "{$e->getMessage()}\n";
+ }
+ var_dump($g->current());
+}
+
+$yfiter = yf($data);
+$yfgen = yf(yielditer($data));
+
+test(yf($data));
+echo "\n";
+test(yf(yielditer($data)));
+
+?>
+--EXPECT--
+int(1)
+Exception!
+NULL
+
+int(1)
+Exception!
+NULL
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 9ef63df8d6..eb7d40e7fc 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -287,6 +287,12 @@ ZEND_API zend_execute_data *zend_generator_check_placeholder_frame(zend_execute_
static void zend_generator_throw_exception(zend_generator *generator, zval *exception)
{
+ /* if we don't stop an array/iterator yield from, the exception will only reach the generator after the values were all iterated over */
+ if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
+ zval_ptr_dtor(&generator->values);
+ ZVAL_UNDEF(&generator->values);
+ }
+
/* Throw the exception in the context of the generator. Decrementing the opline
* to pretend the exception happened during the YIELD opcode. */
zend_execute_data *original_execute_data = EG(current_execute_data);