@@ -9886,11 +9886,22 @@ static int zend_jit_return(dasm_State **Dst, const zend_op *opline, const zend_o
9886
9886
static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, uint32_t op2_info, uint32_t res_info, int may_throw)
9887
9887
{
9888
9888
zend_jit_addr op1_addr, orig_op1_addr, op2_addr, res_addr;
9889
+ const void *exit_addr = NULL;
9889
9890
9890
9891
op1_addr = orig_op1_addr = OP1_ADDR();
9891
9892
op2_addr = OP2_ADDR();
9892
9893
res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
9893
9894
9895
+ if (opline->opcode != ZEND_FETCH_DIM_IS
9896
+ && JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE
9897
+ && (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_OBJECT)))) {
9898
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM);
9899
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
9900
+ if (!exit_addr) {
9901
+ return 0;
9902
+ }
9903
+ }
9904
+
9894
9905
if (op1_info & MAY_BE_REF) {
9895
9906
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
9896
9907
| ZVAL_DEREF FCARG1a, op1_info
@@ -9899,7 +9910,11 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, cons
9899
9910
9900
9911
if (op1_info & MAY_BE_ARRAY) {
9901
9912
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
9902
- | IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7
9913
+ if (exit_addr && !(op1_info & (MAY_BE_OBJECT|MAY_BE_STRING))) {
9914
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, &exit_addr
9915
+ } else {
9916
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7
9917
+ }
9903
9918
}
9904
9919
| GET_ZVAL_LVAL ZREG_FCARG1a, op1_addr
9905
9920
if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode == ZEND_FETCH_DIM_R) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, 8, 9)) {
@@ -9915,7 +9930,11 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, cons
9915
9930
9916
9931
if (op1_info & MAY_BE_STRING) {
9917
9932
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_STRING))) {
9918
- | IF_NOT_ZVAL_TYPE op1_addr, IS_STRING, >6
9933
+ if (exit_addr && !(op1_info & MAY_BE_OBJECT)) {
9934
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_STRING, &exit_addr
9935
+ } else {
9936
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_STRING, >6
9937
+ }
9919
9938
}
9920
9939
| SAVE_VALID_OPLINE opline, r0
9921
9940
if (Z_REG(op1_addr) != ZREG_FCARG1a) {
@@ -9947,7 +9966,11 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, cons
9947
9966
9948
9967
if (op1_info & MAY_BE_OBJECT) {
9949
9968
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_OBJECT))) {
9950
- | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >6
9969
+ if (exit_addr) {
9970
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, &exit_addr
9971
+ } else {
9972
+ | IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >6
9973
+ }
9951
9974
}
9952
9975
| SAVE_VALID_OPLINE opline, r0
9953
9976
if (Z_REG(op1_addr) != ZREG_FCARG1a) {
@@ -10000,15 +10023,24 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, cons
10000
10023
}
10001
10024
}
10002
10025
10003
- if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_OBJECT))) {
10026
+ if ((op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_ARRAY|MAY_BE_STRING|MAY_BE_OBJECT)))
10027
+ && !exit_addr) {
10004
10028
if (opline->opcode != ZEND_FETCH_DIM_IS) {
10005
- | SAVE_VALID_OPLINE opline, r0
10006
- | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
10029
+ if ((opline->opcode != ZEND_FETCH_DIM_IS && (op1_info & MAY_BE_UNDEF)) || (op2_info & MAY_BE_UNDEF)) {
10030
+ | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
10031
+ } else {
10032
+ | SAVE_VALID_OPLINE opline, r0
10033
+ if (Z_MODE(op1_addr) != IS_MEM_ZVAL ||
10034
+ Z_REG(op1_addr) != ZREG_FCARG1a ||
10035
+ Z_OFFSET(op1_addr) != 0) {
10036
+ | LOAD_ZVAL_ADDR FCARG1a, op1_addr
10037
+ }
10038
+ }
10007
10039
| EXT_CALL zend_jit_invalid_array_access, r0
10008
10040
}
10009
10041
| SET_ZVAL_TYPE_INFO res_addr, IS_NULL
10010
10042
if (op1_info & MAY_BE_ARRAY) {
10011
- | jmp >9 // END
10043
+ | jmp >9 // END
10012
10044
}
10013
10045
}
10014
10046
0 commit comments