summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/generators/bug66041.phpt17
-rw-r--r--Zend/zend_compile.c2
-rw-r--r--Zend/zend_generators.c13
-rw-r--r--Zend/zend_generators.h2
-rw-r--r--Zend/zend_vm_def.h14
-rw-r--r--Zend/zend_vm_execute.h350
7 files changed, 266 insertions, 134 deletions
diff --git a/NEWS b/NEWS
index 55ee92e4e6..008b22dc18 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,8 @@ PHP NEWS
- Core:
. Added validation of class names in the autoload process. (Dmitry)
+ . Fixed buf #66041 (list() fails to unpack yielded ArrayAccess object).
+ (Nikita)
- Date:
. Fixed bug #66060 (Heap buffer over-read in DateInterval). (Remi)
diff --git a/Zend/tests/generators/bug66041.phpt b/Zend/tests/generators/bug66041.phpt
new file mode 100644
index 0000000000..d944224134
--- /dev/null
+++ b/Zend/tests/generators/bug66041.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #66041: list() fails to unpack yielded ArrayAccess object
+--FILE--
+<?php
+function dumpElement() {
+ list($value) = yield;
+ var_dump($value);
+};
+
+$fixedArray = new SplFixedArray(1);
+$fixedArray[0] = 'the element';
+
+$generator = dumpElement();
+$generator->send($fixedArray);
+?>
+--EXPECT--
+string(11) "the element"
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 60b9e3e653..c5f3769216 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2782,7 +2782,7 @@ void zend_do_yield(znode *result, znode *value, const znode *key, zend_bool is_v
SET_UNUSED(opline->op2);
}
- opline->result_type = IS_TMP_VAR;
+ opline->result_type = IS_VAR;
opline->result.var = get_temporary_variable(CG(active_op_array));
GET_NODE(result, opline->result);
}
diff --git a/Zend/zend_generators.c b/Zend/zend_generators.c
index 0af20f4593..c0116332e7 100644
--- a/Zend/zend_generators.c
+++ b/Zend/zend_generators.c
@@ -55,6 +55,11 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
zval_ptr_dtor(&execute_data->current_this);
}
+ if (!finished_execution && generator->send_target) {
+ Z_DELREF_PP(generator->send_target);
+ generator->send_target = NULL;
+ }
+
/* A fatal error / die occurred during the generator execution. Trying to clean
* up the stack may not be safe in this case. */
if (CG(unclean_shutdown)) {
@@ -519,8 +524,12 @@ ZEND_METHOD(Generator, send)
return;
}
- /* Put sent value into the TMP_VAR slot */
- MAKE_COPY_ZVAL(&value, &generator->send_target->tmp_var);
+ /* Put sent value in the target VAR slot, if it is used */
+ if (generator->send_target) {
+ Z_DELREF_PP(generator->send_target);
+ Z_ADDREF_P(value);
+ *generator->send_target = value;
+ }
zend_generator_resume(generator TSRMLS_CC);
diff --git a/Zend/zend_generators.h b/Zend/zend_generators.h
index bc125658ee..d5f6101315 100644
--- a/Zend/zend_generators.h
+++ b/Zend/zend_generators.h
@@ -49,7 +49,7 @@ typedef struct _zend_generator {
/* Current key */
zval *key;
/* Variable to put sent value into */
- temp_variable *send_target;
+ zval **send_target;
/* Largest used integer key for auto-incrementing keys */
long largest_used_integer_key;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 05557e9833..9db6ea19f9 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -5353,11 +5353,15 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index ec29f9e7d8..3a0a70e946 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -4198,11 +4198,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -4887,11 +4891,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -5904,11 +5912,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -6625,11 +6637,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -7373,11 +7389,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -9400,11 +9420,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -10091,11 +10115,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -11110,11 +11138,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -11690,11 +11722,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -12378,11 +12414,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -16265,11 +16305,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -18350,11 +18394,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -20818,11 +20866,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -21970,11 +22022,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -24104,11 +24160,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -25602,11 +25662,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -26916,11 +26980,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -28231,11 +28299,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -28653,11 +28725,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -29964,11 +30040,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -33449,11 +33529,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -35396,11 +35480,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -37725,11 +37813,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -38729,11 +38821,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */
@@ -40724,11 +40820,15 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
ZVAL_LONG(generator->key, generator->largest_used_integer_key);
}
- /* If a value is sent it should go into the result var */
- generator->send_target = &EX_T(opline->result.var);
-
- /* Initialize the sent value to NULL */
- EX_T(opline->result.var).tmp_var = EG(uninitialized_zval);
+ if (RETURN_VALUE_USED(opline)) {
+ /* If the return value of yield is used set the send
+ * target and initialize it to NULL */
+ generator->send_target = &EX_T(opline->result.var).var.ptr;
+ Z_ADDREF(EG(uninitialized_zval));
+ EX_T(opline->result.var).var.ptr = &EG(uninitialized_zval);
+ } else {
+ generator->send_target = NULL;
+ }
/* We increment to the next op, so we are at the correct position when the
* generator is resumed. */