summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2013-04-10 15:33:08 +0400
committerDmitry Stogov <dmitry@zend.com>2013-04-10 15:33:08 +0400
commit7845f49006cbe7876a7e28db54acbc8cde284986 (patch)
tree84830679109e307cf7b9f7e5272aeb91a750b5ab
parent2e3e87029fe464bb61dd0a18a6af59c30527e9e4 (diff)
downloadphp-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.c40
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) */