Skip to content

Commit b9a6ec2

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: Check whether expected types are present for compound op jit
2 parents 679bfb1 + bac054d commit b9a6ec2

File tree

3 files changed

+56
-71
lines changed

3 files changed

+56
-71
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2647,6 +2647,31 @@ static bool zend_jit_next_is_send_result(const zend_op *opline)
26472647
return 0;
26482648
}
26492649

2650+
static bool zend_jit_supported_binary_op(zend_uchar op, uint32_t op1_info, uint32_t op2_info)
2651+
{
2652+
switch (op) {
2653+
case ZEND_POW:
2654+
case ZEND_DIV:
2655+
// TODO: check for division by zero ???
2656+
return false;
2657+
case ZEND_ADD:
2658+
case ZEND_SUB:
2659+
case ZEND_MUL:
2660+
return (op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE))
2661+
&& (op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE));
2662+
case ZEND_BW_OR:
2663+
case ZEND_BW_AND:
2664+
case ZEND_BW_XOR:
2665+
case ZEND_SL:
2666+
case ZEND_SR:
2667+
case ZEND_MOD:
2668+
return (op1_info & MAY_BE_LONG) && (op2_info & MAY_BE_LONG);
2669+
case ZEND_CONCAT:
2670+
return (op1_info & MAY_BE_STRING) && (op2_info & MAY_BE_STRING);
2671+
EMPTY_SWITCH_DEFAULT_CASE()
2672+
}
2673+
}
2674+
26502675
static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op *rt_opline)
26512676
{
26522677
int b, i, end;
@@ -3058,11 +3083,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
30583083
}
30593084
goto done;
30603085
case ZEND_ASSIGN_OP:
3061-
if (opline->extended_value == ZEND_POW
3062-
|| opline->extended_value == ZEND_DIV) {
3063-
// TODO: check for division by zero ???
3064-
break;
3065-
}
30663086
if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) {
30673087
break;
30683088
}
@@ -3074,29 +3094,9 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
30743094
if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
30753095
break;
30763096
}
3077-
if (opline->extended_value == ZEND_ADD
3078-
|| opline->extended_value == ZEND_SUB
3079-
|| opline->extended_value == ZEND_MUL
3080-
|| opline->extended_value == ZEND_DIV) {
3081-
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE))
3082-
|| !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
3083-
break;
3084-
}
3085-
} else if (opline->extended_value == ZEND_BW_OR
3086-
|| opline->extended_value == ZEND_BW_AND
3087-
|| opline->extended_value == ZEND_BW_XOR
3088-
|| opline->extended_value == ZEND_SL
3089-
|| opline->extended_value == ZEND_SR
3090-
|| opline->extended_value == ZEND_MOD) {
3091-
if (!(op1_info & MAY_BE_LONG)
3092-
|| !(op2_info & MAY_BE_LONG)) {
3093-
break;
3094-
}
3095-
} else if (opline->extended_value == ZEND_CONCAT) {
3096-
if (!(op1_info & MAY_BE_STRING)
3097-
|| !(op2_info & MAY_BE_STRING)) {
3098-
break;
3099-
}
3097+
if (!zend_jit_supported_binary_op(
3098+
opline->extended_value, op1_info, op2_info)) {
3099+
break;
31003100
}
31013101
op1_def_info = OP1_DEF_INFO();
31023102
if (!zend_jit_assign_op(&dasm_state, opline,
@@ -3108,17 +3108,16 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
31083108
}
31093109
goto done;
31103110
case ZEND_ASSIGN_DIM_OP:
3111-
if (opline->extended_value == ZEND_POW
3112-
|| opline->extended_value == ZEND_DIV) {
3113-
// TODO: check for division by zero ???
3114-
break;
3115-
}
31163111
if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) {
31173112
break;
31183113
}
31193114
if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) {
31203115
break;
31213116
}
3117+
if (!zend_jit_supported_binary_op(
3118+
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
3119+
break;
3120+
}
31223121
if (!zend_jit_assign_dim_op(&dasm_state, opline,
31233122
OP1_INFO(), OP1_DEF_INFO(), OP1_REG_ADDR(), OP2_INFO(),
31243123
OP1_DATA_INFO(), OP1_DATA_RANGE(),
@@ -3183,11 +3182,6 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
31833182
}
31843183
goto done;
31853184
case ZEND_ASSIGN_OBJ_OP:
3186-
if (opline->extended_value == ZEND_POW
3187-
|| opline->extended_value == ZEND_DIV) {
3188-
// TODO: check for division by zero ???
3189-
break;
3190-
}
31913185
if (opline->result_type != IS_UNUSED) {
31923186
break;
31933187
}
@@ -3199,6 +3193,10 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
31993193
if (PROFITABILITY_CHECKS && (!ssa->ops || !ssa->var_info)) {
32003194
break;
32013195
}
3196+
if (!zend_jit_supported_binary_op(
3197+
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
3198+
break;
3199+
}
32023200
ce = NULL;
32033201
ce_is_instanceof = 0;
32043202
if (opline->op1_type == IS_UNUSED) {

ext/opcache/jit/zend_jit_trace.c

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4316,11 +4316,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43164316
}
43174317
goto done;
43184318
case ZEND_ASSIGN_OP:
4319-
if (opline->extended_value == ZEND_POW
4320-
|| opline->extended_value == ZEND_DIV) {
4321-
// TODO: check for division by zero ???
4322-
break;
4323-
}
43244319
if (opline->op1_type != IS_CV || opline->result_type != IS_UNUSED) {
43254320
break;
43264321
}
@@ -4331,29 +4326,9 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43314326
if ((op1_info & MAY_BE_UNDEF) || (op2_info & MAY_BE_UNDEF)) {
43324327
break;
43334328
}
4334-
if (opline->extended_value == ZEND_ADD
4335-
|| opline->extended_value == ZEND_SUB
4336-
|| opline->extended_value == ZEND_MUL
4337-
|| opline->extended_value == ZEND_DIV) {
4338-
if (!(op1_info & (MAY_BE_LONG|MAY_BE_DOUBLE))
4339-
|| !(op2_info & (MAY_BE_LONG|MAY_BE_DOUBLE))) {
4340-
break;
4341-
}
4342-
} else if (opline->extended_value == ZEND_BW_OR
4343-
|| opline->extended_value == ZEND_BW_AND
4344-
|| opline->extended_value == ZEND_BW_XOR
4345-
|| opline->extended_value == ZEND_SL
4346-
|| opline->extended_value == ZEND_SR
4347-
|| opline->extended_value == ZEND_MOD) {
4348-
if (!(op1_info & MAY_BE_LONG)
4349-
|| !(op2_info & MAY_BE_LONG)) {
4350-
break;
4351-
}
4352-
} else if (opline->extended_value == ZEND_CONCAT) {
4353-
if (!(op1_info & MAY_BE_STRING)
4354-
|| !(op2_info & MAY_BE_STRING)) {
4355-
break;
4356-
}
4329+
if (!zend_jit_supported_binary_op(
4330+
opline->extended_value, op1_info, op2_info)) {
4331+
break;
43574332
}
43584333
op1_def_info = OP1_DEF_INFO();
43594334
if (op1_def_info & MAY_BE_GUARD
@@ -4383,6 +4358,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
43834358
if (opline->result_type != IS_UNUSED) {
43844359
break;
43854360
}
4361+
if (!zend_jit_supported_binary_op(
4362+
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
4363+
break;
4364+
}
43864365
op1_info = OP1_INFO();
43874366
op1_addr = OP1_REG_ADDR();
43884367
if (opline->op1_type == IS_VAR) {
@@ -4489,11 +4468,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
44894468
}
44904469
goto done;
44914470
case ZEND_ASSIGN_OBJ_OP:
4492-
if (opline->extended_value == ZEND_POW
4493-
|| opline->extended_value == ZEND_DIV) {
4494-
// TODO: check for division by zero ???
4495-
break;
4496-
}
44974471
if (opline->result_type != IS_UNUSED) {
44984472
break;
44994473
}
@@ -4502,6 +4476,10 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
45024476
|| Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
45034477
break;
45044478
}
4479+
if (!zend_jit_supported_binary_op(
4480+
opline->extended_value, MAY_BE_ANY, OP1_DATA_INFO())) {
4481+
break;
4482+
}
45054483
ce = NULL;
45064484
ce_is_instanceof = 0;
45074485
delayed_fetch_this = 0;

ext/opcache/tests/jit/assign_dim_op_001.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ function false_to_array_nested_invalid_index($a) {
4141
$a[[]][0] += 1;
4242
return $a;
4343
}
44+
function modulo_string($a) {
45+
$a[] %= "";
46+
}
4447

4548
false_to_array(false);
4649
false_to_array_append(false);
@@ -56,6 +59,11 @@ try {
5659
} catch (Error $e) {
5760
echo $e->getMessage(), "\n";
5861
}
62+
try {
63+
var_dump(modulo_string([]));
64+
} catch (TypeError $e) {
65+
echo $e->getMessage(), "\n";
66+
}
5967

6068
?>
6169
--EXPECTF--
@@ -97,3 +105,4 @@ array(1) {
97105

98106
Deprecated: Automatic conversion of false to array is deprecated in %s on line %d
99107
Illegal offset type
108+
Unsupported operand types: null % string

0 commit comments

Comments
 (0)