@@ -1136,7 +1136,6 @@ static void* dasm_labels[zend_lb_MAX];
11361136|.macro OBJ_RELEASE, reg, exit_label, tmp_reg1, tmp_reg2
11371137| GC_DELREF Rx(reg), Rw(tmp_reg1)
11381138| bne >1
1139- | brk #0 // TODO
11401139| // zend_objects_store_del(obj);
11411140|| if (reg != ZREG_FCARG1x) {
11421141| mov FCARG1x, Rx(reg)
@@ -4706,13 +4705,14 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
47064705 } else if (opline->opcode == ZEND_INIT_FCALL_BY_NAME) {
47074706 | brk #0 // TODO
47084707 } else if (opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
4709- | brk #0 // TODO
4708+ | LOAD_ADDR FCARG1x, zv;
4709+ | EXT_CALL zend_jit_find_ns_func_helper, REG0
47104710 } else {
47114711 ZEND_UNREACHABLE();
47124712 }
47134713 | // CACHE_PTR(opline->result.num, fbc);
47144714 | ldr REG1, EX->run_time_cache
4715- | // Get the return value of function zend_jit_find_func_helper
4715+ | // Get the return value of function zend_jit_find_func_helper/zend_jit_find_ns_func_helper
47164716 | mov REG0, RETVALx
47174717 | str REG0, [REG1, #opline->result.num]
47184718 if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
@@ -5282,7 +5282,38 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
52825282 |8:
52835283 }
52845284 if (opline->opcode == ZEND_DO_FCALL_BY_NAME) {
5285- | brk #0 // TODO
5285+ if (!func) {
5286+ if (trace) {
5287+ uint32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
5288+
5289+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
5290+ if (!exit_addr) {
5291+ return 0;
5292+ }
5293+ | brk #0 // TODO
5294+ } else {
5295+ || ZEND_ASSERT(ZEND_ACC_DEPRECATED <= MAX_IMM12);
5296+ | ldr TMP1w, [REG0, #offsetof(zend_op_array, fn_flags)]
5297+ | tst TMP1w, #ZEND_ACC_DEPRECATED
5298+ | bne >1
5299+ |.cold_code
5300+ |1:
5301+ | brk #0 // TODO
5302+ if (!GCC_GLOBAL_REGS) {
5303+ | mov FCARG1x, RX
5304+ }
5305+ | EXT_CALL zend_jit_deprecated_helper, REG0
5306+ | and RETVALw, RETVALw, #0xff
5307+ | cmp RETVALw, #0 // Result is 0 on exception
5308+ | ldr REG0, EX:RX->func // reload
5309+ | bne >1
5310+ | b ->exception_handler
5311+ |.code
5312+ |1:
5313+ }
5314+ } else if (func->common.fn_flags & ZEND_ACC_DEPRECATED) {
5315+ | brk #0 // TODO
5316+ }
52865317 }
52875318
52885319 | // ZVAL_NULL(EX_VAR(opline->result.var));
@@ -5445,7 +5476,17 @@ static int zend_jit_send_val(dasm_State **Dst, const zend_op *opline, uint32_t o
54455476 }
54465477 | brk #0 // TODO
54475478 } else {
5448- | brk #0 // TODO
5479+ | ldr REG0, EX:RX->func
5480+ | ldr TMP1w, [REG0, #offsetof(zend_function, quick_arg_flags)]
5481+ | LOAD_32BIT_VAL TMP2w, mask
5482+ | tst TMP1w, TMP2w
5483+ | bne >1
5484+ |.cold_code
5485+ |1:
5486+ | brk #0 // TODO
5487+ | SET_EX_OPLINE opline, REG0
5488+ | b ->throw_cannot_pass_by_ref
5489+ |.code
54495490 }
54505491 }
54515492
@@ -5504,7 +5545,30 @@ static int zend_jit_send_var(dasm_State **Dst, const zend_op *opline, const zend
55045545 } else if (opline->opcode == ZEND_SEND_VAR_NO_REF_EX) {
55055546 | brk #0 // TODO
55065547 } else if (opline->opcode == ZEND_SEND_FUNC_ARG) {
5507- | brk #0 // TODO
5548+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE
5549+ && JIT_G(current_frame)
5550+ && JIT_G(current_frame)->call
5551+ && JIT_G(current_frame)->call->func) {
5552+ if (ARG_SHOULD_BE_SENT_BY_REF(JIT_G(current_frame)->call->func, arg_num)) {
5553+ if (!zend_jit_send_ref(Dst, opline, op_array, op1_info, 0)) {
5554+ return 0;
5555+ }
5556+ return 1;
5557+ }
5558+ } else {
5559+ | ldr TMP1w, [RX, #offsetof(zend_execute_data, This.u1.type_info)]
5560+ | LOAD_32BIT_VAL TMP2w, ZEND_CALL_SEND_ARG_BY_REF
5561+ | tst TMP1w, TMP2w
5562+ | bne >1
5563+ |.cold_code
5564+ |1:
5565+ | brk #0 // TODO
5566+ if (!zend_jit_send_ref(Dst, opline, op_array, op1_info, 1)) {
5567+ return 0;
5568+ }
5569+ | b >7
5570+ |.code
5571+ }
55085572 }
55095573
55105574 if (op1_info & MAY_BE_UNDEF) {
@@ -5579,7 +5643,42 @@ static int zend_jit_check_func_arg(dasm_State **Dst, const zend_op *opline)
55795643{
55805644 uint32_t arg_num = opline->op2.num;
55815645
5582- | brk #0 // TODO
5646+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE
5647+ && JIT_G(current_frame)
5648+ && JIT_G(current_frame)->call
5649+ && JIT_G(current_frame)->call->func) {
5650+ | brk #0 // TODO
5651+ } else {
5652+ // if (QUICK_ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, arg_num)) {
5653+ uint32_t mask = (ZEND_SEND_BY_REF|ZEND_SEND_PREFER_REF) << ((arg_num + 3) * 2);
5654+
5655+ if (!zend_jit_reuse_ip(Dst)) {
5656+ return 0;
5657+ }
5658+
5659+ | ldr REG0, EX:RX->func
5660+ | ldr TMP1w, [REG0, #offsetof(zend_function, quick_arg_flags)]
5661+ | LOAD_32BIT_VAL TMP2w, mask
5662+ | tst TMP1w, TMP2w
5663+ | bne >1
5664+ |.cold_code
5665+ |1:
5666+ | brk #0 // TODO
5667+ | // ZEND_ADD_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
5668+ | ldr TMP1w, [RX, #offsetof(zend_execute_data, This.u1.type_info)]
5669+ | LOAD_32BIT_VAL TMP2w, ZEND_CALL_SEND_ARG_BY_REF
5670+ | orr TMP1w, TMP1w, TMP2w
5671+ | str TMP1w, [RX, #offsetof(zend_execute_data, This.u1.type_info)]
5672+ | b >1
5673+ |.code
5674+ | // ZEND_DEL_CALL_FLAG(EX(call), ZEND_CALL_SEND_ARG_BY_REF);
5675+ | ldr TMP1w, [RX, #offsetof(zend_execute_data, This.u1.type_info)]
5676+ | LOAD_32BIT_VAL TMP2w, ZEND_CALL_SEND_ARG_BY_REF
5677+ | mvn TMP2w, TMP2w
5678+ | and TMP1w, TMP1w, TMP2w
5679+ | str TMP1w, [RX, #offsetof(zend_execute_data, This.u1.type_info)]
5680+ |1:
5681+ }
55835682
55845683 return 1;
55855684}
@@ -6160,7 +6259,59 @@ static int zend_jit_verify_arg_type(dasm_State **Dst, const zend_op *opline, zen
61606259 uint32_t type_mask = ZEND_TYPE_PURE_MASK(arg_info->type) & MAY_BE_ANY;
61616260 zend_reg tmp_reg = (type_mask == 0 || is_power_of_two(type_mask)) ? ZREG_FCARG1x : ZREG_REG0;
61626261
6163- | brk #0 // TODO
6262+ if (ZEND_ARG_SEND_MODE(arg_info)) {
6263+ | brk #0 // TODO
6264+ }
6265+
6266+ if (type_mask != 0) {
6267+ if (is_power_of_two(type_mask)) {
6268+ uint32_t type_code = concrete_type(type_mask);
6269+ || ZEND_ASSERT(type_code <= MAX_IMM12);
6270+ | IF_NOT_ZVAL_TYPE res_addr, type_code, >1, TMP1w, TMP2
6271+ } else {
6272+ | brk #0 // TODO
6273+ }
6274+
6275+ |.cold_code
6276+ |1:
6277+
6278+ in_cold = 1;
6279+ }
6280+
6281+ | brk #0 // TODO: currently in cold code
6282+ if (Z_REG(res_addr) != ZREG_FCARG1x || Z_OFFSET(res_addr) != 0) {
6283+ | brk #0 // TODO
6284+ | LOAD_ZVAL_ADDR FCARG1x, res_addr
6285+ }
6286+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6287+ | brk #0 // TODO
6288+ | SET_EX_OPLINE opline, REG0
6289+ } else {
6290+ | ADDR_STORE EX->opline, opline, REG0
6291+ }
6292+ | LOAD_ADDR FCARG2x, (ptrdiff_t)arg_info
6293+ | EXT_CALL zend_jit_verify_arg_slow, REG0
6294+ | mov REG0w, RETVALw
6295+
6296+ if (check_exception) {
6297+ | brk #0 // TODO
6298+ | and REG0w, REG0w, #0xff
6299+ | tst REG0w, REG0w
6300+ if (in_cold) {
6301+ | bne >1
6302+ | b ->exception_handler
6303+ |.code
6304+ |1:
6305+ } else {
6306+ | beq ->exception_handler
6307+ }
6308+ } else if (in_cold) {
6309+ | brk #0 // TODO
6310+ | b >1
6311+ |.code
6312+ |1:
6313+ }
6314+
61646315 return 1;
61656316}
61666317
@@ -6169,7 +6320,51 @@ static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_
61696320 uint32_t arg_num = opline->op1.num;
61706321 zend_arg_info *arg_info = NULL;
61716322
6172- | brk #0 // TODO
6323+ if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
6324+ if (EXPECTED(arg_num <= op_array->num_args)) {
6325+ arg_info = &op_array->arg_info[arg_num-1];
6326+ } else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
6327+ arg_info = &op_array->arg_info[op_array->num_args];
6328+ }
6329+ if (arg_info && !ZEND_TYPE_IS_SET(arg_info->type)) {
6330+ arg_info = NULL;
6331+ }
6332+ }
6333+
6334+ if (arg_info || (opline+1)->opcode != ZEND_RECV) {
6335+ | ldr TMP1w, EX->This.u2.num_args
6336+ | LOAD_32BIT_VAL TMP2w, arg_num
6337+ | cmp TMP1w, TMP2w
6338+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6339+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
6340+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6341+
6342+ if (!exit_addr) {
6343+ return 0;
6344+ }
6345+ | brk #0 // TODO
6346+ } else {
6347+ | blt >1
6348+ |.cold_code
6349+ |1:
6350+ | brk #0 // TODO
6351+ |.code
6352+ }
6353+ }
6354+
6355+ if (arg_info) {
6356+ if (!zend_jit_verify_arg_type(Dst, opline, arg_info, 1)) {
6357+ return 0;
6358+ }
6359+ }
6360+
6361+ if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE) {
6362+ if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
6363+ | LOAD_IP_ADDR (opline + 1)
6364+ zend_jit_set_last_valid_opline(opline + 1);
6365+ }
6366+ }
6367+
61736368 return 1;
61746369}
61756370
0 commit comments