@@ -276,7 +276,34 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
276
276
}
277
277
}
278
278
279
- #define convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , op , op_func ) \
279
+ #define ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (opcode ) \
280
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
281
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation))) { \
282
+ if (EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, op2))) { \
283
+ return SUCCESS; \
284
+ } \
285
+ }
286
+
287
+ #define ZEND_TRY_BINARY_OP2_OBJECT_OPERATION (opcode ) \
288
+ if (UNEXPECTED(Z_TYPE_P(op2) == IS_OBJECT) \
289
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op2, do_operation)) \
290
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op2, do_operation)(opcode, result, op1, op2))) { \
291
+ return SUCCESS; \
292
+ }
293
+
294
+ #define ZEND_TRY_BINARY_OBJECT_OPERATION (opcode ) \
295
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(opcode) \
296
+ else \
297
+ ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(opcode)
298
+
299
+ #define ZEND_TRY_UNARY_OBJECT_OPERATION (opcode ) \
300
+ if (UNEXPECTED(Z_TYPE_P(op1) == IS_OBJECT) \
301
+ && UNEXPECTED(Z_OBJ_HANDLER_P(op1, do_operation)) \
302
+ && EXPECTED(SUCCESS == Z_OBJ_HANDLER_P(op1, do_operation)(opcode, result, op1, NULL))) { \
303
+ return SUCCESS; \
304
+ }
305
+
306
+ #define convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , op ) \
280
307
do { \
281
308
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) { \
282
309
if (Z_ISREF_P(op1)) { \
@@ -286,7 +313,7 @@ static zend_always_inline int zendi_try_convert_scalar_to_number(zval *op, zval
286
313
break; \
287
314
} \
288
315
} \
289
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op, op_func); \
316
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(op); \
290
317
op1_lval = _zval_get_long_func_noisy(op1); \
291
318
if (UNEXPECTED(EG(exception))) { \
292
319
if (result != op1) { \
@@ -959,7 +986,7 @@ static zend_never_inline int ZEND_FASTCALL add_function_slow(zval *result, zval
959
986
return SUCCESS ;
960
987
}
961
988
962
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_ADD , add_function );
989
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_ADD );
963
990
964
991
zval op1_copy , op2_copy ;
965
992
if (UNEXPECTED (zendi_try_convert_scalar_to_number (op1 , & op1_copy ) == FAILURE )
@@ -1024,7 +1051,7 @@ static zend_never_inline int ZEND_FASTCALL sub_function_slow(zval *result, zval
1024
1051
return SUCCESS ;
1025
1052
}
1026
1053
1027
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_SUB , sub_function );
1054
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_SUB );
1028
1055
1029
1056
zval op1_copy , op2_copy ;
1030
1057
if (UNEXPECTED (zendi_try_convert_scalar_to_number (op1 , & op1_copy ) == FAILURE )
@@ -1093,7 +1120,7 @@ static zend_never_inline int ZEND_FASTCALL mul_function_slow(zval *result, zval
1093
1120
return SUCCESS ;
1094
1121
}
1095
1122
1096
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_MUL , mul_function );
1123
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_MUL );
1097
1124
1098
1125
zval op1_copy , op2_copy ;
1099
1126
if (UNEXPECTED (zendi_try_convert_scalar_to_number (op1 , & op1_copy ) == FAILURE )
@@ -1194,7 +1221,7 @@ ZEND_API int ZEND_FASTCALL pow_function(zval *result, zval *op1, zval *op2) /* {
1194
1221
return SUCCESS ;
1195
1222
}
1196
1223
1197
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_POW , pow_function );
1224
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_POW );
1198
1225
1199
1226
zval op1_copy , op2_copy ;
1200
1227
if (UNEXPECTED (zendi_try_convert_scalar_to_number (op1 , & op1_copy ) == FAILURE )
@@ -1274,7 +1301,7 @@ ZEND_API int ZEND_FASTCALL div_function(zval *result, zval *op1, zval *op2) /* {
1274
1301
return SUCCESS ;
1275
1302
}
1276
1303
1277
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_DIV , div_function );
1304
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_DIV );
1278
1305
1279
1306
zval op1_copy , op2_copy ;
1280
1307
if (UNEXPECTED (zendi_try_convert_scalar_to_number (op1 , & op1_copy ) == FAILURE )
@@ -1304,7 +1331,7 @@ ZEND_API int ZEND_FASTCALL mod_function(zval *result, zval *op1, zval *op2) /* {
1304
1331
{
1305
1332
zend_long op1_lval , op2_lval ;
1306
1333
1307
- convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_MOD , mod_function );
1334
+ convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_MOD );
1308
1335
1309
1336
if (op2_lval == 0 ) {
1310
1337
/* modulus by zero */
@@ -1354,7 +1381,7 @@ ZEND_API int ZEND_FASTCALL boolean_xor_function(zval *result, zval *op1, zval *o
1354
1381
break ;
1355
1382
}
1356
1383
}
1357
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BOOL_XOR , boolean_xor_function );
1384
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BOOL_XOR );
1358
1385
op1_val = zval_is_true (op1 );
1359
1386
}
1360
1387
} while (0 );
@@ -1495,7 +1522,7 @@ ZEND_API int ZEND_FASTCALL bitwise_or_function(zval *result, zval *op1, zval *op
1495
1522
}
1496
1523
1497
1524
if (UNEXPECTED (Z_TYPE_P (op1 ) != IS_LONG )) {
1498
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_OR , bitwise_or_function );
1525
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_OR );
1499
1526
op1_lval = _zval_get_long_func_noisy (op1 );
1500
1527
if (UNEXPECTED (EG (exception ))) {
1501
1528
if (result != op1 ) {
@@ -1573,7 +1600,7 @@ ZEND_API int ZEND_FASTCALL bitwise_and_function(zval *result, zval *op1, zval *o
1573
1600
}
1574
1601
1575
1602
if (UNEXPECTED (Z_TYPE_P (op1 ) != IS_LONG )) {
1576
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_AND , bitwise_and_function );
1603
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_AND );
1577
1604
op1_lval = _zval_get_long_func_noisy (op1 );
1578
1605
if (UNEXPECTED (EG (exception ))) {
1579
1606
if (result != op1 ) {
@@ -1651,7 +1678,7 @@ ZEND_API int ZEND_FASTCALL bitwise_xor_function(zval *result, zval *op1, zval *o
1651
1678
}
1652
1679
1653
1680
if (UNEXPECTED (Z_TYPE_P (op1 ) != IS_LONG )) {
1654
- ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_XOR , bitwise_xor_function );
1681
+ ZEND_TRY_BINARY_OP1_OBJECT_OPERATION (ZEND_BW_XOR );
1655
1682
op1_lval = _zval_get_long_func_noisy (op1 );
1656
1683
if (UNEXPECTED (EG (exception ))) {
1657
1684
if (result != op1 ) {
@@ -1687,7 +1714,7 @@ ZEND_API int ZEND_FASTCALL shift_left_function(zval *result, zval *op1, zval *op
1687
1714
{
1688
1715
zend_long op1_lval , op2_lval ;
1689
1716
1690
- convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_SL , shift_left_function );
1717
+ convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_SL );
1691
1718
1692
1719
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
1693
1720
if (UNEXPECTED ((zend_ulong )op2_lval >= SIZEOF_ZEND_LONG * 8 )) {
@@ -1724,7 +1751,7 @@ ZEND_API int ZEND_FASTCALL shift_right_function(zval *result, zval *op1, zval *o
1724
1751
{
1725
1752
zend_long op1_lval , op2_lval ;
1726
1753
1727
- convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_SR , shift_right_function );
1754
+ convert_op1_op2_long (op1 , op1_lval , op2 , op2_lval , result , ZEND_SR );
1728
1755
1729
1756
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
1730
1757
if (UNEXPECTED ((zend_ulong )op2_lval >= SIZEOF_ZEND_LONG * 8 )) {
@@ -1770,7 +1797,7 @@ ZEND_API int ZEND_FASTCALL concat_function(zval *result, zval *op1, zval *op2) /
1770
1797
op1 = Z_REFVAL_P (op1 );
1771
1798
if (Z_TYPE_P (op1 ) == IS_STRING ) break ;
1772
1799
}
1773
- ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_CONCAT , concat_function );
1800
+ ZEND_TRY_BINARY_OBJECT_OPERATION (ZEND_CONCAT );
1774
1801
ZVAL_STR (& op1_copy , zval_get_string_func (op1 ));
1775
1802
if (UNEXPECTED (EG (exception ))) {
1776
1803
zval_ptr_dtor_str (& op1_copy );
0 commit comments