@@ -422,8 +422,14 @@ static void* dasm_labels[zend_lb_MAX];
422
422
|| }
423
423
|.endmacro
424
424
425
- |.macro CMP_IP, addr
426
- | brk #0 // TODO
425
+ |.macro CMP_IP, addr, tmp_reg1, tmp_reg2
426
+ | LOAD_ADDR tmp_reg1, addr
427
+ || if (GCC_GLOBAL_REGS) {
428
+ | cmp IP, tmp_reg1
429
+ || } else {
430
+ | ldr tmp_reg2, EX->opline
431
+ | cmp tmp_reg2, tmp_reg1
432
+ || }
427
433
|.endmacro
428
434
429
435
|.macro LOAD_ZVAL_ADDR, reg, addr
@@ -1128,8 +1134,24 @@ static void* dasm_labels[zend_lb_MAX];
1128
1134
| brk #0 // TODO
1129
1135
|.endmacro
1130
1136
1131
- |.macro OBJ_RELEASE, reg, exit_label
1137
+ |.macro OBJ_RELEASE, reg, exit_label, tmp_reg1, tmp_reg2
1138
+ | GC_DELREF Rx(reg), Rw(tmp_reg1)
1139
+ | bne >1
1132
1140
| brk #0 // TODO
1141
+ | // zend_objects_store_del(obj);
1142
+ || if (reg != ZREG_FCARG1x) {
1143
+ | mov FCARG1x, Rx(reg)
1144
+ || }
1145
+ | EXT_CALL zend_objects_store_del, Rx(tmp_reg1)
1146
+ | b exit_label
1147
+ |1:
1148
+ | IF_GC_MAY_NOT_LEAK Rx(reg), >1, Rw(tmp_reg1), Rw(tmp_reg2)
1149
+ | // gc_possible_root(obj)
1150
+ || if (reg != ZREG_FCARG1x) {
1151
+ | mov FCARG1x, Rx(reg)
1152
+ || }
1153
+ | EXT_CALL gc_possible_root, Rx(tmp_reg1)
1154
+ |1:
1133
1155
|.endmacro
1134
1156
1135
1157
|.macro UNDEFINED_OFFSET, opline
@@ -2068,7 +2090,6 @@ static int zend_jit_save_call_chain(dasm_State **Dst, uint32_t call_level)
2068
2090
if (call_level == 1) {
2069
2091
| str xzr, EX:RX->prev_execute_data
2070
2092
} else {
2071
- | brk #0 // TODO: test
2072
2093
| ldr REG0, EX->call
2073
2094
| str REG0, EX:RX->prev_execute_data
2074
2095
}
@@ -2430,7 +2451,8 @@ static int zend_jit_jmp(dasm_State **Dst, unsigned int target_label)
2430
2451
2431
2452
static int zend_jit_cond_jmp(dasm_State **Dst, const zend_op *next_opline, unsigned int target_label)
2432
2453
{
2433
- | brk #0 // TODO
2454
+ | CMP_IP next_opline, TMP1, TMP2
2455
+ | bne =>target_label
2434
2456
2435
2457
zend_jit_set_last_valid_opline(next_opline);
2436
2458
@@ -4799,15 +4821,26 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
4799
4821
| SET_EX_OPLINE opline, REG0
4800
4822
4801
4823
if (opline->opcode == ZEND_DO_FCALL) {
4802
- | brk #0 // TODO
4824
+ if (!func) {
4825
+ if (trace) {
4826
+ uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
4827
+
4828
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
4829
+ if (!exit_addr) {
4830
+ return 0;
4831
+ }
4832
+ | brk #0 // TODO
4833
+ }
4834
+ }
4803
4835
}
4804
4836
4805
4837
if (!delayed_call_chain) {
4806
4838
if (call_level == 1) {
4807
4839
| str xzr, EX->call
4808
4840
} else {
4809
4841
| //EX(call) = call->prev_execute_data;
4810
- | brk #0 // TODO: test
4842
+ | ldr REG0, EX:RX->prev_execute_data
4843
+ | str REG0, EX->call
4811
4844
}
4812
4845
}
4813
4846
delayed_call_chain = 0;
@@ -4820,13 +4853,38 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
4820
4853
}
4821
4854
4822
4855
if (opline->opcode == ZEND_DO_FCALL) {
4823
- | brk #0 // TODO
4856
+ if (!func) {
4857
+ if (!trace) {
4858
+ | ldr TMP1w, [REG0, #offsetof(zend_op_array, fn_flags)]
4859
+ || ZEND_ASSERT(ZEND_ACC_DEPRECATED <= MAX_IMM12);
4860
+ | tst TMP1w, #ZEND_ACC_DEPRECATED
4861
+ | bne >1
4862
+ |.cold_code
4863
+ |1:
4864
+ | brk #0 // TODO
4865
+ if (!GCC_GLOBAL_REGS) {
4866
+ | mov FCARG1x, RX
4867
+ }
4868
+ | EXT_CALL zend_jit_deprecated_helper, REG0
4869
+ | and RETVALw, RETVALw, #0xff
4870
+ | cmp RETVALw, #0 // Result is 0 on exception
4871
+ | ldr REG0, EX:RX->func // reload
4872
+ | bne >1
4873
+ | b ->exception_handler
4874
+ |.code
4875
+ |1:
4876
+ }
4877
+ } else if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
4878
+ | brk #0
4879
+ }
4824
4880
}
4825
4881
4826
4882
if (!func
4827
4883
&& opline->opcode != ZEND_DO_UCALL
4828
4884
&& opline->opcode != ZEND_DO_ICALL) {
4829
- | brk #0 // TODO
4885
+ | ldrb TMP1w, [REG0, #offsetof(zend_function, type)]
4886
+ | cmp TMP1w, #ZEND_USER_FUNCTION
4887
+ | bne >8
4830
4888
}
4831
4889
4832
4890
if ((!func || func->type == ZEND_USER_FUNCTION)
@@ -5022,7 +5080,19 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5022
5080
|8:
5023
5081
if (opline->opcode == ZEND_DO_FCALL) {
5024
5082
// TODO: optimize ???
5025
- | brk #0 // TODO
5083
+ | // if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS))
5084
+ | ldrb TMP1w, [RX, #(offsetof(zend_execute_data, This.u1.type_info) + 2)]
5085
+ | tst TMP1w, #(ZEND_CALL_RELEASE_THIS >> 16)
5086
+ | bne >1
5087
+ |.cold_code
5088
+ |1:
5089
+ | add TMP1, RX, #offsetof(zend_execute_data, This)
5090
+ | GET_Z_PTR FCARG1x, TMP1
5091
+ | // OBJ_RELEASE(object);
5092
+ | OBJ_RELEASE ZREG_FCARG1x, >2, ZREG_TMP1, ZREG_TMP2
5093
+ | b >2
5094
+ |.code
5095
+ |2:
5026
5096
}
5027
5097
5028
5098
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE ||
@@ -5084,7 +5154,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5084
5154
}
5085
5155
5086
5156
if ((!trace || !func) && opline->opcode != ZEND_DO_ICALL) {
5087
- | brk #0 // TODO
5157
+ | LOAD_IP_ADDR (opline + 1)
5088
5158
} else if (trace
5089
5159
&& trace->op == ZEND_JIT_TRACE_END
5090
5160
&& trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {
0 commit comments