@@ -422,8 +422,14 @@ static void* dasm_labels[zend_lb_MAX];
422422|| }
423423|.endmacro
424424
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+ || }
427433|.endmacro
428434
429435|.macro LOAD_ZVAL_ADDR, reg, addr
@@ -1128,8 +1134,24 @@ static void* dasm_labels[zend_lb_MAX];
11281134| brk #0 // TODO
11291135|.endmacro
11301136
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
11321140| 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:
11331155|.endmacro
11341156
11351157|.macro UNDEFINED_OFFSET, opline
@@ -2068,7 +2090,6 @@ static int zend_jit_save_call_chain(dasm_State **Dst, uint32_t call_level)
20682090 if (call_level == 1) {
20692091 | str xzr, EX:RX->prev_execute_data
20702092 } else {
2071- | brk #0 // TODO: test
20722093 | ldr REG0, EX->call
20732094 | str REG0, EX:RX->prev_execute_data
20742095 }
@@ -2430,7 +2451,8 @@ static int zend_jit_jmp(dasm_State **Dst, unsigned int target_label)
24302451
24312452static int zend_jit_cond_jmp(dasm_State **Dst, const zend_op *next_opline, unsigned int target_label)
24322453{
2433- | brk #0 // TODO
2454+ | CMP_IP next_opline, TMP1, TMP2
2455+ | bne =>target_label
24342456
24352457 zend_jit_set_last_valid_opline(next_opline);
24362458
@@ -4799,15 +4821,26 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
47994821 | SET_EX_OPLINE opline, REG0
48004822
48014823 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+ }
48034835 }
48044836
48054837 if (!delayed_call_chain) {
48064838 if (call_level == 1) {
48074839 | str xzr, EX->call
48084840 } else {
48094841 | //EX(call) = call->prev_execute_data;
4810- | brk #0 // TODO: test
4842+ | ldr REG0, EX:RX->prev_execute_data
4843+ | str REG0, EX->call
48114844 }
48124845 }
48134846 delayed_call_chain = 0;
@@ -4820,13 +4853,38 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
48204853 }
48214854
48224855 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+ }
48244880 }
48254881
48264882 if (!func
48274883 && opline->opcode != ZEND_DO_UCALL
48284884 && 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
48304888 }
48314889
48324890 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
50225080 |8:
50235081 if (opline->opcode == ZEND_DO_FCALL) {
50245082 // 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:
50265096 }
50275097
50285098 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
50845154 }
50855155
50865156 if ((!trace || !func) && opline->opcode != ZEND_DO_ICALL) {
5087- | brk #0 // TODO
5157+ | LOAD_IP_ADDR (opline + 1)
50885158 } else if (trace
50895159 && trace->op == ZEND_JIT_TRACE_END
50905160 && trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER) {
0 commit comments