@@ -453,7 +453,7 @@ static void* dasm_labels[zend_lb_MAX];
453
453
|.endmacro
454
454
455
455
|.macro GET_Z_TYPE_INFO, reg, zv
456
- | mov reg, dword [zv+ offsetof(zval,u1.type_info)]
456
+ | ldr reg, [zv, # offsetof(zval,u1.type_info)]
457
457
|.endmacro
458
458
459
459
|.macro SET_Z_TYPE_INFO, zv, type, tmp_reg
@@ -826,7 +826,8 @@ static void* dasm_labels[zend_lb_MAX];
826
826
|.endmacro
827
827
828
828
|.macro IF_UNDEF, type_reg, label
829
- | brk #0 // TODO
829
+ | tst type_reg, type_reg
830
+ | beq label
830
831
|.endmacro
831
832
832
833
|.macro IF_TYPE, type, val, label
@@ -1031,7 +1032,6 @@ static void* dasm_labels[zend_lb_MAX];
1031
1032
|.cold_code
1032
1033
|1:
1033
1034
|| } else {
1034
- | brk #0 // TODO: test.
1035
1035
| IF_NOT_ZVAL_REFCOUNTED addr, >4, Rw(tmp_reg1), Rx(tmp_reg2)
1036
1036
|| }
1037
1037
|| }
@@ -1338,7 +1338,35 @@ static int zend_jit_exception_handler_undef_stub(dasm_State **Dst)
1338
1338
static int zend_jit_leave_function_stub(dasm_State **Dst)
1339
1339
{
1340
1340
|->leave_function_handler:
1341
- | brk #0 // TODO: test
1341
+ if (zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
1342
+ | LOAD_32BIT_VAL TMP1w, ZEND_CALL_TOP
1343
+ | tst FCARG1w, TMP1w
1344
+ | bne >1
1345
+ | brk #0 // TODO: currently jump to label 1.
1346
+ | EXT_CALL zend_jit_leave_nested_func_helper, REG0
1347
+ | ADD_HYBRID_SPAD
1348
+ | JMP_IP TMP1
1349
+ |1:
1350
+ | EXT_CALL zend_jit_leave_top_func_helper, REG0
1351
+ | ADD_HYBRID_SPAD
1352
+ | JMP_IP TMP1
1353
+ } else {
1354
+ if (GCC_GLOBAL_REGS) {
1355
+ | add sp, sp, SPAD
1356
+ } else {
1357
+ | mov FCARG2x, FP
1358
+ | ldp FP, RX, T2 // retore FP and IP
1359
+ | ldr LR, T4 // retore LR
1360
+ | add sp, sp, NR_SPAD
1361
+ }
1362
+ | LOAD_32BIT_VAL TMP1w, ZEND_CALL_TOP
1363
+ | tst FCARG1w, TMP1w
1364
+ | bne >1
1365
+ | brk #0 // TODO: currently jump to label 1.
1366
+ | EXT_JMP zend_jit_leave_nested_func_helper, REG0
1367
+ |1:
1368
+ | EXT_JMP zend_jit_leave_top_func_helper, REG0
1369
+ }
1342
1370
1343
1371
return 1;
1344
1372
}
@@ -6193,7 +6221,23 @@ static int zend_jit_zval_copy_deref(dasm_State **Dst, zend_jit_addr res_addr, ze
6193
6221
{
6194
6222
ZEND_ASSERT(type_reg == ZREG_REG2);
6195
6223
6196
- | brk #0 // TODO
6224
+ | GET_ZVAL_PTR REG1, val_addr, TMP1
6225
+ | lsr TMP1w, REG2w, #8
6226
+ | and TMP1w, TMP1w, #0xff // TMP1w -> 8-15 bits of REG2w
6227
+ | IF_NOT_REFCOUNTED TMP1w, >2
6228
+ | brk #0 // TODO: currently jump to label 2 directly.
6229
+ | and TMP2w, REG2w, #0xff // TMP2w -> low 8 bits of REG2w
6230
+ | IF_NOT_TYPE TMP2w, IS_REFERENCE, >1
6231
+ | add TMP3, REG1, #offsetof(zend_reference, val)
6232
+ | GET_Z_TYPE_INFO REG2w, TMP3
6233
+ | GET_Z_PTR REG1, TMP3
6234
+ | IF_NOT_REFCOUNTED TMP1w, >2
6235
+ |1:
6236
+ | GC_ADDREF REG1, TMP1w
6237
+ |2:
6238
+ | SET_ZVAL_PTR res_addr, REG1, TMP1
6239
+ | SET_ZVAL_TYPE_INFO_FROM_REG res_addr, REG2, TMP1
6240
+
6197
6241
return 1;
6198
6242
}
6199
6243
@@ -6899,7 +6943,30 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
6899
6943
}
6900
6944
} else {
6901
6945
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, prop_info->offset);
6902
- | brk #0 // TODO
6946
+ | LOAD_32BIT_VAL TMP1w, (prop_info->offset + 8)
6947
+ | ldr REG2w, [FCARG1x, TMP1]
6948
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6949
+ if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
6950
+ /* perform IS_UNDEF check only after result type guard (during deoptimization) */
6951
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
6952
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6953
+
6954
+ if (!exit_addr) {
6955
+ return 0;
6956
+ }
6957
+ | brk #0 // TODO
6958
+ }
6959
+ } else {
6960
+ | and TMP1w, REG2w, #0xff // low 8 bits. 8-15 bits are used later in zend_jit_zval_copy_deref().
6961
+ | IF_UNDEF TMP1w, >5
6962
+ }
6963
+ if (opline->opcode == ZEND_FETCH_OBJ_W
6964
+ && (opline->extended_value & ZEND_FETCH_OBJ_FLAGS)
6965
+ && ZEND_TYPE_IS_SET(prop_info->type)) {
6966
+ uint32_t flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS;
6967
+
6968
+ | brk #0 // TODO
6969
+ }
6903
6970
}
6904
6971
if (op1_avoid_refcounting) {
6905
6972
SET_STACK_REG(JIT_G(current_frame)->stack,
@@ -7266,7 +7333,32 @@ static int zend_jit_free(dasm_State **Dst, const zend_op *opline, uint32_t op1_i
7266
7333
{
7267
7334
zend_jit_addr op1_addr = OP1_ADDR();
7268
7335
7269
- | brk #0 // TODO
7336
+ if (op1_info & (MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF)) {
7337
+ if (may_throw) {
7338
+ | brk #0 // TODO
7339
+ | SET_EX_OPLINE opline, REG0
7340
+ }
7341
+ if (opline->opcode == ZEND_FE_FREE && (op1_info & (MAY_BE_OBJECT|MAY_BE_REF))) {
7342
+ if (op1_info & MAY_BE_ARRAY) {
7343
+ | brk #0 // TODO
7344
+ | IF_ZVAL_TYPE op1_addr, IS_ARRAY, >7, TMP1w, TMP2
7345
+ }
7346
+ | brk #0 // TODO
7347
+ | LOAD_32BIT_VAL TMP1w, opline->op1.var + offsetof(zval, u2.fe_iter_idx)
7348
+ | ldr FCARG1w, [FP, TMP1]
7349
+ | LOAD_32BIT_VAL TMP1w, -1
7350
+ | cmp FCARG1w, TMP1w
7351
+ | beq >7
7352
+ | EXT_CALL zend_hash_iterator_del, REG0
7353
+ |7:
7354
+ }
7355
+ | ZVAL_PTR_DTOR op1_addr, op1_info, 0, 0, opline, ZREG_TMP1, ZREG_TMP2
7356
+ if (may_throw) {
7357
+ if (!zend_jit_check_exception(Dst)) {
7358
+ return 0;
7359
+ }
7360
+ }
7361
+ }
7270
7362
return 1;
7271
7363
}
7272
7364
0 commit comments