31
31
|.define CARG4, x3
32
32
|.define CARG5, x4
33
33
|.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
34
40
|.define RETVALx, x0
35
41
|.define RETVALw, w0
36
42
|.define FCARG1x, x0
@@ -1447,7 +1453,16 @@ static int zend_jit_cannot_add_element_stub(dasm_State **Dst)
1447
1453
static int zend_jit_undefined_function_stub(dasm_State **Dst)
1448
1454
{
1449
1455
|->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
1451
1466
return 1;
1452
1467
}
1453
1468
@@ -4836,7 +4851,7 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
4836
4851
if (!func
4837
4852
&& trace
4838
4853
&& trace->op == ZEND_JIT_TRACE_INIT_CALL) {
4839
- | brk #0 // TODO: Tracing mode. ASLR?
4854
+ func = (zend_function*)trace->func;
4840
4855
}
4841
4856
4842
4857
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
4845
4860
/* load constant address later */
4846
4861
} else if (func && op_array == &func->op_array) {
4847
4862
/* recursive call */
4848
- | brk #0 // TODO
4863
+ | ldr REG0, EX->func
4849
4864
} else {
4850
4865
| // if (CACHED_PTR(opline->result.num))
4851
4866
| 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
4857
4872
&& func
4858
4873
&& func->type == ZEND_USER_FUNCTION
4859
4874
&& (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
4861
4881
} else {
4862
4882
zval *zv = RT_CONSTANT(opline, opline->op2);
4863
4883
4864
4884
if (opline->opcode == ZEND_INIT_FCALL) {
4865
4885
| LOAD_ADDR FCARG1x, Z_STR_P(zv);
4866
4886
| EXT_CALL zend_jit_find_func_helper, REG0
4867
4887
} 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
4869
4890
} else if (opline->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
4870
4891
| LOAD_ADDR FCARG1x, zv;
4871
4892
| 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
4882
4903
} else {
4883
4904
| cbnz REG0, >3
4884
4905
| // SAVE_OPLINE();
4885
- | brk #0 // TODO: invalid func address.
4906
+ | SET_EX_OPLINE opline, REG0
4907
+ | b ->undefined_function
4886
4908
}
4887
4909
}
4888
4910
|.code
@@ -5175,12 +5197,10 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5175
5197
5176
5198
prev_opline = opline - 1;
5177
5199
while (prev_opline->opcode == ZEND_EXT_FCALL_BEGIN || prev_opline->opcode == ZEND_TICKS) {
5178
- | brk #0 // TODO
5179
5200
prev_opline--;
5180
5201
}
5181
5202
if (prev_opline->opcode == ZEND_SEND_UNPACK || prev_opline->opcode == ZEND_SEND_ARRAY ||
5182
5203
prev_opline->opcode == ZEND_CHECK_UNDEF_ARGS) {
5183
- | brk #0 // TODO
5184
5204
unknown_num_args = 1;
5185
5205
}
5186
5206
@@ -5196,7 +5216,6 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5196
5216
if (!func) {
5197
5217
/* resolve function at run time */
5198
5218
} else if (func->type == ZEND_USER_FUNCTION) {
5199
- | brk #0 // TODO
5200
5219
ZEND_ASSERT(opline->opcode != ZEND_DO_ICALL);
5201
5220
call_num_args = call_info->num_args;
5202
5221
} 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
5312
5331
if (func && op_array == &func->op_array) {
5313
5332
/* recursive call */
5314
5333
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
5316
5336
}
5317
5337
} else {
5318
5338
if (func) {
5319
- | brk #0 // TODO
5339
+ | ldr REG0, EX:RX->func
5320
5340
}
5321
5341
| ldr REG2, [REG0, #offsetof(zend_op_array, run_time_cache__ptr)]
5322
5342
// Always defined as ZEND_MAP_PTR_KIND_PTR_OR_OFFSET. See Zend/zend_map_ptr.h.
5323
5343
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
5324
5344
| ldr REG2, [REG2]
5325
5345
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
5326
5346
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
+ }
5328
5360
} else {
5329
5361
| tst REG2, #1
5330
5362
| beq >1
@@ -5345,11 +5377,82 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5345
5377
5346
5378
| // opline = op_array->opcodes;
5347
5379
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
+ }
5349
5452
} else {
5350
5453
| // opline = op_array->opcodes
5351
5454
if (func && zend_accel_in_shm(func->op_array.opcodes)) {
5352
- | brk #0 // TODO
5455
+ | LOAD_IP_ADDR (func->op_array.opcodes)
5353
5456
} else if (GCC_GLOBAL_REGS) {
5354
5457
| ldr IP, [REG0, #offsetof(zend_op_array, opcodes)]
5355
5458
} else {
@@ -5358,6 +5461,10 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
5358
5461
}
5359
5462
if (func) {
5360
5463
| 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)
5361
5468
} else {
5362
5469
| // first_extra_arg = op_array->num_args;
5363
5470
| 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
5387
5494
|1:
5388
5495
| // if (EXPECTED((int)num_args < op_array->last_var)) {
5389
5496
if (func) {
5390
- | brk #0 // TODO
5497
+ | movz REG2w, #(func->op_array.last_var)
5391
5498
} else {
5392
5499
| ldr REG2w, [REG0, #offsetof(zend_op_array, last_var)]
5393
5500
}
0 commit comments