From 4638f7b91407c48710007af82a68da0007c820f2 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Jan 2015 07:43:28 +0300 Subject: Change "foreach" statement behavior (this is just a PoC yet) - "foreach by value" don't relay on internal array/object pointer and doesnt perform array duplication. It just locks it incrementing reference counter. If the original array is modified by some code, the copy on write is performed and "foreach" still work with the old copy. - it makes no difference if array given to "foreach by value" is reference itself - "foreach by reference" still use internal array/object pointer and should work similar to PHP-5. (This id not completely implemented) --- Zend/tests/bug40509.phpt | 2 +- Zend/tests/bug40705.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'Zend/tests') diff --git a/Zend/tests/bug40509.phpt b/Zend/tests/bug40509.phpt index 21eaae9444..65e32533ef 100644 --- a/Zend/tests/bug40509.phpt +++ b/Zend/tests/bug40509.phpt @@ -23,4 +23,4 @@ var_dump(key($arr["v"])); int(0) int(0) int(0) -NULL +int(0) diff --git a/Zend/tests/bug40705.phpt b/Zend/tests/bug40705.phpt index 374f73b75e..8a679654d5 100644 --- a/Zend/tests/bug40705.phpt +++ b/Zend/tests/bug40705.phpt @@ -23,4 +23,4 @@ int(0) int(0) int(1) int(2) -NULL +int(0) -- cgit v1.2.1 From 92e90c09f085c22707ff4a59201f016f56e0ef8b Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Jan 2015 12:44:57 +0300 Subject: Fixed operand destruction in case of exceptions in iterator --- Zend/tests/foreach_003.phpt | 71 +++++++++++++++++++++++++++++++++++++++++++++ Zend/tests/foreach_004.phpt | 65 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 Zend/tests/foreach_003.phpt create mode 100644 Zend/tests/foreach_004.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_003.phpt b/Zend/tests/foreach_003.phpt new file mode 100644 index 0000000000..71b0f2a5a3 --- /dev/null +++ b/Zend/tests/foreach_003.phpt @@ -0,0 +1,71 @@ +--TEST-- +Iterator exceptions in foreach by value +--FILE-- +count = $count; + $this->trap = $trap; + } + + function trap($trap) { + if ($trap === $this->trap) { + throw new Exception($trap); + } + } + + function rewind() {$this->trap(__FUNCTION__); $this->n = 0;} + function valid() {$this->trap(__FUNCTION__); return $this->n < $this->count;} + function key() {$this->trap(__FUNCTION__); return $this->n;} + function current() {$this->trap(__FUNCTION__); return $this->n;} + function next() {$this->trap(__FUNCTION__); $this->n++;} +} + +foreach(['rewind', 'valid', 'key', 'current', 'next'] as $trap) { + $obj = new IT(3, $trap); + try { + // IS_CV + foreach ($obj as $key => $val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + unset($obj); + + try { + // IS_VAR + foreach (new IT(3, $trap) as $key => $val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + + try { + // IS_TMP_VAR + foreach ((object)new IT(2, $trap) as $key => $val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +rewind +rewind +rewind +valid +valid +valid +key +key +key +current +current +current +0 +next +0 +next +0 +next diff --git a/Zend/tests/foreach_004.phpt b/Zend/tests/foreach_004.phpt new file mode 100644 index 0000000000..1f754a77ed --- /dev/null +++ b/Zend/tests/foreach_004.phpt @@ -0,0 +1,65 @@ +--TEST-- +Iterator exceptions in foreach by reference +--FILE-- +trap = $trap; + } + + function trap($trap) { + if ($trap === $this->trap) { + throw new Exception($trap); + } + } + + function rewind() {$this->trap(__FUNCTION__); return parent::rewind();} + function valid() {$this->trap(__FUNCTION__); return parent::valid();} + function key() {$this->trap(__FUNCTION__); return parent::key();} + function next() {$this->trap(__FUNCTION__); return parent::next();} +} + +foreach(['rewind', 'valid', 'key', 'next'] as $trap) { + $obj = new IT($trap); + try { + // IS_CV + foreach ($obj as $key => &$val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + unset($obj); + + try { + // IS_VAR + foreach (new IT($trap) as $key => &$val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + + try { + // IS_TMP_VAR + foreach ((object)new IT($trap) as $key => &$val) echo "$val\n"; + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +rewind +rewind +rewind +valid +valid +valid +key +key +key +0 +next +0 +next +0 +next -- cgit v1.2.1 From 61e739187391661e2d541947bec25d7dcc4479f3 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Jan 2015 14:59:54 +0300 Subject: Fixed temporary variable re-allocation pass --- Zend/tests/foreach_005.phpt | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 Zend/tests/foreach_005.phpt (limited to 'Zend/tests') 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-- + +--EXPECT-- +1-1 +2-2 +2-3 +3-2 +3-3 +4-4 +5-3 +5-4 +5-5 -- cgit v1.2.1 From eef80c583762d1e98d177cdbb27e3a8a6b0c4539 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Wed, 28 Jan 2015 16:52:21 +0300 Subject: Fixed foreach by reference iteration over constant array --- Zend/tests/foreach_006.phpt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 Zend/tests/foreach_006.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_006.phpt b/Zend/tests/foreach_006.phpt new file mode 100644 index 0000000000..65d6fdc52c --- /dev/null +++ b/Zend/tests/foreach_006.phpt @@ -0,0 +1,20 @@ +--TEST-- +Foreach by reference on constant +--FILE-- + +--EXPECT-- +1 +2 +3 +1 +2 +3 +1 +2 +3 -- cgit v1.2.1 From 10a3260b1f16b6075fd8140f673dfef4d5efea91 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 29 Jan 2015 21:04:44 +0300 Subject: New test --- Zend/tests/foreach_007.phpt | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 Zend/tests/foreach_007.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_007.phpt b/Zend/tests/foreach_007.phpt new file mode 100644 index 0000000000..b99bc73ebe --- /dev/null +++ b/Zend/tests/foreach_007.phpt @@ -0,0 +1,13 @@ +--TEST-- +Foreach by reference and inserting new element when we are already at the end +--FILE-- + +--EXPECT-- +1 +2 -- cgit v1.2.1 From 721fc9e80d2ee8f2cd79c8c3cdceffae2c72de92 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 29 Jan 2015 21:43:28 +0300 Subject: Added new test --- Zend/tests/foreach_008.phpt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Zend/tests/foreach_008.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_008.phpt b/Zend/tests/foreach_008.phpt new file mode 100644 index 0000000000..c68bcd89da --- /dev/null +++ b/Zend/tests/foreach_008.phpt @@ -0,0 +1,21 @@ +--TEST-- +Nested foreach by reference and array modification +--FILE-- + +--EXPECT-- +0 - 0 +0 - 1 +0 - 3 +3 - 0 +3 - 3 -- cgit v1.2.1 From 4c5b385ff53ae9f0b52572e98c4db801f56603b0 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 07:56:37 +0300 Subject: More careful iterators update. --- Zend/tests/foreach_009.phpt | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Zend/tests/foreach_009.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_009.phpt b/Zend/tests/foreach_009.phpt new file mode 100644 index 0000000000..6ce8384642 --- /dev/null +++ b/Zend/tests/foreach_009.phpt @@ -0,0 +1,40 @@ +--TEST-- +Nested foreach by reference and array modification with resize +--FILE-- + +--EXPECT-- +4-4 +4-5 +4-6 +4-7 +5-4 +5-5 +5-6 +5-7 +5-8 +6-4 +6-5 +6-6 +6-7 +6-8 +7-4 +7-5 +7-6 +7-7 +7-8 +8-4 +8-5 +8-6 +8-7 +8-8 -- cgit v1.2.1 From 5aa9712b0a30303aadfe3bdd8ae1f072ca3e6ba1 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 09:49:35 +0300 Subject: Implement consistent behavior for foreach by value over plain object --- Zend/tests/foreach_010.phpt | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Zend/tests/foreach_010.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_010.phpt b/Zend/tests/foreach_010.phpt new file mode 100644 index 0000000000..6ba7e7e9fd --- /dev/null +++ b/Zend/tests/foreach_010.phpt @@ -0,0 +1,40 @@ +--TEST-- +Nested foreach by value over object and object modification with resize +--FILE-- +0, 'b'=>1, 'c'=>2, 'd'=>3, 'e'=>4, 'f'=>5, 'g'=>6, 'h'=>7]; +unset($o->a, $o->b, $o->c, $o->d); +foreach ($o as $v1) { + foreach ($o as $v2) { + echo "$v1-$v2\n"; + if ($v1 == 5 && $v2 == 6) { + $o->i = 8; + } + } +} +?> +--EXPECT-- +4-4 +4-5 +4-6 +4-7 +5-4 +5-5 +5-6 +5-7 +5-8 +6-4 +6-5 +6-6 +6-7 +6-8 +7-4 +7-5 +7-6 +7-7 +7-8 +8-4 +8-5 +8-6 +8-7 +8-8 -- cgit v1.2.1 From cc4b7be41e2e2b9b0d7a3c8e98466b8886692e6e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 12:24:31 +0300 Subject: Make internal function, operation on array passed by reference, to preserve foreach hash position --- Zend/tests/foreach_011.phpt | 19 +++++++++++++++++++ Zend/tests/foreach_012.phpt | 18 ++++++++++++++++++ Zend/tests/foreach_013.phpt | 17 +++++++++++++++++ Zend/tests/foreach_014.phpt | 15 +++++++++++++++ Zend/tests/foreach_015.phpt | 18 ++++++++++++++++++ Zend/tests/foreach_016.phpt | 18 ++++++++++++++++++ 6 files changed, 105 insertions(+) create mode 100644 Zend/tests/foreach_011.phpt create mode 100644 Zend/tests/foreach_012.phpt create mode 100644 Zend/tests/foreach_013.phpt create mode 100644 Zend/tests/foreach_014.phpt create mode 100644 Zend/tests/foreach_015.phpt create mode 100644 Zend/tests/foreach_016.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_011.phpt b/Zend/tests/foreach_011.phpt new file mode 100644 index 0000000000..e91426fb27 --- /dev/null +++ b/Zend/tests/foreach_011.phpt @@ -0,0 +1,19 @@ +--TEST-- +sort() functions precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 +3 +2 +1 +0 diff --git a/Zend/tests/foreach_012.phpt b/Zend/tests/foreach_012.phpt new file mode 100644 index 0000000000..5e5538cd4d --- /dev/null +++ b/Zend/tests/foreach_012.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_walk() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 +3 +14 +15 \ No newline at end of file diff --git a/Zend/tests/foreach_013.phpt b/Zend/tests/foreach_013.phpt new file mode 100644 index 0000000000..cfbb3d7f79 --- /dev/null +++ b/Zend/tests/foreach_013.phpt @@ -0,0 +1,17 @@ +--TEST-- +array_push() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 +3 +4 diff --git a/Zend/tests/foreach_014.phpt b/Zend/tests/foreach_014.phpt new file mode 100644 index 0000000000..8d0ac582a9 --- /dev/null +++ b/Zend/tests/foreach_014.phpt @@ -0,0 +1,15 @@ +--TEST-- +array_pop() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 diff --git a/Zend/tests/foreach_015.phpt b/Zend/tests/foreach_015.phpt new file mode 100644 index 0000000000..adc8085f34 --- /dev/null +++ b/Zend/tests/foreach_015.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_shift() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 +3 +4 +array(0) { +} \ No newline at end of file diff --git a/Zend/tests/foreach_016.phpt b/Zend/tests/foreach_016.phpt new file mode 100644 index 0000000000..423c8dd0a6 --- /dev/null +++ b/Zend/tests/foreach_016.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_unshift() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +1 +2 +3 +int(11) -- cgit v1.2.1 From 08302c0d6d1cab279b9f2129df03a057baddf2ff Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 14:20:46 +0300 Subject: Make array_splice() to preserve foreach hash position --- Zend/tests/foreach_017.phpt | 111 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 Zend/tests/foreach_017.phpt (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_017.phpt b/Zend/tests/foreach_017.phpt new file mode 100644 index 0000000000..780d2e90fc --- /dev/null +++ b/Zend/tests/foreach_017.phpt @@ -0,0 +1,111 @@ +--TEST-- +array_unshift() function precerve foreach by reference iterator pointer +--FILE-- + +--EXPECT-- +0 +1 +2 +3 +4 + +0 +1 +4 + +0 +1 +2 +4 + +0 +1 +2 +3 +4 + +0 +1 +x +y +z +4 + +0 +1 +2 +4 -- cgit v1.2.1 From b37f1d58d2a141b6e1d980a461ccb588d4317d2e Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 30 Jan 2015 18:08:30 +0300 Subject: Fixed test name --- Zend/tests/foreach_017.phpt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Zend/tests') diff --git a/Zend/tests/foreach_017.phpt b/Zend/tests/foreach_017.phpt index 780d2e90fc..55eeeb0891 100644 --- a/Zend/tests/foreach_017.phpt +++ b/Zend/tests/foreach_017.phpt @@ -1,5 +1,5 @@ --TEST-- -array_unshift() function precerve foreach by reference iterator pointer +array_splice() function precerve foreach by reference iterator pointer --FILE--