@@ -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