summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-01-28 14:59:54 +0300
committerDmitry Stogov <dmitry@zend.com>2015-01-28 14:59:54 +0300
commit61e739187391661e2d541947bec25d7dcc4479f3 (patch)
tree5249c6660c839583978ef7335acb6c54cc2d18e1
parent92e90c09f085c22707ff4a59201f016f56e0ef8b (diff)
downloadphp-git-61e739187391661e2d541947bec25d7dcc4479f3.tar.gz
Fixed temporary variable re-allocation pass
-rw-r--r--Zend/tests/foreach_005.phpt22
-rw-r--r--ext/opcache/Optimizer/optimize_temp_vars_5.c23
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 */