@@ -4784,7 +4784,7 @@ static int zend_jit_concat(dasm_State **Dst, const zend_op *opline, const zend_o
4784
4784
return zend_jit_concat_helper(Dst, opline, op_array, opline->op1_type, opline->op1, op1_addr, op1_info, opline->op2_type, opline->op2, op2_addr, op2_info, res_addr, res_info, may_throw);
4785
4785
}
4786
4786
4787
- static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_op *opline, uint32_t type, uint32_t op1_info, uint32_t op2_info, uint32_t found, uint32_t not_found)
4787
+ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_op *opline, uint32_t type, uint32_t op1_info, uint32_t op2_info, uint32_t found, uint32_t not_found, const void *found_exit_addr, const void *not_found_exit_addr )
4788
4788
/* Labels: 1,2,3,4,5 */
4789
4789
{
4790
4790
zend_jit_addr op2_addr = OP2_ADDR();
@@ -4827,7 +4827,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4827
4827
| cmp dword [FCARG1a + offsetof(zend_array, nNumUsed)], val
4828
4828
|.endif
4829
4829
if (type == BP_JIT_IS) {
4830
- | jbe >9 // NOT_FOUND
4830
+ if (not_found_exit_addr) {
4831
+ | jbe ¬_found_exit_addr
4832
+ } else {
4833
+ | jbe >9 // NOT_FOUND
4834
+ }
4831
4835
} else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && (type == BP_VAR_R || type == BP_VAR_RW)) {
4832
4836
| jbe &exit_addr
4833
4837
} else {
@@ -4860,7 +4864,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4860
4864
| cmp dword [FCARG1a + offsetof(zend_array, nNumUsed)], FCARG2a
4861
4865
|.endif
4862
4866
if (type == BP_JIT_IS) {
4863
- | jbe >9 // NOT_FOUND
4867
+ if (not_found_exit_addr) {
4868
+ | jbe ¬_found_exit_addr
4869
+ } else {
4870
+ | jbe >9 // NOT_FOUND
4871
+ }
4864
4872
} else if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE && (type == BP_VAR_R || type == BP_VAR_RW)) {
4865
4873
| jbe &exit_addr
4866
4874
} else {
@@ -4892,7 +4900,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
4892
4900
}
4893
4901
| EXT_CALL _zend_hash_index_find, r0
4894
4902
| test r0, r0
4895
- | jz >9 // NOT_FOUND
4903
+ if (not_found_exit_addr) {
4904
+ | jz ¬_found_exit_addr
4905
+ } else {
4906
+ | jz >9 // NOT_FOUND
4907
+ }
4896
4908
if (op2_info & MAY_BE_STRING) {
4897
4909
| jmp >5
4898
4910
}
@@ -5020,7 +5032,11 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5020
5032
| EXT_CALL _zend_hash_find_known_hash, r0
5021
5033
}
5022
5034
| test r0, r0
5023
- | jz >9 // NOT_FOUND
5035
+ if (not_found_exit_addr) {
5036
+ | jz ¬_found_exit_addr
5037
+ } else {
5038
+ | jz >9 // NOT_FOUND
5039
+ }
5024
5040
| // if (UNEXPECTED(Z_TYPE_P(retval) == IS_INDIRECT))
5025
5041
| IF_NOT_Z_TYPE r0, IS_INDIRECT, >1
5026
5042
| GET_Z_PTR r0, r0
@@ -5101,7 +5117,13 @@ static int zend_jit_fetch_dimension_address_inner(dasm_State **Dst, const zend_o
5101
5117
| ZVAL_DEREF r0, MAY_BE_REF
5102
5118
}
5103
5119
| cmp byte [r0 + 8], IS_NULL
5104
- | jle >9 // NOT FOUND
5120
+ if (not_found_exit_addr) {
5121
+ | jle ¬_found_exit_addr
5122
+ } else if (found_exit_addr) {
5123
+ | jg &found_exit_addr
5124
+ } else {
5125
+ | jle >9 // NOT FOUND
5126
+ }
5105
5127
}
5106
5128
5107
5129
if (op2_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - (MAY_BE_LONG|MAY_BE_STRING))) {
@@ -5534,7 +5556,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, const ze
5534
5556
uint32_t var_info = zend_array_element_type(op1_info, 0, 0);
5535
5557
zend_jit_addr var_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
5536
5558
5537
- if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, 8, 8)) {
5559
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_W, op1_info, op2_info, 8, 8, NULL, NULL )) {
5538
5560
return 0;
5539
5561
}
5540
5562
@@ -5755,7 +5777,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, const
5755
5777
var_info |= MAY_BE_REF;
5756
5778
}
5757
5779
5758
- if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, 8, 8)) {
5780
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_VAR_RW, op1_info, op2_info, 8, 8, NULL, NULL )) {
5759
5781
return 0;
5760
5782
}
5761
5783
@@ -10170,7 +10192,7 @@ static int zend_jit_fetch_dim_read(dasm_State **Dst, const zend_op *opline, cons
10170
10192
}
10171
10193
}
10172
10194
| GET_ZVAL_LVAL ZREG_FCARG1a, op1_addr
10173
- if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, 8, 9)) {
10195
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, (opline->opcode != ZEND_FETCH_DIM_IS) ? BP_VAR_R : BP_VAR_IS, op1_info, op2_info, 8, 9, NULL, NULL )) {
10174
10196
return 0;
10175
10197
}
10176
10198
}
@@ -10352,13 +10374,35 @@ static int zend_jit_isset_isempty_dim(dasm_State **Dst, const zend_op *opline, c
10352
10374
}
10353
10375
10354
10376
if (op1_info & MAY_BE_ARRAY) {
10377
+ const void *found_exit_addr = NULL;
10378
+ const void *not_found_exit_addr = NULL;
10379
+
10355
10380
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
10356
10381
| IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7
10357
10382
}
10358
10383
| GET_ZVAL_LVAL ZREG_FCARG1a, op1_addr
10359
- if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_JIT_IS, op1_info, op2_info, 8, 9)) {
10384
+ if (exit_addr
10385
+ && !(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY))
10386
+ && !may_throw
10387
+ && !(opline->op1_type & (IS_TMP_VAR|IS_VAR))
10388
+ && (!(opline->op2_type & (IS_TMP_VAR|IS_VAR)) || !(op2_info & MAY_BE_LONG))) {
10389
+ if (smart_branch_opcode == ZEND_JMPNZ) {
10390
+ found_exit_addr = exit_addr;
10391
+ } else {
10392
+ not_found_exit_addr = exit_addr;
10393
+ }
10394
+ }
10395
+ if (!zend_jit_fetch_dimension_address_inner(Dst, opline, BP_JIT_IS, op1_info, op2_info, 8, 9, found_exit_addr, not_found_exit_addr)) {
10360
10396
return 0;
10361
10397
}
10398
+
10399
+ if (found_exit_addr) {
10400
+ |9:
10401
+ return 1;
10402
+ } else if (not_found_exit_addr) {
10403
+ |8:
10404
+ return 1;
10405
+ }
10362
10406
}
10363
10407
10364
10408
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-MAY_BE_ARRAY)) {
0 commit comments