Skip to content

Commit 3524702

Browse files
committed
Fix GH-17428: Assertion failure ext/opcache/jit/zend_jit_ir.c:8940
The code to update the call_level in that case skips the opline itself, as that's handled by the tail handler, and then wants to set the opline to the last opline of the block because the code below the switch will update the call_level for that opline. However, the test has a block with a single opline (THROW). The block after that has ZEND_INIT_FCALL, because `i` points to ZEND_INIT_FCALL now, it erroneously causes the call_level after the switch. Closes GH-17438.
1 parent b1e0176 commit 3524702

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ PHP NEWS
4444
. Fixed bug GH-15981 (Segfault with frameless jumps and minimal JIT).
4545
(nielsdos)
4646
. Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos)
47+
. Fixed bug GH-17428 (Assertion failure ext/opcache/jit/zend_jit_ir.c:8940).
48+
(nielsdos)
4749

4850
- PHPDBG:
4951
. Fix crashes in function registration + test. (nielsdos, Girgias)

ext/opcache/jit/zend_jit.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,8 +2622,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
26222622
/* THROW and EXIT may be used in the middle of BB */
26232623
/* don't generate code for the rest of BB */
26242624

2625-
/* Skip current opline for call_level computation
2626-
* Don't include last opline because end of loop already checks call level of last opline */
2625+
/* Skip current opline for call_level computation because it does not influence call_level.
2626+
* Don't include last opline because end of loop already checks call level of last opline. */
26272627
i++;
26282628
for (; i < end; i++) {
26292629
opline = op_array->opcodes + i;
@@ -2633,7 +2633,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
26332633
call_level--;
26342634
}
26352635
}
2636-
opline = op_array->opcodes + i;
2636+
opline = op_array->opcodes + end;
26372637
break;
26382638
/* stackless execution */
26392639
case ZEND_INCLUDE_OR_EVAL:

ext/opcache/tests/jit/gh17428.phpt

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--TEST--
2+
GH-17428 (Assertion failure ext/opcache/jit/zend_jit_ir.c:8940)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit=1205
7+
--FILE--
8+
<?php
9+
new EmptyIterator();
10+
srand(1000);
11+
error_reporting(E_ALL);
12+
testConversion('', '');
13+
testConversion('', '');
14+
testConversion('', '');
15+
testConversion('', '');
16+
testConversion('', '');
17+
function testRoundTrip($data) {
18+
}
19+
for ($iterations = 0; $iterations < 100; $iterations++) {
20+
$strlen = rand(1, 100);
21+
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
22+
$randstring = '';
23+
for ($i = 0; $i < $strlen; $i++) {
24+
$randstring .= $characters[rand(0, strlen($characters) - 1)];
25+
}
26+
die($randstring);
27+
}
28+
echo "Done!\n";
29+
throw new Hello(new stdClass);
30+
?>
31+
--EXPECTF--
32+
Fatal error: Uncaught Error: Call to undefined function testConversion() in %s:%d
33+
Stack trace:
34+
#0 {main}
35+
thrown in %s on line %d

0 commit comments

Comments
 (0)