diff options
author | Dmitry Stogov <dmitry@zend.com> | 2013-04-10 15:33:08 +0400 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2013-04-10 15:33:08 +0400 |
commit | 7845f49006cbe7876a7e28db54acbc8cde284986 (patch) | |
tree | 84830679109e307cf7b9f7e5272aeb91a750b5ab | |
parent | 2e3e87029fe464bb61dd0a18a6af59c30527e9e4 (diff) | |
download | php-git-7845f49006cbe7876a7e28db54acbc8cde284986.tar.gz |
Numeric string constants used as array indeces have to be converted to long at compile time
-rw-r--r-- | ext/opcache/Optimizer/block_pass.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c index 05cb15acc9..d46ac0eace 100644 --- a/ext/opcache/Optimizer/block_pass.c +++ b/ext/opcache/Optimizer/block_pass.c @@ -612,6 +612,46 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array, VAR_UNSET(opline->op2); COPY_NODE(opline->op2, src->op1); MAKE_NOP(src); + + /* numeric string constants used as array indeces have to be + converted to long at compile time */ + if (opline->opcode == ZEND_ADD_ARRAY_ELEMENT || + opline->opcode == ZEND_INIT_ARRAY || + opline->opcode == ZEND_UNSET_DIM || + opline->opcode == ZEND_ISSET_ISEMPTY_DIM_OBJ || + opline->opcode == ZEND_FETCH_DIM_R || + opline->opcode == ZEND_FETCH_DIM_W || + opline->opcode == ZEND_FETCH_DIM_RW || + opline->opcode == ZEND_FETCH_DIM_IS || + opline->opcode == ZEND_FETCH_DIM_FUNC_ARG || + opline->opcode == ZEND_FETCH_DIM_UNSET || + opline->opcode == ZEND_FETCH_DIM_TMP_VAR || + (opline->opcode == ZEND_OP_DATA && + ((opline-1)->opcode == ZEND_ASSIGN_DIM || + ((opline-1)->extended_value == ZEND_ASSIGN_DIM && + ((opline-1)->opcode == ZEND_ASSIGN_ADD || + (opline-1)->opcode == ZEND_ASSIGN_SUB || + (opline-1)->opcode == ZEND_ASSIGN_MUL || + (opline-1)->opcode == ZEND_ASSIGN_DIV || + (opline-1)->opcode == ZEND_ASSIGN_MOD || + (opline-1)->opcode == ZEND_ASSIGN_SL || + (opline-1)->opcode == ZEND_ASSIGN_SR || + (opline-1)->opcode == ZEND_ASSIGN_CONCAT || + (opline-1)->opcode == ZEND_ASSIGN_BW_OR || + (opline-1)->opcode == ZEND_ASSIGN_BW_AND || + (opline-1)->opcode == ZEND_ASSIGN_BW_XOR))))) { + + if (Z_TYPE(ZEND_OP2_LITERAL(opline)) == IS_STRING) { + ulong index; + int numeric = 0; + + ZEND_HANDLE_NUMERIC_EX(Z_STRVAL(ZEND_OP2_LITERAL(opline)), Z_STRLEN(ZEND_OP2_LITERAL(opline))+1, index, numeric = 1); + if (numeric) { + zval_dtor(&ZEND_OP2_LITERAL(opline)); + ZVAL_LONG(&ZEND_OP2_LITERAL(opline), index); + } + } + } } /* T = PRINT(X), F(T) => ECHO(X), F(1) */ |