mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.3'
* PHP-8.3: Fixed GH-12382: JIT Index invalid or out of range error
This commit is contained in:
commit
d17c672833
2 changed files with 76 additions and 7 deletions
|
@ -4408,6 +4408,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
uint32_t res_use_info,
|
uint32_t res_use_info,
|
||||||
int may_overflow)
|
int may_overflow)
|
||||||
{
|
{
|
||||||
|
bool must_set_cflags = 0;
|
||||||
bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
|
bool same_ops = zend_jit_same_addr(op1_addr, op2_addr);
|
||||||
zend_reg result_reg;
|
zend_reg result_reg;
|
||||||
zend_reg tmp_reg = ZREG_R0;
|
zend_reg tmp_reg = ZREG_R0;
|
||||||
|
@ -4430,10 +4431,39 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
tmp_reg = ZREG_FCARG1;
|
tmp_reg = ZREG_FCARG1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (may_overflow) {
|
||||||
|
must_set_cflags = 1;
|
||||||
|
} else {
|
||||||
|
const zend_op *next_opline = opline + 1;
|
||||||
|
|
||||||
|
if (next_opline->opcode == ZEND_IS_EQUAL ||
|
||||||
|
next_opline->opcode == ZEND_IS_NOT_EQUAL ||
|
||||||
|
next_opline->opcode == ZEND_IS_SMALLER ||
|
||||||
|
next_opline->opcode == ZEND_IS_SMALLER_OR_EQUAL ||
|
||||||
|
next_opline->opcode == ZEND_CASE ||
|
||||||
|
next_opline->opcode == ZEND_IS_IDENTICAL ||
|
||||||
|
next_opline->opcode == ZEND_IS_NOT_IDENTICAL ||
|
||||||
|
next_opline->opcode == ZEND_CASE_STRICT) {
|
||||||
|
if (next_opline->op1_type == IS_CONST
|
||||||
|
&& Z_TYPE_P(RT_CONSTANT(next_opline, next_opline->op1)) == IS_LONG
|
||||||
|
&& Z_LVAL_P(RT_CONSTANT(next_opline, next_opline->op1)) == 0
|
||||||
|
&& next_opline->op2_type == opline->result_type
|
||||||
|
&& next_opline->op2.var == opline->result.var) {
|
||||||
|
must_set_cflags = 1;
|
||||||
|
} else if (next_opline->op2_type == IS_CONST
|
||||||
|
&& Z_TYPE_P(RT_CONSTANT(next_opline, next_opline->op2)) == IS_LONG
|
||||||
|
&& Z_LVAL_P(RT_CONSTANT(next_opline, next_opline->op2)) == 0
|
||||||
|
&& next_opline->op2_type == opline->result_type
|
||||||
|
&& next_opline->op2.var == opline->result.var) {
|
||||||
|
must_set_cflags = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (opcode == ZEND_MUL &&
|
if (opcode == ZEND_MUL &&
|
||||||
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
||||||
Z_LVAL_P(Z_ZV(op2_addr)) == 2) {
|
Z_LVAL_P(Z_ZV(op2_addr)) == 2) {
|
||||||
if (Z_MODE(op1_addr) == IS_REG && !may_overflow) {
|
if (Z_MODE(op1_addr) == IS_REG && !must_set_cflags) {
|
||||||
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Ra(Z_REG(op1_addr))]
|
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Ra(Z_REG(op1_addr))]
|
||||||
} else {
|
} else {
|
||||||
| GET_ZVAL_LVAL result_reg, op1_addr
|
| GET_ZVAL_LVAL result_reg, op1_addr
|
||||||
|
@ -4441,7 +4471,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
}
|
}
|
||||||
} else if (opcode == ZEND_MUL &&
|
} else if (opcode == ZEND_MUL &&
|
||||||
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
||||||
!may_overflow &&
|
!must_set_cflags &&
|
||||||
Z_LVAL_P(Z_ZV(op2_addr)) > 0 &&
|
Z_LVAL_P(Z_ZV(op2_addr)) > 0 &&
|
||||||
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) {
|
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op2_addr)))) {
|
||||||
| GET_ZVAL_LVAL result_reg, op1_addr
|
| GET_ZVAL_LVAL result_reg, op1_addr
|
||||||
|
@ -4449,7 +4479,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
} else if (opcode == ZEND_MUL &&
|
} else if (opcode == ZEND_MUL &&
|
||||||
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
||||||
Z_LVAL_P(Z_ZV(op1_addr)) == 2) {
|
Z_LVAL_P(Z_ZV(op1_addr)) == 2) {
|
||||||
if (Z_MODE(op2_addr) == IS_REG && !may_overflow) {
|
if (Z_MODE(op2_addr) == IS_REG && !must_set_cflags) {
|
||||||
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Ra(Z_REG(op2_addr))]
|
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Ra(Z_REG(op2_addr))]
|
||||||
} else {
|
} else {
|
||||||
| GET_ZVAL_LVAL result_reg, op2_addr
|
| GET_ZVAL_LVAL result_reg, op2_addr
|
||||||
|
@ -4457,7 +4487,7 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
}
|
}
|
||||||
} else if (opcode == ZEND_MUL &&
|
} else if (opcode == ZEND_MUL &&
|
||||||
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
||||||
!may_overflow &&
|
!must_set_cflags &&
|
||||||
Z_LVAL_P(Z_ZV(op1_addr)) > 0 &&
|
Z_LVAL_P(Z_ZV(op1_addr)) > 0 &&
|
||||||
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op1_addr)))) {
|
zend_long_is_power_of_two(Z_LVAL_P(Z_ZV(op1_addr)))) {
|
||||||
| GET_ZVAL_LVAL result_reg, op2_addr
|
| GET_ZVAL_LVAL result_reg, op2_addr
|
||||||
|
@ -4468,19 +4498,19 @@ static int zend_jit_math_long_long(dasm_State **Dst,
|
||||||
| GET_ZVAL_LVAL result_reg, op1_addr
|
| GET_ZVAL_LVAL result_reg, op1_addr
|
||||||
| shr Ra(result_reg), zend_long_floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
|
| shr Ra(result_reg), zend_long_floor_log2(Z_LVAL_P(Z_ZV(op2_addr)))
|
||||||
} else if (opcode == ZEND_ADD &&
|
} else if (opcode == ZEND_ADD &&
|
||||||
!may_overflow &&
|
!must_set_cflags &&
|
||||||
Z_MODE(op1_addr) == IS_REG &&
|
Z_MODE(op1_addr) == IS_REG &&
|
||||||
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
||||||
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
|
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op2_addr)))) {
|
||||||
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Z_LVAL_P(Z_ZV(op2_addr))]
|
| lea Ra(result_reg), [Ra(Z_REG(op1_addr))+Z_LVAL_P(Z_ZV(op2_addr))]
|
||||||
} else if (opcode == ZEND_ADD &&
|
} else if (opcode == ZEND_ADD &&
|
||||||
!may_overflow &&
|
!must_set_cflags &&
|
||||||
Z_MODE(op2_addr) == IS_REG &&
|
Z_MODE(op2_addr) == IS_REG &&
|
||||||
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op1_addr) == IS_CONST_ZVAL &&
|
||||||
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op1_addr)))) {
|
IS_SIGNED_32BIT(Z_LVAL_P(Z_ZV(op1_addr)))) {
|
||||||
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Z_LVAL_P(Z_ZV(op1_addr))]
|
| lea Ra(result_reg), [Ra(Z_REG(op2_addr))+Z_LVAL_P(Z_ZV(op1_addr))]
|
||||||
} else if (opcode == ZEND_SUB &&
|
} else if (opcode == ZEND_SUB &&
|
||||||
!may_overflow &&
|
!must_set_cflags &&
|
||||||
Z_MODE(op1_addr) == IS_REG &&
|
Z_MODE(op1_addr) == IS_REG &&
|
||||||
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
Z_MODE(op2_addr) == IS_CONST_ZVAL &&
|
||||||
IS_SIGNED_32BIT(-Z_LVAL_P(Z_ZV(op2_addr)))) {
|
IS_SIGNED_32BIT(-Z_LVAL_P(Z_ZV(op2_addr)))) {
|
||||||
|
|
39
ext/opcache/tests/jit/gh12382.phpt
Normal file
39
ext/opcache/tests/jit/gh12382.phpt
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
--TEST--
|
||||||
|
GH-12382: JIT Index invalid or out of range error
|
||||||
|
--INI--
|
||||||
|
opcache.enable=1
|
||||||
|
opcache.enable_cli=1
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
function applyMaskPenaltyRule3(SplFixedArray $array) : void
|
||||||
|
{
|
||||||
|
for ($y = 0; $y < 21; ++$y) {
|
||||||
|
for ($x = 0; $x < 21; ++$x) {
|
||||||
|
if (
|
||||||
|
(
|
||||||
|
$x + 10 < 21
|
||||||
|
&& 0 === $array[$y][$x + 7]
|
||||||
|
)
|
||||||
|
|| (
|
||||||
|
$x - 4 >= 0
|
||||||
|
&& 0 === $array[$y][$x - 1]
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$matrix = SplFixedArray::fromArray(
|
||||||
|
array_map(
|
||||||
|
fn (array $arr): SplFixedArray => SplFixedArray::fromArray($arr),
|
||||||
|
[[1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, ], [1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, ], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ], [0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, ], [0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, ], [0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, ], [1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, ], [1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, ], [0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, ], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, ], [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, ], [1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, ], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, ], [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, ], ]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
applyMaskPenaltyRule3($matrix);
|
||||||
|
applyMaskPenaltyRule3($matrix);
|
||||||
|
?>
|
||||||
|
DONE
|
||||||
|
--EXPECT--
|
||||||
|
DONE
|
Loading…
Add table
Add a link
Reference in a new issue