diff --git a/NEWS b/NEWS index 3fe788a7ead..c082f336225 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,9 @@ PHP NEWS . Fixed bug GH-18850 (Repeated inclusion of file with __halt_compiler() triggers "Constant already defined" warning). (ilutov) +- Opcache: + . Fixed bug GH-19493 (JIT variable not stored before YIELD). (Arnaud) + - OpenSSL: . Fixed bug GH-19245 (Success error message on TLS stream accept failure). (Jakub Zelenka) diff --git a/ext/opcache/jit/zend_jit_vm_helpers.c b/ext/opcache/jit/zend_jit_vm_helpers.c index f4d261cd753..8b85324ef89 100644 --- a/ext/opcache/jit/zend_jit_vm_helpers.c +++ b/ext/opcache/jit/zend_jit_vm_helpers.c @@ -937,11 +937,18 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, break; } +#ifdef HAVE_GCC_GLOBAL_REGS + const zend_op *prev_opline = opline; +#endif handler = (zend_vm_opcode_handler_t)ZEND_OP_TRACE_INFO(opline, offset)->call_handler; #ifdef HAVE_GCC_GLOBAL_REGS handler(); if (UNEXPECTED(opline == zend_jit_halt_op)) { - stop = ZEND_JIT_TRACE_STOP_RETURN; + if (prev_opline->opcode == ZEND_YIELD || prev_opline->opcode == ZEND_YIELD_FROM) { + stop = ZEND_JIT_TRACE_STOP_INTERPRETER; + } else { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } opline = NULL; halt = ZEND_JIT_TRACE_HALT; break; @@ -951,7 +958,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex, rc = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); if (rc != 0) { if (rc < 0) { - stop = ZEND_JIT_TRACE_STOP_RETURN; + if (opline->opcode == ZEND_YIELD || opline->opcode == ZEND_YIELD_FROM) { + stop = ZEND_JIT_TRACE_STOP_INTERPRETER; + } else { + stop = ZEND_JIT_TRACE_STOP_RETURN; + } opline = NULL; halt = ZEND_JIT_TRACE_HALT; break; diff --git a/ext/opcache/tests/jit/gh19493-001.phpt b/ext/opcache/tests/jit/gh19493-001.phpt new file mode 100644 index 00000000000..68e5d6e2401 --- /dev/null +++ b/ext/opcache/tests/jit/gh19493-001.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19493 001: Var not stored before YIELD +--FILE-- +getReturn()); + +?> +--EXPECT-- +int(99) diff --git a/ext/opcache/tests/jit/gh19493-002.phpt b/ext/opcache/tests/jit/gh19493-002.phpt new file mode 100644 index 00000000000..57f2a982673 --- /dev/null +++ b/ext/opcache/tests/jit/gh19493-002.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-19493 002: Var not stored before YIELD_FROM +--FILE-- +getReturn()); + +?> +--EXPECT-- +int(99)