@@ -10501,95 +10501,100 @@ static int zend_jit_bind_global(dasm_State **Dst, const zend_op *opline, const z
10501
10501
static int zend_jit_recv(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array)
10502
10502
{
10503
10503
uint32_t arg_num = opline->op1.num;
10504
-
10505
- | cmp dword EX->This.u2.num_args, arg_num
10506
- | jb >1
10507
- |.cold_code
10508
- |1:
10509
- | SAVE_VALID_OPLINE opline, r0
10510
- | mov FCARG1a, FP
10511
- | EXT_CALL zend_missing_arg_error, r0
10512
- | jmp ->exception_handler
10513
- |.code
10504
+ zend_arg_info *arg_info = NULL;
10514
10505
10515
10506
if (op_array->fn_flags & ZEND_ACC_HAS_TYPE_HINTS) {
10516
- zend_arg_info *arg_info = NULL;
10517
-
10518
10507
if (EXPECTED(arg_num <= op_array->num_args)) {
10519
10508
arg_info = &op_array->arg_info[arg_num-1];
10520
10509
} else if (UNEXPECTED(op_array->fn_flags & ZEND_ACC_VARIADIC)) {
10521
10510
arg_info = &op_array->arg_info[op_array->num_args];
10522
10511
}
10523
- if (arg_info) {
10524
- zend_type type = arg_info->type;
10512
+ if (arg_info && !ZEND_TYPE_IS_SET(arg_info->type)) {
10513
+ arg_info = NULL;
10514
+ }
10515
+ }
10525
10516
10526
- if (ZEND_TYPE_IS_SET(type)) {
10527
- // Type check
10528
- zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10517
+ if (arg_info || (opline+1)->opcode != ZEND_RECV) {
10518
+ | cmp dword EX->This.u2.num_args, arg_num
10519
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
10520
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, opline, NULL, ZEND_JIT_EXIT_TO_VM);
10521
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
10529
10522
10530
- | LOAD_ZVAL_ADDR r0, res_addr
10531
- if (ZEND_ARG_SEND_MODE(arg_info)) {
10532
- | GET_Z_PTR r0, r0
10533
- | add r0, offsetof(zend_reference, val)
10534
- }
10523
+ if (!exit_addr) {
10524
+ return 0;
10525
+ }
10526
+ | jb &exit_addr
10527
+ } else {
10528
+ | jb >1
10529
+ |.cold_code
10530
+ |1:
10531
+ | SAVE_VALID_OPLINE opline, r0
10532
+ | mov FCARG1a, FP
10533
+ | EXT_CALL zend_missing_arg_error, r0
10534
+ | jmp ->exception_handler
10535
+ |.code
10536
+ }
10537
+ }
10535
10538
10536
- uint32_t type_mask = ZEND_TYPE_PURE_MASK(type);
10537
- if (type_mask == 0) {
10538
- | jmp >8
10539
- } else if (is_power_of_two(type_mask)) {
10540
- uint32_t type_code = concrete_type(type_mask);
10541
- | cmp byte [r0 + 8], type_code
10542
- | jne >8
10543
- } else {
10544
- | mov edx, 1
10545
- | mov cl, byte [r0 + 8]
10546
- | shl edx, cl
10547
- | test edx, type_mask
10548
- | je >8
10549
- }
10539
+ if (arg_info) {
10540
+ // Type check
10541
+ zend_type type = arg_info->type;
10542
+ zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
10543
+ uint32_t type_mask;
10550
10544
10551
- |.cold_code
10552
- |8:
10553
- | SAVE_VALID_OPLINE opline, r0
10554
- | mov FCARG1a, r0
10555
- | mov r0, EX->run_time_cache
10556
- | add r0, opline->extended_value
10557
- | mov FCARG2a, EX->func
10558
- |.if X64WIN
10559
- | mov CARG3, arg_num
10560
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10561
- | mov aword A5, r0
10562
- | EXT_CALL zend_jit_verify_arg_slow, r0
10563
- |.elif X64
10564
- | mov CARG3, arg_num
10565
- | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10566
- | mov CARG5, r0
10567
- | EXT_CALL zend_jit_verify_arg_slow, r0
10568
- |.else
10569
- | sub r4, 4
10570
- | push r0
10571
- | push (ptrdiff_t)arg_info
10572
- | push arg_num
10573
- | EXT_CALL zend_jit_verify_arg_slow, r0
10574
- | add r4, 4
10575
- |.endif
10576
- if (!zend_jit_check_exception(Dst)) {
10577
- return 0;
10578
- }
10579
- | jmp >1
10580
- |.code
10581
- |1:
10545
+ | LOAD_ZVAL_ADDR r0, res_addr
10546
+ if (ZEND_ARG_SEND_MODE(arg_info)) {
10547
+ | GET_Z_PTR r0, r0
10548
+ | add r0, offsetof(zend_reference, val)
10549
+ }
10582
10550
10583
- if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
10584
- last_valid_opline = NULL;
10585
- if (!zend_jit_set_valid_ip(Dst, opline + 1)) {
10586
- return 0;
10587
- }
10588
- }
10551
+ type_mask = ZEND_TYPE_PURE_MASK(type);
10552
+ if (type_mask == 0) {
10553
+ | jmp >8
10554
+ } else if (is_power_of_two(type_mask)) {
10555
+ uint32_t type_code = concrete_type(type_mask);
10556
+ | cmp byte [r0 + 8], type_code
10557
+ | jne >8
10558
+ } else {
10559
+ | mov edx, 1
10560
+ | mov cl, byte [r0 + 8]
10561
+ | shl edx, cl
10562
+ | test edx, type_mask
10563
+ | je >8
10564
+ }
10589
10565
10590
- return 1;
10591
- }
10566
+ |.cold_code
10567
+ |8:
10568
+ | SAVE_VALID_OPLINE opline, r0
10569
+ | mov FCARG1a, r0
10570
+ | mov r0, EX->run_time_cache
10571
+ | add r0, opline->extended_value
10572
+ | mov FCARG2a, EX->func
10573
+ |.if X64WIN
10574
+ | mov CARG3, arg_num
10575
+ | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10576
+ | mov aword A5, r0
10577
+ | EXT_CALL zend_jit_verify_arg_slow, r0
10578
+ |.elif X64
10579
+ | mov CARG3, arg_num
10580
+ | LOAD_ADDR CARG4, (ptrdiff_t)arg_info
10581
+ | mov CARG5, r0
10582
+ | EXT_CALL zend_jit_verify_arg_slow, r0
10583
+ |.else
10584
+ | sub r4, 4
10585
+ | push r0
10586
+ | push (ptrdiff_t)arg_info
10587
+ | push arg_num
10588
+ | EXT_CALL zend_jit_verify_arg_slow, r0
10589
+ | add r4, 4
10590
+ |.endif
10591
+
10592
+ if (!zend_jit_check_exception(Dst)) {
10593
+ return 0;
10592
10594
}
10595
+ | jmp >1
10596
+ |.code
10597
+ |1:
10593
10598
}
10594
10599
10595
10600
if ((opline+1)->opcode != ZEND_RECV && (opline+1)->opcode != ZEND_RECV_INIT) {
0 commit comments