From 56b18d478ed9e40afd66860e82017d5c2017eac1 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 1 Apr 2020 14:35:01 +0200 Subject: [PATCH] Don't convert binop operand types in opcache This may produce different behavior if operator overloading is involved, and may change the error message. If there's strong interest, this could be done in the DFA pass with available type information. It does not look particularly practically useful to me though. --- ext/opcache/Optimizer/pass1.c | 60 +++++------------------------------ 1 file changed, 8 insertions(+), 52 deletions(-) diff --git a/ext/opcache/Optimizer/pass1.c b/ext/opcache/Optimizer/pass1.c index 7d244a283c..9219e5e19e 100644 --- a/ext/opcache/Optimizer/pass1.c +++ b/ext/opcache/Optimizer/pass1.c @@ -45,58 +45,6 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) while (opline < end) { switch (opline->opcode) { - case ZEND_ADD: - case ZEND_SUB: - case ZEND_MUL: - case ZEND_DIV: - case ZEND_POW: - if (opline->op1_type == IS_CONST) { - if (Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) { - /* don't optimise if it should produce a runtime numeric string error */ - if (is_numeric_string(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)), NULL, NULL, 0)) { - convert_scalar_to_number(&ZEND_OP1_LITERAL(opline)); - } - } - } - if (opline->op2_type == IS_CONST) { - if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { - /* don't optimise if it should produce a runtime numeric string error */ - if (is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0)) { - convert_scalar_to_number(&ZEND_OP2_LITERAL(opline)); - } - } - if (opline->op1_type == IS_CONST) { - goto constant_binary_op; - } - } - break; - - case ZEND_MOD: - case ZEND_SL: - case ZEND_SR: - if (opline->op1_type == IS_CONST) { - if (Z_TYPE(ZEND_OP1_LITERAL(opline)) != IS_LONG) { - /* don't optimise if it should produce a runtime numeric string error */ - if (!(Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING - && !is_numeric_string(Z_STRVAL(ZEND_OP1_LITERAL(opline)), Z_STRLEN(ZEND_OP1_LITERAL(opline)), NULL, NULL, 0))) { - convert_to_long(&ZEND_OP1_LITERAL(opline)); - } - } - } - if (opline->op2_type == IS_CONST) { - if (Z_TYPE(ZEND_OP2_LITERAL(opline)) != IS_LONG) { - /* don't optimise if it should produce a runtime numeric string error */ - if (!(Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING - && !is_numeric_string(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline)), NULL, NULL, 0))) { - convert_to_long(&ZEND_OP2_LITERAL(opline)); - } - } - if (opline->op1_type == IS_CONST) { - goto constant_binary_op; - } - } - break; - case ZEND_CONCAT: case ZEND_FAST_CONCAT: if (opline->op1_type == IS_CONST) { @@ -114,6 +62,14 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx) } break; + case ZEND_ADD: + case ZEND_SUB: + case ZEND_MUL: + case ZEND_DIV: + case ZEND_POW: + case ZEND_MOD: + case ZEND_SL: + case ZEND_SR: case ZEND_BW_OR: case ZEND_BW_AND: case ZEND_BW_XOR: -- 2.50.1