3131|.define CARG4, x3
3232|.define CARG5, x4
3333|.define CARG6, x5
34+ |.define CARG1w, w0
35+ |.define CARG2w, w1
36+ |.define CARG3w, w2
37+ |.define CARG4w, w3
38+ |.define CARG5w, w4
39+ |.define CARG6w, w5
3440|.define RETVALx, x0
3541|.define RETVALw, w0
3642|.define FCARG1x, x0
@@ -1447,7 +1453,16 @@ static int zend_jit_cannot_add_element_stub(dasm_State **Dst)
14471453static int zend_jit_undefined_function_stub(dasm_State **Dst)
14481454{
14491455 |->undefined_function:
1450- | brk #0 // TODO
1456+ | ldr REG0, EX->opline
1457+ | movz CARG1, #0
1458+ | LOAD_ADDR CARG2, "Call to undefined function %s()"
1459+ | ldr CARG3w, [REG0, #offsetof(zend_op, op2.constant)]
1460+ | sxtw CARG3, CARG3w
1461+ | add REG0, REG0, CARG3
1462+ | ldr CARG3, [REG0]
1463+ | add CARG3, CARG3, #offsetof(zend_string, val)
1464+ | EXT_CALL zend_throw_error, REG0
1465+ | b ->exception_handler
14511466 return 1;
14521467}
14531468
@@ -4836,7 +4851,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
48364851 if (!func
48374852 && trace
48384853 && trace->op == ZEND_JIT_TRACE_INIT_CALL) {
4839- | brk #0 // TODO: Tracing mode. ASLR?
4854+ func = (zend_function*)trace->func;
48404855 }
48414856
48424857 if (opline->opcode == ZEND_INIT_FCALL
@@ -4845,7 +4860,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
48454860 /* load constant address later */
48464861 } else if (func && op_array == &func->op_array) {
48474862 /* recursive call */
4848- | brk #0 // TODO
4863+ | ldr REG0, EX->func
48494864 } else {
48504865 | // if (CACHED_PTR(opline->result.num))
48514866 | ldr REG0, EX->run_time_cache
@@ -4857,15 +4872,21 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
48574872 && func
48584873 && func->type == ZEND_USER_FUNCTION
48594874 && (func->op_array.fn_flags & ZEND_ACC_IMMUTABLE)) {
4860- | brk #0 // TODO
4875+ | LOAD_ADDR FCARG1x, func
4876+ | EXT_CALL zend_jit_init_func_run_time_cache_helper, REG0
4877+ | ldr REG1, EX->run_time_cache
4878+ | mov REG0, RETVALx
4879+ | str REG0, [REG1, #opline->result.num]
4880+ | b >3
48614881 } else {
48624882 zval *zv = RT_CONSTANT(opline, opline->op2);
48634883
48644884 if (opline->opcode == ZEND_INIT_FCALL) {
48654885 | LOAD_ADDR FCARG1x, Z_STR_P(zv);
48664886 | EXT_CALL zend_jit_find_func_helper, REG0
48674887 } else if (opline->opcode == ZEND_INIT_FCALL_BY_NAME) {
4868- | brk #0 // TODO
4888+ | LOAD_ADDR FCARG1x, Z_STR_P(zv + 1);
4889+ | EXT_CALL zend_jit_find_func_helper, REG0
48694890 } else if (opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
48704891 | LOAD_ADDR FCARG1x, zv;
48714892 | EXT_CALL zend_jit_find_ns_func_helper, REG0
@@ -4882,7 +4903,8 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
48824903 } else {
48834904 | cbnz REG0, >3
48844905 | // SAVE_OPLINE();
4885- | brk #0 // TODO: invalid func address.
4906+ | SET_EX_OPLINE opline, REG0
4907+ | b ->undefined_function
48864908 }
48874909 }
48884910 |.code
@@ -5175,12 +5197,10 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
51755197
51765198 prev_opline = opline - 1;
51775199 while (prev_opline->opcode == ZEND_EXT_FCALL_BEGIN || prev_opline->opcode == ZEND_TICKS) {
5178- | brk #0 // TODO
51795200 prev_opline--;
51805201 }
51815202 if (prev_opline->opcode == ZEND_SEND_UNPACK || prev_opline->opcode == ZEND_SEND_ARRAY ||
51825203 prev_opline->opcode == ZEND_CHECK_UNDEF_ARGS) {
5183- | brk #0 // TODO
51845204 unknown_num_args = 1;
51855205 }
51865206
@@ -5196,7 +5216,6 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
51965216 if (!func) {
51975217 /* resolve function at run time */
51985218 } else if (func->type == ZEND_USER_FUNCTION) {
5199- | brk #0 // TODO
52005219 ZEND_ASSERT(opline->opcode != ZEND_DO_ICALL);
52015220 call_num_args = call_info->num_args;
52025221 } else if (func->type == ZEND_INTERNAL_FUNCTION) {
@@ -5312,19 +5331,32 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
53125331 if (func && op_array == &func->op_array) {
53135332 /* recursive call */
53145333 if (trace || func->op_array.cache_size > sizeof(void*)) {
5315- | brk #0 // TODO
5334+ | ldr REG2, EX->run_time_cache
5335+ | str REG2, EX:RX->run_time_cache
53165336 }
53175337 } else {
53185338 if (func) {
5319- | brk #0 // TODO
5339+ | ldr REG0, EX:RX->func
53205340 }
53215341 | ldr REG2, [REG0, #offsetof(zend_op_array, run_time_cache__ptr)]
53225342// Always defined as ZEND_MAP_PTR_KIND_PTR_OR_OFFSET. See Zend/zend_map_ptr.h.
53235343#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
53245344 | ldr REG2, [REG2]
53255345#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
53265346 if (func && !(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) {
5327- | brk #0 // TODO
5347+ if (ZEND_MAP_PTR_IS_OFFSET(func->op_array.run_time_cache)) {
5348+ | MEM_LOAD_OP_ZTS add, ldr, REG2, compiler_globals, map_ptr_base, REG1, TMP1
5349+ } else if ((func->op_array.fn_flags & ZEND_ACC_IMMUTABLE)
5350+ && (!func->op_array.scope || (func->op_array.scope->ce_flags & ZEND_ACC_LINKED))) {
5351+ | MEM_LOAD_OP_ZTS add, ldr, REG2, compiler_globals, map_ptr_base, REG1, TMP1
5352+ } else {
5353+ /* the called op_array may be not persisted yet */
5354+ | tst REG2, #1
5355+ | beq >1
5356+ | MEM_LOAD_OP_ZTS add, ldr, REG2, compiler_globals, map_ptr_base, REG1, TMP1
5357+ |1:
5358+ | ldr REG2, [REG2]
5359+ }
53285360 } else {
53295361 | tst REG2, #1
53305362 | beq >1
@@ -5345,11 +5377,82 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
53455377
53465378 | // opline = op_array->opcodes;
53475379 if (func && !unknown_num_args) {
5348- | brk #0 // TODO
5380+ for (i = call_num_args; i < func->op_array.last_var; i++) {
5381+ uint32_t n = EX_NUM_TO_VAR(i);
5382+ | // ZVAL_UNDEF(EX_VAR(n))
5383+ | str wzr, [RX, #(n + offsetof(zval,u1.type_info))]
5384+ }
5385+
5386+ if (call_num_args <= func->op_array.num_args) {
5387+ if (!trace || (trace->op == ZEND_JIT_TRACE_END
5388+ && trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER)) {
5389+ uint32_t num_args;
5390+
5391+ if ((func->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0) {
5392+ if (trace) {
5393+ num_args = 0;
5394+ } else if (call_info) {
5395+ num_args = skip_valid_arguments(op_array, ssa, call_info);
5396+ } else {
5397+ num_args = call_num_args;
5398+ }
5399+ } else {
5400+ num_args = call_num_args;
5401+ }
5402+ if (zend_accel_in_shm(func->op_array.opcodes)) {
5403+ | LOAD_IP_ADDR (func->op_array.opcodes + num_args)
5404+ } else {
5405+ | ldr REG0, EX->func
5406+ if (GCC_GLOBAL_REGS) {
5407+ | ldr IP, [REG0, #offsetof(zend_op_array, opcodes)]
5408+ if (num_args) {
5409+ | add IP, IP, #(num_args * sizeof(zend_op))
5410+ }
5411+ } else {
5412+ | ldr REG1, [REG0, #offsetof(zend_op_array, opcodes)]
5413+ if (num_args) {
5414+ | add REG1, REG1, #(num_args * sizeof(zend_op))
5415+ }
5416+ | str REG1, EX->opline
5417+ }
5418+ }
5419+
5420+ if (!trace && op_array == &func->op_array) {
5421+ /* recursive call */
5422+ if (ZEND_OBSERVER_ENABLED) {
5423+ | SAVE_IP
5424+ | mov CARG1, FP
5425+ | EXT_CALL zend_observer_fcall_begin, REG0
5426+ }
5427+ #ifdef CONTEXT_THREADED_JIT
5428+ | brk #0 // TODO
5429+ #else
5430+ | b =>num_args
5431+ #endif
5432+ return 1;
5433+ }
5434+ }
5435+ } else {
5436+ if (!trace || (trace->op == ZEND_JIT_TRACE_END
5437+ && trace->stop == ZEND_JIT_TRACE_STOP_INTERPRETER)) {
5438+ if (func && zend_accel_in_shm(func->op_array.opcodes)) {
5439+ | LOAD_IP_ADDR (func->op_array.opcodes)
5440+ } else if (GCC_GLOBAL_REGS) {
5441+ | ldr IP, [REG0, #offsetof(zend_op_array, opcodes)]
5442+ } else {
5443+ | ldr CARG1, [REG0, #offsetof(zend_op_array, opcodes)]
5444+ | str CARG1, EX->opline
5445+ }
5446+ }
5447+ if (!GCC_GLOBAL_REGS) {
5448+ | mov CARG1, FP
5449+ }
5450+ | EXT_CALL zend_jit_copy_extra_args_helper, REG0
5451+ }
53495452 } else {
53505453 | // opline = op_array->opcodes
53515454 if (func && zend_accel_in_shm(func->op_array.opcodes)) {
5352- | brk #0 // TODO
5455+ | LOAD_IP_ADDR (func->op_array.opcodes)
53535456 } else if (GCC_GLOBAL_REGS) {
53545457 | ldr IP, [REG0, #offsetof(zend_op_array, opcodes)]
53555458 } else {
@@ -5358,6 +5461,10 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
53585461 }
53595462 if (func) {
53605463 | brk #0 // TODO
5464+ | // num_args = EX_NUM_ARGS();
5465+ | ldr REG1w, [FP, #offsetof(zend_execute_data, This.u2.num_args)]
5466+ | // if (UNEXPECTED(num_args > first_extra_arg))
5467+ | cmp REG1w, #(func->op_array.num_args)
53615468 } else {
53625469 | // first_extra_arg = op_array->num_args;
53635470 | ldr REG2w, [REG0, #offsetof(zend_op_array, num_args)]
@@ -5387,7 +5494,7 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
53875494 |1:
53885495 | // if (EXPECTED((int)num_args < op_array->last_var)) {
53895496 if (func) {
5390- | brk #0 // TODO
5497+ | movz REG2w, #(func->op_array.last_var)
53915498 } else {
53925499 | ldr REG2w, [REG0, #offsetof(zend_op_array, last_var)]
53935500 }
0 commit comments