@@ -3502,10 +3502,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3502
3502
|| !(op2_info & MAY_BE_LONG )) {
3503
3503
break ;
3504
3504
}
3505
- if (opline -> result_type == IS_TMP_VAR
3505
+ res_addr = RES_REG_ADDR ();
3506
+ if (Z_MODE (res_addr ) != IS_REG
3507
+ && opline -> result_type == IS_TMP_VAR
3506
3508
&& (p + 1 )-> op == ZEND_JIT_TRACE_VM
3507
3509
&& (p + 1 )-> opline == opline + 1
3508
- && (opline + 1 )-> opcode == ZEND_SEND_VAL
3510
+ && ((opline + 1 )-> opcode == ZEND_SEND_VAL
3511
+ || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
3512
+ && frame
3513
+ && frame -> call
3514
+ && frame -> call -> func
3515
+ && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
3509
3516
&& (opline + 1 )-> op1_type == IS_TMP_VAR
3510
3517
&& (opline + 1 )-> op1 .var == opline -> result .var ) {
3511
3518
p ++ ;
@@ -3529,7 +3536,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3529
3536
goto jit_failure ;
3530
3537
}
3531
3538
} else {
3532
- send_result = 0 ;
3533
3539
if (opline -> result_type == IS_CV ) {
3534
3540
res_use_info = RES_USE_INFO ();
3535
3541
} else {
@@ -3539,7 +3545,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3539
3545
res_use_info = -1 ;
3540
3546
#endif
3541
3547
}
3542
- res_addr = RES_REG_ADDR ();
3543
3548
}
3544
3549
res_info = RES_INFO ();
3545
3550
if (!zend_jit_long_math (& dasm_state , opline ,
@@ -3564,19 +3569,22 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3564
3569
if (opline -> opcode == ZEND_ADD &&
3565
3570
(op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY &&
3566
3571
(op2_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY ) {
3567
- if (!zend_jit_add_arrays (& dasm_state , opline , op1_info , op2_info )) {
3568
- goto jit_failure ;
3569
- }
3570
- goto done ;
3571
- }
3572
- if (!(op1_info & (MAY_BE_LONG |MAY_BE_DOUBLE )) ||
3572
+ /* pass */
3573
+ } else if (!(op1_info & (MAY_BE_LONG |MAY_BE_DOUBLE )) ||
3573
3574
!(op2_info & (MAY_BE_LONG |MAY_BE_DOUBLE ))) {
3574
3575
break ;
3575
3576
}
3576
- if (opline -> result_type == IS_TMP_VAR
3577
+ res_addr = RES_REG_ADDR ();
3578
+ if (Z_MODE (res_addr ) != IS_REG
3579
+ && opline -> result_type == IS_TMP_VAR
3577
3580
&& (p + 1 )-> op == ZEND_JIT_TRACE_VM
3578
3581
&& (p + 1 )-> opline == opline + 1
3579
- && (opline + 1 )-> opcode == ZEND_SEND_VAL
3582
+ && ((opline + 1 )-> opcode == ZEND_SEND_VAL
3583
+ || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
3584
+ && frame
3585
+ && frame -> call
3586
+ && frame -> call -> func
3587
+ && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
3580
3588
&& (opline + 1 )-> op1_type == IS_TMP_VAR
3581
3589
&& (opline + 1 )-> op1 .var == opline -> result .var ) {
3582
3590
p ++ ;
@@ -3602,7 +3610,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3602
3610
goto jit_failure ;
3603
3611
}
3604
3612
} else {
3605
- send_result = 0 ;
3606
3613
if (opline -> result_type == IS_CV ) {
3607
3614
res_use_info = RES_USE_INFO ();
3608
3615
} else {
@@ -3612,19 +3619,27 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3612
3619
res_use_info = -1 ;
3613
3620
#endif
3614
3621
}
3615
- res_addr = RES_REG_ADDR ();
3616
3622
}
3617
3623
res_info = RES_INFO ();
3618
- if (!zend_jit_math (& dasm_state , opline ,
3619
- op1_info , OP1_REG_ADDR (),
3620
- op2_info , OP2_REG_ADDR (),
3621
- res_use_info , res_info , res_addr ,
3622
- (op1_info & MAY_BE_LONG ) && (op2_info & MAY_BE_LONG ) && (res_info & (MAY_BE_DOUBLE |MAY_BE_GUARD )) && zend_may_overflow (opline , ssa_op , op_array , ssa ),
3623
- zend_may_throw (opline , ssa_op , op_array , ssa ))) {
3624
- goto jit_failure ;
3625
- }
3626
- if ((res_info & (MAY_BE_ANY |MAY_BE_GUARD )) == (MAY_BE_LONG |MAY_BE_GUARD )) {
3627
- ssa -> var_info [ssa_op -> result_def ].type &= ~MAY_BE_GUARD ;
3624
+ if (opline -> opcode == ZEND_ADD &&
3625
+ (op1_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY &&
3626
+ (op2_info & (MAY_BE_ANY |MAY_BE_UNDEF )) == MAY_BE_ARRAY ) {
3627
+ if (!zend_jit_add_arrays (& dasm_state , opline , op1_info , op2_info , res_addr )) {
3628
+ goto jit_failure ;
3629
+ }
3630
+ } else {
3631
+ if (!zend_jit_math (& dasm_state , opline ,
3632
+ op1_info , OP1_REG_ADDR (),
3633
+ op2_info , OP2_REG_ADDR (),
3634
+ res_use_info , res_info , res_addr ,
3635
+ (op1_info & MAY_BE_LONG ) && (op2_info & MAY_BE_LONG ) && (res_info & (MAY_BE_DOUBLE |MAY_BE_GUARD )) && zend_may_overflow (opline , ssa_op , op_array , ssa ),
3636
+ zend_may_throw (opline , ssa_op , op_array , ssa ))) {
3637
+ goto jit_failure ;
3638
+ }
3639
+ if ((res_info & (MAY_BE_ANY |MAY_BE_GUARD )) == (MAY_BE_LONG |MAY_BE_GUARD )
3640
+ || (res_info & (MAY_BE_ANY |MAY_BE_GUARD )) == (MAY_BE_DOUBLE |MAY_BE_GUARD )) {
3641
+ ssa -> var_info [ssa_op -> result_def ].type &= ~MAY_BE_GUARD ;
3642
+ }
3628
3643
}
3629
3644
goto done ;
3630
3645
case ZEND_CONCAT :
@@ -3640,10 +3655,17 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3640
3655
!(op2_info & MAY_BE_STRING )) {
3641
3656
break ;
3642
3657
}
3643
- if (opline -> result_type == IS_TMP_VAR
3658
+ res_addr = RES_REG_ADDR ();
3659
+ if (Z_MODE (res_addr ) != IS_REG
3660
+ && opline -> result_type == IS_TMP_VAR
3644
3661
&& (p + 1 )-> op == ZEND_JIT_TRACE_VM
3645
3662
&& (p + 1 )-> opline == opline + 1
3646
- && (opline + 1 )-> opcode == ZEND_SEND_VAL
3663
+ && ((opline + 1 )-> opcode == ZEND_SEND_VAL
3664
+ || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
3665
+ && frame
3666
+ && frame -> call
3667
+ && frame -> call -> func
3668
+ && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
3647
3669
&& (opline + 1 )-> op1_type == IS_TMP_VAR
3648
3670
&& (opline + 1 )-> op1 .var == opline -> result .var ) {
3649
3671
p ++ ;
@@ -3667,9 +3689,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
3667
3689
if (!zend_jit_reuse_ip (& dasm_state )) {
3668
3690
goto jit_failure ;
3669
3691
}
3670
- } else {
3671
- send_result = 0 ;
3672
- res_addr = RES_REG_ADDR ();
3673
3692
}
3674
3693
if (!zend_jit_concat (& dasm_state , opline ,
3675
3694
op1_info , op2_info , res_addr ,
@@ -4028,13 +4047,6 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4028
4047
if (opline -> op1_type != IS_CV ) {
4029
4048
break ;
4030
4049
}
4031
- if (opline -> result_type == IS_UNUSED ) {
4032
- res_addr = 0 ;
4033
- res_info = -1 ;
4034
- } else {
4035
- res_addr = RES_REG_ADDR ();
4036
- res_info = RES_INFO ();
4037
- }
4038
4050
op2_addr = OP2_REG_ADDR ();
4039
4051
if (ra
4040
4052
&& ssa_op -> op2_def >= 0
@@ -4072,6 +4084,47 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
4072
4084
op1_def_info &= ~MAY_BE_REF ;
4073
4085
}
4074
4086
}
4087
+ if (opline -> result_type == IS_UNUSED ) {
4088
+ res_addr = 0 ;
4089
+ res_info = -1 ;
4090
+ } else {
4091
+ res_addr = RES_REG_ADDR ();
4092
+ res_info = RES_INFO ();
4093
+ if (Z_MODE (res_addr ) != IS_REG
4094
+ && opline -> result_type == IS_TMP_VAR
4095
+ && (p + 1 )-> op == ZEND_JIT_TRACE_VM
4096
+ && (p + 1 )-> opline == opline + 1
4097
+ && ((opline + 1 )-> opcode == ZEND_SEND_VAL
4098
+ || ((opline + 1 )-> opcode == ZEND_SEND_VAL_EX
4099
+ && frame
4100
+ && frame -> call
4101
+ && frame -> call -> func
4102
+ && !ARG_MUST_BE_SENT_BY_REF (frame -> call -> func , (opline + 1 )-> op2 .num )))
4103
+ && (opline + 1 )-> op1_type == IS_TMP_VAR
4104
+ && (opline + 1 )-> op1 .var == opline -> result .var ) {
4105
+ p ++ ;
4106
+ if (frame -> call
4107
+ && frame -> call -> func
4108
+ && frame -> call -> func -> type == ZEND_USER_FUNCTION ) {
4109
+ uint8_t res_type = p -> op1_type ;
4110
+ if (res_type & IS_TRACE_REFERENCE ) {
4111
+ res_type = IS_UNKNOWN ;
4112
+ }
4113
+ if (res_type != IS_UNKNOWN ) {
4114
+ zend_jit_trace_send_type (opline + 1 , frame -> call , res_type );
4115
+ }
4116
+ }
4117
+ while ((p + 1 )-> op == ZEND_JIT_TRACE_OP1_TYPE ||
4118
+ (p + 1 )-> op == ZEND_JIT_TRACE_OP2_TYPE ) {
4119
+ p ++ ;
4120
+ }
4121
+ send_result = 1 ;
4122
+ res_addr = ZEND_ADDR_MEM_ZVAL (ZREG_RX , (opline + 1 )-> result .var );
4123
+ if (!zend_jit_reuse_ip (& dasm_state )) {
4124
+ goto jit_failure ;
4125
+ }
4126
+ }
4127
+ }
4075
4128
if (!zend_jit_assign (& dasm_state , opline ,
4076
4129
op1_info , op1_addr ,
4077
4130
op1_def_info , op1_def_addr ,
0 commit comments