Grokbase Groups PHP php-cvs May 2016
FAQ
Commit: 4746e5efcb135051e003294f4721792139779fd0
Author: Nikita Popov <nikic@php.net> Sat, 28 May 2016 13:13:11 +0200
Parents: d29bd582a8cc28e9288b441e269d98f4f28da77d
Branches: PHP-7.0 master

Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=4746e5efcb135051e003294f4721792139779fd0

Log:
Forbid "yield from" in force closed generators

Same check we do for "yield", was missed when "yield from" was
added. We could make this more granular by only forbidding to
actually yield values and still allow something like "yield from []",
but this does not seem worthwhile.

Changed paths:
   A Zend/tests/generators/yield_from_force_closed.phpt
   M Zend/zend_vm_def.h
   M Zend/zend_vm_execute.h


Diff:
diff --git a/Zend/tests/generators/yield_from_force_closed.phpt b/Zend/tests/generators/yield_from_force_closed.phpt
new file mode 100644
index 0000000..87fcd2e
--- /dev/null
+++ b/Zend/tests/generators/yield_from_force_closed.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Cannot "yield from" from force closed generator
+--FILE--
+<?php
+
+function gen1() {
+ echo "gen1\n";
+ yield 1;
+}
+
+function gen2() {
+ try {
+ echo "try\n";
+ yield from gen1();
+ } finally {
+ echo "finally\n";
+ yield from gen1();
+ }
+}
+
+try {
+ $gen = gen2();
+ $gen->rewind();
+ unset($gen);
+} catch (Error $e) {
+ echo $e, "\n";
+}
+
+?>
+--EXPECTF--
+try
+gen1
+finally
+Error: Cannot use "yield from" in a force-closed generator in %s:%d
+Stack trace:
+#0 %s(%d): gen2()
+#1 {main}
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index cbb986b..ce7c6fa 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -7442,6 +7442,12 @@ ZEND_VM_HANDLER(142, ZEND_YIELD_FROM, CONST|TMP|VAR|CV, ANY)
   SAVE_OPLINE();
   val = GET_OP1_ZVAL_PTR_DEREF(BP_VAR_R);

+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+ FREE_OP1();
+ HANDLE_EXCEPTION();
+ }
+
   if (Z_TYPE_P(val) == IS_ARRAY) {
    ZVAL_COPY_VALUE(&generator->values, val);
    if (OP1_TYPE != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index d9d58e0..aba8081 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4106,6 +4106,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CONST_HANDLER(
   SAVE_OPLINE();
   val = EX_CONSTANT(opline->op1);

+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+
+ HANDLE_EXCEPTION();
+ }
+
   if (Z_TYPE_P(val) == IS_ARRAY) {
    ZVAL_COPY_VALUE(&generator->values, val);
    if (IS_CONST != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
@@ -12502,6 +12508,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_TMP_HANDLER(ZE
   SAVE_OPLINE();
   val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1);

+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+ zval_ptr_dtor_nogc(free_op1);
+ HANDLE_EXCEPTION();
+ }
+
   if (Z_TYPE_P(val) == IS_ARRAY) {
    ZVAL_COPY_VALUE(&generator->values, val);
    if (IS_TMP_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
@@ -16320,6 +16332,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_VAR_HANDLER(ZE
   SAVE_OPLINE();
   val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1);

+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+ zval_ptr_dtor_nogc(free_op1);
+ HANDLE_EXCEPTION();
+ }
+
   if (Z_TYPE_P(val) == IS_ARRAY) {
    ZVAL_COPY_VALUE(&generator->values, val);
    if (IS_VAR != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {
@@ -29759,6 +29777,12 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_FROM_SPEC_CV_HANDLER(ZEN
   SAVE_OPLINE();
   val = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var);

+ if (UNEXPECTED(generator->flags & ZEND_GENERATOR_FORCED_CLOSE)) {
+ zend_throw_error(NULL, "Cannot use \"yield from\" in a force-closed generator");
+
+ HANDLE_EXCEPTION();
+ }
+
   if (Z_TYPE_P(val) == IS_ARRAY) {
    ZVAL_COPY_VALUE(&generator->values, val);
    if (IS_CV != IS_TMP_VAR && Z_OPT_REFCOUNTED_P(val)) {

Search Discussions

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupphp-cvs @
categoriesphp
postedMay 28, '16 at 11:25a
activeMay 28, '16 at 11:25a
posts1
users1
websitephp.net

1 user in discussion

Nikita Popov: 1 post

People

Translate

site design / logo © 2019 Grokbase