Skip to content

Commit 3cfa846

Browse files
committed
Add zend_is_op_long_compatible() function instead of repeating the check multiple times
1 parent 14881dc commit 3cfa846

File tree

3 files changed

+25
-22
lines changed

3 files changed

+25
-22
lines changed

Zend/Optimizer/pass1.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,9 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
121121
|| opline->extended_value == ZEND_SR) {
122122
zval *op2 = &ZEND_OP2_LITERAL(opline);
123123
if (Z_TYPE_P(op2) != IS_LONG) {
124-
/* Don't optimize if it should produce an incompatible float to int error */
125-
// TODO There must be a better way
126-
if (Z_TYPE_P(op2) == IS_DOUBLE
127-
&& !zend_is_long_compatible(
128-
Z_DVAL_P(op2), zend_dval_to_lval(Z_DVAL_P(op2)))) {
124+
if (!zend_is_op_long_compatible(op2)) {
129125
break;
130126
}
131-
/* don't optimize if it should produce a runtime numeric string error */
132-
if (Z_TYPE_P(op2) == IS_STRING) {
133-
double dval = 0;
134-
zend_uchar is_num = is_numeric_string(Z_STRVAL_P(op2),
135-
Z_STRLEN_P(op2), NULL, &dval, /* allow_errors */ false);
136-
if (is_num == 0 || (is_num == IS_DOUBLE && !zend_is_long_compatible(dval, zend_dval_to_lval(dval)))) {
137-
break;
138-
}
139-
}
140127
convert_to_long(op2);
141128
}
142129
} else if (opline->extended_value == ZEND_CONCAT) {

Zend/zend_compile.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8156,6 +8156,27 @@ static bool zend_try_ct_eval_magic_const(zval *zv, zend_ast *ast) /* {{{ */
81568156
}
81578157
/* }}} */
81588158

8159+
ZEND_API bool zend_is_op_long_compatible(zval *op)
8160+
{
8161+
/* This is handled before */
8162+
ZEND_ASSERT(Z_TYPE_P(op) != IS_ARRAY);
8163+
8164+
if (Z_TYPE_P(op) == IS_DOUBLE
8165+
&& !zend_is_long_compatible(Z_DVAL_P(op), zend_dval_to_lval(Z_DVAL_P(op)))) {
8166+
return false;
8167+
}
8168+
8169+
if (Z_TYPE_P(op) == IS_STRING) {
8170+
double dval = 0;
8171+
zend_uchar is_num = is_numeric_str_function(Z_STR_P(op), NULL, &dval);
8172+
if (is_num == 0 || (is_num == IS_DOUBLE && !zend_is_long_compatible(dval, zend_dval_to_lval(dval)))) {
8173+
return false;
8174+
}
8175+
}
8176+
8177+
return true;
8178+
}
8179+
81598180
ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, zval *op1, zval *op2) /* {{{ */
81608181
{
81618182
if ((opcode == ZEND_CONCAT || opcode == ZEND_FAST_CONCAT)) {
@@ -8210,13 +8231,7 @@ ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, zval *op1, zval *op
82108231
/* Operation which cast float/float-strings to integers might produce incompatible float to int errors */
82118232
if (opcode == ZEND_SL || opcode == ZEND_SR || opcode == ZEND_BW_OR
82128233
|| opcode == ZEND_BW_AND || opcode == ZEND_BW_XOR || opcode == ZEND_MOD) {
8213-
if (Z_TYPE_P(op1) == IS_DOUBLE || Z_TYPE_P(op2) == IS_DOUBLE) {
8214-
return true;
8215-
}
8216-
if ((Z_TYPE_P(op1) == IS_STRING && is_numeric_str_function(Z_STR_P(op1), NULL, NULL) != IS_LONG)
8217-
|| (Z_TYPE_P(op2) == IS_STRING && is_numeric_str_function(Z_STR_P(op2), NULL, NULL) != IS_LONG)) {
8218-
return true;
8219-
}
8234+
return (!zend_is_op_long_compatible(op1) || !zend_is_op_long_compatible(op2));
82208235
}
82218236

82228237
return 0;
@@ -8238,7 +8253,7 @@ static inline bool zend_try_ct_eval_binary_op(zval *result, uint32_t opcode, zva
82388253
ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, zval *op)
82398254
{
82408255
if (opcode == ZEND_BW_NOT) {
8241-
return (Z_TYPE_P(op) <= IS_TRUE || Z_TYPE_P(op) == IS_ARRAY || Z_TYPE_P(op) == IS_DOUBLE);
8256+
return (Z_TYPE_P(op) <= IS_TRUE || Z_TYPE_P(op) == IS_ARRAY || !zend_is_op_long_compatible(op));
82428257
}
82438258

82448259
return 0;

Zend/zend_compile.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,7 @@ END_EXTERN_C()
11621162
/* The default value for CG(compiler_options) during eval() */
11631163
#define ZEND_COMPILE_DEFAULT_FOR_EVAL 0
11641164

1165+
ZEND_API bool zend_is_op_long_compatible(zval *op);
11651166
ZEND_API bool zend_binary_op_produces_error(uint32_t opcode, zval *op1, zval *op2);
11661167
ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, zval *op);
11671168

0 commit comments

Comments
 (0)