@@ -40040,6 +40040,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER
40040
40040
ZEND_VM_SMART_BRANCH(result, 1);
40041
40041
}
40042
40042
40043
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
40044
+ {
40045
+ /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
40046
+ /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
40047
+ /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
40048
+ USE_OPLINE
40049
+ zval *op1, *op2;
40050
+ zend_bool result;
40051
+
40052
+ op1 = EX_VAR(opline->op1.var);
40053
+ op2 = RT_CONSTANT(opline, opline->op2);
40054
+ result = fast_is_identical_function(op1, op2);
40055
+ /* Free is a no-op for const/cv */
40056
+ ZEND_VM_SMART_BRANCH(result, 0);
40057
+ }
40058
+
40059
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
40060
+ {
40061
+ USE_OPLINE
40062
+ zval *op1, *op2;
40063
+ zend_bool result;
40064
+
40065
+ op1 = EX_VAR(opline->op1.var);
40066
+ op2 = RT_CONSTANT(opline, opline->op2);
40067
+ result = fast_is_identical_function(op1, op2);
40068
+ /* Free is a no-op for const/cv */
40069
+ ZEND_VM_SMART_BRANCH(!result, 0);
40070
+ }
40071
+
40043
40072
static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
40044
40073
{
40045
40074
USE_OPLINE
@@ -48119,6 +48148,35 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_
48119
48148
ZEND_VM_RETURN();
48120
48149
}
48121
48150
48151
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
48152
+ {
48153
+ /* This is declared below the specializations for MAY_BE_LONG/MAY_BE_DOUBLE so those will be used instead if possible. */
48154
+ /* This optimizes $x === SOME_CONST_EXPR and $x === $y for non-refs and non-undef, which can't throw. */
48155
+ /* (Infinite recursion when comparing arrays is an uncatchable fatal error) */
48156
+ USE_OPLINE
48157
+ zval *op1, *op2;
48158
+ zend_bool result;
48159
+
48160
+ op1 = EX_VAR(opline->op1.var);
48161
+ op2 = EX_VAR(opline->op2.var);
48162
+ result = fast_is_identical_function(op1, op2);
48163
+ /* Free is a no-op for const/cv */
48164
+ ZEND_VM_SMART_BRANCH(result, 0);
48165
+ }
48166
+
48167
+ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
48168
+ {
48169
+ USE_OPLINE
48170
+ zval *op1, *op2;
48171
+ zend_bool result;
48172
+
48173
+ op1 = EX_VAR(opline->op1.var);
48174
+ op2 = EX_VAR(opline->op2.var);
48175
+ result = fast_is_identical_function(op1, op2);
48176
+ /* Free is a no-op for const/cv */
48177
+ ZEND_VM_SMART_BRANCH(!result, 0);
48178
+ }
48179
+
48122
48180
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NULL_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
48123
48181
{
48124
48182
USE_OPLINE
@@ -50998,6 +51056,16 @@ ZEND_API void execute_ex(zend_execute_data *ex)
50998
51056
(void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_LABEL,
50999
51057
(void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_LABEL,
51000
51058
(void*)&&ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_LABEL,
51059
+ (void*)&&ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_LABEL,
51060
+ (void*)&&ZEND_NULL_LABEL,
51061
+ (void*)&&ZEND_NULL_LABEL,
51062
+ (void*)&&ZEND_NULL_LABEL,
51063
+ (void*)&&ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_LABEL,
51064
+ (void*)&&ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_LABEL,
51065
+ (void*)&&ZEND_NULL_LABEL,
51066
+ (void*)&&ZEND_NULL_LABEL,
51067
+ (void*)&&ZEND_NULL_LABEL,
51068
+ (void*)&&ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_LABEL,
51001
51069
(void*)&&ZEND_NULL_LABEL,
51002
51070
(void*)&&ZEND_NULL_LABEL,
51003
51071
(void*)&&ZEND_NULL_LABEL,
@@ -55003,6 +55071,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
55003
55071
VM_TRACE(ZEND_IN_ARRAY_SPEC_CV_CONST)
55004
55072
ZEND_IN_ARRAY_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55005
55073
HYBRID_BREAK();
55074
+ HYBRID_CASE(ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST):
55075
+ VM_TRACE(ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST)
55076
+ ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55077
+ HYBRID_BREAK();
55078
+ HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST):
55079
+ VM_TRACE(ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST)
55080
+ ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55081
+ HYBRID_BREAK();
55006
55082
HYBRID_CASE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST):
55007
55083
VM_TRACE(ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST)
55008
55084
ZEND_FETCH_DIM_R_INDEX_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
@@ -55575,6 +55651,14 @@ ZEND_API void execute_ex(zend_execute_data *ex)
55575
55651
VM_TRACE(ZEND_YIELD_SPEC_CV_CV)
55576
55652
ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55577
55653
HYBRID_BREAK();
55654
+ HYBRID_CASE(ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV):
55655
+ VM_TRACE(ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV)
55656
+ ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55657
+ HYBRID_BREAK();
55658
+ HYBRID_CASE(ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV):
55659
+ VM_TRACE(ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV)
55660
+ ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
55661
+ HYBRID_BREAK();
55578
55662
HYBRID_CASE(HYBRID_HALT):
55579
55663
#ifdef ZEND_VM_FP_GLOBAL_REG
55580
55664
execute_data = orig_execute_data;
@@ -58486,6 +58570,16 @@ void zend_vm_init(void)
58486
58570
ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_HANDLER,
58487
58571
ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPZ_HANDLER,
58488
58572
ZEND_IS_NOT_EQUAL_DOUBLE_SPEC_TMPVARCV_TMPVARCV_JMPNZ_HANDLER,
58573
+ ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER,
58574
+ ZEND_NULL_HANDLER,
58575
+ ZEND_NULL_HANDLER,
58576
+ ZEND_NULL_HANDLER,
58577
+ ZEND_IS_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER,
58578
+ ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CONST_HANDLER,
58579
+ ZEND_NULL_HANDLER,
58580
+ ZEND_NULL_HANDLER,
58581
+ ZEND_NULL_HANDLER,
58582
+ ZEND_IS_NOT_IDENTICAL_NOTHROW_SPEC_CV_CV_HANDLER,
58489
58583
ZEND_NULL_HANDLER,
58490
58584
ZEND_NULL_HANDLER,
58491
58585
ZEND_NULL_HANDLER,
@@ -59050,7 +59144,7 @@ void zend_vm_init(void)
59050
59144
2280,
59051
59145
2281 | SPEC_RULE_OP1,
59052
59146
2286 | SPEC_RULE_OP1 | SPEC_RULE_OP2,
59053
- 3203
59147
+ 3213
59054
59148
};
59055
59149
#if (ZEND_VM_KIND == ZEND_VM_KIND_HYBRID)
59056
59150
zend_opcode_handler_funcs = labels;
@@ -59285,6 +59379,8 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
59285
59379
break;
59286
59380
}
59287
59381
spec = 2612 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
59382
+ } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
59383
+ spec = 2837 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
59288
59384
}
59289
59385
break;
59290
59386
case ZEND_IS_NOT_IDENTICAL:
@@ -59301,6 +59397,8 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
59301
59397
break;
59302
59398
}
59303
59399
spec = 2762 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH | SPEC_RULE_COMMUTATIVE;
59400
+ } else if (op->op1_type == IS_CV && (op->op2_type & (IS_CONST|IS_CV)) && !(op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) && !(op2_info & (MAY_BE_UNDEF|MAY_BE_REF))) {
59401
+ spec = 2842 | SPEC_RULE_OP2 | SPEC_RULE_COMMUTATIVE;
59304
59402
}
59305
59403
break;
59306
59404
case ZEND_IS_EQUAL:
@@ -59340,62 +59438,62 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
59340
59438
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
59341
59439
break;
59342
59440
}
59343
- spec = 2837 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59441
+ spec = 2847 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59344
59442
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
59345
59443
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
59346
59444
break;
59347
59445
}
59348
- spec = 2912 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59446
+ spec = 2922 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59349
59447
}
59350
59448
break;
59351
59449
case ZEND_IS_SMALLER_OR_EQUAL:
59352
59450
if (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG) {
59353
59451
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
59354
59452
break;
59355
59453
}
59356
- spec = 2987 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59454
+ spec = 2997 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59357
59455
} else if (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE) {
59358
59456
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
59359
59457
break;
59360
59458
}
59361
- spec = 3062 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59459
+ spec = 3072 | SPEC_RULE_OP1 | SPEC_RULE_OP2 | SPEC_RULE_SMART_BRANCH;
59362
59460
}
59363
59461
break;
59364
59462
case ZEND_QM_ASSIGN:
59365
59463
if (op1_info == MAY_BE_LONG) {
59366
- spec = 3149 | SPEC_RULE_OP1;
59464
+ spec = 3159 | SPEC_RULE_OP1;
59367
59465
} else if (op1_info == MAY_BE_DOUBLE) {
59368
- spec = 3154 | SPEC_RULE_OP1;
59466
+ spec = 3164 | SPEC_RULE_OP1;
59369
59467
} else if ((op->op1_type == IS_CONST) ? !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1)) : (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE))))) {
59370
- spec = 3159 | SPEC_RULE_OP1;
59468
+ spec = 3169 | SPEC_RULE_OP1;
59371
59469
}
59372
59470
break;
59373
59471
case ZEND_PRE_INC:
59374
59472
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
59375
- spec = 3137 | SPEC_RULE_RETVAL;
59473
+ spec = 3147 | SPEC_RULE_RETVAL;
59376
59474
} else if (op1_info == MAY_BE_LONG) {
59377
- spec = 3139 | SPEC_RULE_RETVAL;
59475
+ spec = 3149 | SPEC_RULE_RETVAL;
59378
59476
}
59379
59477
break;
59380
59478
case ZEND_PRE_DEC:
59381
59479
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
59382
- spec = 3141 | SPEC_RULE_RETVAL;
59480
+ spec = 3151 | SPEC_RULE_RETVAL;
59383
59481
} else if (op1_info == MAY_BE_LONG) {
59384
- spec = 3143 | SPEC_RULE_RETVAL;
59482
+ spec = 3153 | SPEC_RULE_RETVAL;
59385
59483
}
59386
59484
break;
59387
59485
case ZEND_POST_INC:
59388
59486
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
59389
- spec = 3145 ;
59487
+ spec = 3155 ;
59390
59488
} else if (op1_info == MAY_BE_LONG) {
59391
- spec = 3146 ;
59489
+ spec = 3156 ;
59392
59490
}
59393
59491
break;
59394
59492
case ZEND_POST_DEC:
59395
59493
if (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG) {
59396
- spec = 3147 ;
59494
+ spec = 3157 ;
59397
59495
} else if (op1_info == MAY_BE_LONG) {
59398
- spec = 3148 ;
59496
+ spec = 3158 ;
59399
59497
}
59400
59498
break;
59401
59499
case ZEND_JMP:
@@ -59405,35 +59503,35 @@ ZEND_API void ZEND_FASTCALL zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t
59405
59503
break;
59406
59504
case ZEND_SEND_VAL:
59407
59505
if (op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
59408
- spec = 3199 ;
59506
+ spec = 3209 ;
59409
59507
}
59410
59508
break;
59411
59509
case ZEND_SEND_VAR_EX:
59412
59510
if (op->op2.num <= MAX_ARG_FLAG_NUM && (op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
59413
- spec = 3194 | SPEC_RULE_OP1;
59511
+ spec = 3204 | SPEC_RULE_OP1;
59414
59512
}
59415
59513
break;
59416
59514
case ZEND_FE_FETCH_R:
59417
59515
if (op->op2_type == IS_CV && (op1_info & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF)) == MAY_BE_ARRAY) {
59418
- spec = 3201 | SPEC_RULE_RETVAL;
59516
+ spec = 3211 | SPEC_RULE_RETVAL;
59419
59517
}
59420
59518
break;
59421
59519
case ZEND_FETCH_DIM_R:
59422
59520
if (!(op2_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_REF))) {
59423
59521
if (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {
59424
59522
break;
59425
59523
}
59426
- spec = 3164 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
59524
+ spec = 3174 | SPEC_RULE_OP1 | SPEC_RULE_OP2;
59427
59525
}
59428
59526
break;
59429
59527
case ZEND_SEND_VAL_EX:
59430
59528
if (op->op2.num <= MAX_ARG_FLAG_NUM && op->op1_type == IS_CONST && !Z_REFCOUNTED_P(RT_CONSTANT(op, op->op1))) {
59431
- spec = 3200 ;
59529
+ spec = 3210 ;
59432
59530
}
59433
59531
break;
59434
59532
case ZEND_SEND_VAR:
59435
59533
if ((op1_info & (MAY_BE_UNDEF|MAY_BE_REF)) == 0) {
59436
- spec = 3189 | SPEC_RULE_OP1;
59534
+ spec = 3199 | SPEC_RULE_OP1;
59437
59535
}
59438
59536
break;
59439
59537
case ZEND_BW_OR:
0 commit comments