diff options
author | Dmitry Stogov <dmitry@zend.com> | 2015-01-28 14:59:54 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2015-01-28 14:59:54 +0300 |
commit | 61e739187391661e2d541947bec25d7dcc4479f3 (patch) | |
tree | 5249c6660c839583978ef7335acb6c54cc2d18e1 | |
parent | 92e90c09f085c22707ff4a59201f016f56e0ef8b (diff) | |
download | php-git-61e739187391661e2d541947bec25d7dcc4479f3.tar.gz |
Fixed temporary variable re-allocation pass
-rw-r--r-- | Zend/tests/foreach_005.phpt | 22 | ||||
-rw-r--r-- | ext/opcache/Optimizer/optimize_temp_vars_5.c | 23 |
2 files changed, 37 insertions, 8 deletions
diff --git a/Zend/tests/foreach_005.phpt b/Zend/tests/foreach_005.phpt new file mode 100644 index 0000000000..6ed9fe940b --- /dev/null +++ b/Zend/tests/foreach_005.phpt @@ -0,0 +1,22 @@ +--TEST-- +Nested foreach by reference on the same array +--FILE-- +<?php +$a = [1,2,3]; +foreach($a as &$x) { + foreach($a as &$y) { + echo "$x-$y\n"; + $y++; + } +} +?> +--EXPECT-- +1-1 +2-2 +2-3 +3-2 +3-3 +4-4 +5-3 +5-4 +5-5 diff --git a/ext/opcache/Optimizer/optimize_temp_vars_5.c b/ext/opcache/Optimizer/optimize_temp_vars_5.c index ac5389ed2b..7ff94ddae5 100644 --- a/ext/opcache/Optimizer/optimize_temp_vars_5.c +++ b/ext/opcache/Optimizer/optimize_temp_vars_5.c @@ -69,9 +69,8 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c /* special puprose variable to keep HashTable* on VM stack */ if (opline->opcode == ZEND_OP_DATA && (opline-1)->opcode == ZEND_FE_FETCH_RW && - (opline-2)->opcode == ZEND_FE_RESET_RW && opline->op1_type == IS_TMP_VAR) { - start_of_T[VAR_NUM(ZEND_OP1(opline).var) - offset] = opline - 2; + start_of_T[VAR_NUM(ZEND_OP1(opline).var) - offset] = opline; } opline--; } @@ -85,13 +84,21 @@ void optimize_temporary_variables(zend_op_array *op_array, zend_optimizer_ctx *c while (opline >= end) { if ((ZEND_OP1_TYPE(opline) & (IS_VAR | IS_TMP_VAR))) { - currT = VAR_NUM(ZEND_OP1(opline).var) - offset; - if (!valid_T[currT]) { - GET_AVAILABLE_T(); - map_T[currT] = i; - valid_T[currT] = 1; + /* special puprose variable to keep HashPointer on VM stack */ + if (opline->opcode == ZEND_OP_DATA && + (opline-1)->opcode == ZEND_FE_FETCH_RW && + opline->op1_type == IS_TMP_VAR) { + max++; + ZEND_OP1(opline).var = NUM_VAR(max + offset); + } else { + currT = VAR_NUM(ZEND_OP1(opline).var) - offset; + if (!valid_T[currT]) { + GET_AVAILABLE_T(); + map_T[currT] = i; + valid_T[currT] = 1; + } + ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset); } - ZEND_OP1(opline).var = NUM_VAR(map_T[currT] + offset); } /* Skip OP_DATA */ |