Skip to content

Commit 504a633

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fit JIT variable not stored before YIELD
2 parents 38b9c33 + bc05bfe commit 504a633

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ PHP NEWS
1616
- ODBC:
1717
. Remove ODBCVER and assume ODBC 3.5. (Calvin Buckley)
1818

19+
- Opcache:
20+
. Fixed bug GH-19493 (JIT variable not stored before YIELD). (Arnaud)
21+
1922
- OpenSSL:
2023
. Implement #81724 (openssl_cms_encrypt only allows specific ciphers).
2124
(Jakub Zelenka)

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,6 +987,7 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
987987
break;
988988
}
989989

990+
const zend_op *prev_opline = opline;
990991
handler = ZEND_OP_TRACE_INFO(opline, offset)->call_handler;
991992
#ifdef HAVE_GCC_GLOBAL_REGS
992993
handler();
@@ -995,7 +996,11 @@ zend_jit_trace_stop ZEND_FASTCALL zend_jit_trace_execute(zend_execute_data *ex,
995996
opline = handler(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
996997
if (UNEXPECTED(((uintptr_t)opline & ~ZEND_VM_ENTER_BIT) == 0)) {
997998
#endif
998-
stop = ZEND_JIT_TRACE_STOP_RETURN;
999+
if (prev_opline->opcode == ZEND_YIELD || prev_opline->opcode == ZEND_YIELD_FROM) {
1000+
stop = ZEND_JIT_TRACE_STOP_INTERPRETER;
1001+
} else {
1002+
stop = ZEND_JIT_TRACE_STOP_RETURN;
1003+
}
9991004
opline = NULL;
10001005
halt = ZEND_JIT_TRACE_HALT;
10011006
break;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-19493 001: Var not stored before YIELD
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
$offset = 0;
8+
yield true;
9+
for ($i = 0; $i < 100; $i++) {
10+
$offset++;
11+
if ($offset === 99) {
12+
break;
13+
}
14+
yield true;
15+
}
16+
return $offset;
17+
}
18+
$gen = f();
19+
foreach ($gen as $v) {}
20+
var_dump($gen->getReturn());
21+
22+
?>
23+
--EXPECT--
24+
int(99)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
--TEST--
2+
GH-19493 002: Var not stored before YIELD_FROM
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
$offset = 0;
8+
yield from [true];
9+
for ($i = 0; $i < 100; $i++) {
10+
$offset++;
11+
if ($offset === 99) {
12+
break;
13+
}
14+
yield from [true];
15+
}
16+
return $offset;
17+
}
18+
$gen = f();
19+
foreach ($gen as $v) {}
20+
var_dump($gen->getReturn());
21+
22+
?>
23+
--EXPECT--
24+
int(99)

0 commit comments

Comments
 (0)