Skip to content

Commit 4c8ff48

Browse files
committed
Always load EX(opline) into the current frame in JIT when observers are enabled
Fixes #13772.
1 parent 50fe64c commit 4c8ff48

File tree

4 files changed

+31
-2
lines changed

4 files changed

+31
-2
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9475,7 +9475,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
94759475
}
94769476

94779477
if (ZEND_OBSERVER_ENABLED) {
9478-
| SAVE_IP
9478+
| SET_EX_OPLINE opline, REG0
94799479
| mov FCARG1x, FP
94809480
| EXT_CALL zend_observer_fcall_begin, REG0
94819481
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10221,7 +10221,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
1022110221
}
1022210222

1022310223
if (ZEND_OBSERVER_ENABLED) {
10224-
| SAVE_IP
10224+
| SET_EX_OPLINE opline, r0
1022510225
| mov FCARG1a, FP
1022610226
| EXT_CALL zend_observer_fcall_begin, r0
1022710227
}

ext/opcache/tests/jit/gh13772.phpt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
EX(opline) is correctly set for nested JIT user code calls
3+
--EXTENSIONS--
4+
opcache
5+
zend_test
6+
--INI--
7+
opcache.enable=1
8+
opcache.enable_cli=1
9+
zend_test.observer.enabled=1
10+
zend_test.observer.observe_all=1
11+
zend_test.observer.show_output=0
12+
--FILE--
13+
<?php
14+
15+
function Ack($m, $n) {
16+
if ($m == 0) return $n+1;
17+
if ($n == 0) return Ack($m-1, 1);
18+
return Ack($m - 1, Ack($m, ($n - 1)));
19+
}
20+
21+
var_dump(Ack(3, 3));
22+
23+
?>
24+
--EXPECT--
25+
int(61)
26+

ext/zend_test/observer.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ static void observer_show_opcode(zend_execute_data *execute_data)
6969

7070
static void observer_begin(zend_execute_data *execute_data)
7171
{
72+
ZEND_ASSERT(!ZEND_USER_CODE(EX(func)->type) ||
73+
(EX(opline) >= EX(func)->op_array.opcodes && EX(opline) < EX(func)->op_array.opcodes + EX(func)->op_array.last));
74+
7275
if (!ZT_G(observer_show_output)) {
7376
return;
7477
}

0 commit comments

Comments
 (0)