@@ -4978,6 +4978,8 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4978
4978
| bls &exit_addr
4979
4979
} else if (type == BP_VAR_IS && not_found_exit_addr) {
4980
4980
| bls ¬_found_exit_addr
4981
+ } else if (type == BP_VAR_RW && not_found_exit_addr) {
4982
+ | bls ¬_found_exit_addr
4981
4983
} else if (type == BP_VAR_IS && found_exit_addr) {
4982
4984
| bls >7 // NOT_FOUND
4983
4985
} else {
@@ -5100,7 +5102,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5100
5102
break;
5101
5103
case BP_VAR_RW:
5102
5104
if (packed_loaded) {
5103
- | IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
5105
+ if (not_found_exit_addr) {
5106
+ |.cold_code
5107
+ } else {
5108
+ | IF_NOT_Z_TYPE REG0, IS_UNDEF, >8, TMP1w
5109
+ }
5104
5110
}
5105
5111
|2:
5106
5112
|4:
@@ -5112,6 +5118,17 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5112
5118
| EXT_CALL zend_jit_hash_index_lookup_rw, REG0
5113
5119
| mov REG0, RETVALx
5114
5120
| cbz REG0, >9
5121
+ if (not_found_exit_addr) {
5122
+ if (packed_loaded) {
5123
+ | cbnz REG0, >8
5124
+ | b ¬_found_exit_addr
5125
+ |.code
5126
+ } else {
5127
+ | cbz REG0, ¬_found_exit_addr
5128
+ }
5129
+ } else {
5130
+ | cbz REG0, >9
5131
+ }
5115
5132
break;
5116
5133
case BP_VAR_W:
5117
5134
if (packed_loaded) {
@@ -5921,6 +5938,8 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, uint32_t
5921
5938
static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint32_t op1_info, uint32_t op1_def_info, zend_jit_addr op1_addr, uint32_t op2_info, uint32_t op1_data_info, zend_ssa_range *op1_data_range, uint8_t dim_type, int may_throw)
5922
5939
{
5923
5940
zend_jit_addr op2_addr, op3_addr, var_addr;
5941
+ const void *not_found_exit_addr = NULL;
5942
+ uint32_t var_info = MAY_BE_NULL;
5924
5943
5925
5944
ZEND_ASSERT(opline->result_type == IS_UNUSED);
5926
5945
@@ -5993,7 +6012,6 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
5993
6012
}
5994
6013
5995
6014
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
5996
- uint32_t var_info;
5997
6015
uint32_t var_def_info = zend_array_element_type(op1_def_info, opline->op1_type, 1, 0);
5998
6016
5999
6017
|6:
@@ -6022,12 +6040,25 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
6022
6040
var_info |= MAY_BE_RC1;
6023
6041
}
6024
6042
6025
- if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, NULL, NULL)) {
6043
+ if (dim_type != IS_UNKNOWN
6044
+ && dim_type != IS_UNDEF
6045
+ && (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY
6046
+ && (op2_info & (MAY_BE_LONG|MAY_BE_STRING))
6047
+ && !(op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING)))) {
6048
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, 0);
6049
+ not_found_exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6050
+ }
6051
+
6052
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, dim_type, NULL, not_found_exit_addr, NULL)) {
6026
6053
return 0;
6027
6054
}
6028
6055
6029
6056
|8:
6030
- if (op1_info & (MAY_BE_ARRAY_OF_REF)) {
6057
+ if (not_found_exit_addr && dim_type != IS_REFERENCE) {
6058
+ | IF_NOT_Z_TYPE, REG0, dim_type, ¬_found_exit_addr, TMP1w
6059
+ var_info = (1 << dim_type) | (var_info & ~(MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF));
6060
+ }
6061
+ if (var_info & MAY_BE_REF) {
6031
6062
binary_op_type binary_op = get_binary_op(opline->extended_value);
6032
6063
| IF_NOT_Z_TYPE, REG0, IS_REFERENCE, >1, TMP1w
6033
6064
| GET_Z_PTR FCARG1x, REG0
@@ -6120,7 +6151,8 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, uint3
6120
6151
|.code
6121
6152
|9:
6122
6153
}
6123
- } else if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY)) {
6154
+ } else if ((op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_ARRAY))
6155
+ && (!not_found_exit_addr || (var_info & MAY_BE_REF))) {
6124
6156
|.cold_code
6125
6157
|9:
6126
6158
| FREE_OP (opline+1)->op1_type, (opline+1)->op1, op1_data_info, 0, opline, ZREG_TMP1, ZREG_TMP2
0 commit comments