1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

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.
This commit is contained in:
Niels Dossche
2025-01-10 19:07:41 +01:00
parent b1e0176455
commit 3524702fe1
3 changed files with 40 additions and 3 deletions

2
NEWS
View File

@@ -44,6 +44,8 @@ PHP NEWS
. Fixed bug GH-15981 (Segfault with frameless jumps and minimal JIT).
(nielsdos)
. Fixed bug GH-17307 (Internal closure causes JIT failure). (nielsdos)
. Fixed bug GH-17428 (Assertion failure ext/opcache/jit/zend_jit_ir.c:8940).
(nielsdos)
- PHPDBG:
. Fix crashes in function registration + test. (nielsdos, Girgias)

View File

@@ -2622,8 +2622,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
/* THROW and EXIT may be used in the middle of BB */
/* don't generate code for the rest of BB */
/* Skip current opline for call_level computation
* Don't include last opline because end of loop already checks call level of last opline */
/* Skip current opline for call_level computation because it does not influence call_level.
* Don't include last opline because end of loop already checks call level of last opline. */
i++;
for (; i < end; i++) {
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
call_level--;
}
}
opline = op_array->opcodes + i;
opline = op_array->opcodes + end;
break;
/* stackless execution */
case ZEND_INCLUDE_OR_EVAL:

View File

@@ -0,0 +1,35 @@
--TEST--
GH-17428 (Assertion failure ext/opcache/jit/zend_jit_ir.c:8940)
--EXTENSIONS--
opcache
--INI--
opcache.jit=1205
--FILE--
<?php
new EmptyIterator();
srand(1000);
error_reporting(E_ALL);
testConversion('', '');
testConversion('', '');
testConversion('', '');
testConversion('', '');
testConversion('', '');
function testRoundTrip($data) {
}
for ($iterations = 0; $iterations < 100; $iterations++) {
$strlen = rand(1, 100);
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < $strlen; $i++) {
$randstring .= $characters[rand(0, strlen($characters) - 1)];
}
die($randstring);
}
echo "Done!\n";
throw new Hello(new stdClass);
?>
--EXPECTF--
Fatal error: Uncaught Error: Call to undefined function testConversion() in %s:%d
Stack trace:
#0 {main}
thrown in %s on line %d