From 5c00c0900115160a8bd28dbf6dd3fdf1a1dcd5d3 Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Mon, 25 Feb 2019 21:11:53 +0800 Subject: [PATCH 1/7] Add method Zephir\Variable::geVariantInits --- CHANGELOG.md | 8 ++++++-- Library/Variable.php | 10 ++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4fe0635c0..3bfdce6f8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Fixed +- Objects are not traversable with foreach + [#1818](https://github.com/phalcon/zephir/issues/1818) + [#1595](https://github.com/phalcon/zephir/issues/1595) ## [0.11.10] - 2019-02-23 ### Changed @@ -23,8 +27,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Fixed calling anonymous functions by resolving context [#1751](https://github.com/phalcon/zephir/issues/1751) - Fixed a bug when accessing super-global variables that do not exist (only for PHP >= 7.0 ) [#1775](https://github.com/phalcon/zephir/issues/1775) -- Fixed incorrect behavior during work with ArrayAccess [1061](https://github.com/phalcon/zephir/issues/1061), - [1400](https://github.com/phalcon/zephir/issues/1400) +- Fixed incorrect behavior during work with ArrayAccess [#1061](https://github.com/phalcon/zephir/issues/1061), + [#1400](https://github.com/phalcon/zephir/issues/1400) ## [0.11.9] - 2019-01-15 - Fixed `zend_closure` declaration to reflect PHP 7.3 changes diff --git a/Library/Variable.php b/Library/Variable.php index c5724d509a..2b99d7a9c4 100644 --- a/Library/Variable.php +++ b/Library/Variable.php @@ -790,6 +790,16 @@ public function initNonReferenced(CompilationContext $compilationContext) $compilationContext->codePrinter->output('ZEPHIR_INIT_ZVAL_NREF('.$this->getName().');'); } + /** + * Get the number of times the variable has been initialized. + * + * @return int + */ + public function geVariantInits() + { + return $this->variantInits; + } + /** * Increase the number of times the variable has been initialized. */ From 85762bf2ecdc81e2ef1ef601ea48ad846fc45965 Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Mon, 25 Feb 2019 21:12:37 +0800 Subject: [PATCH 2/7] Updated method Zephir\Expression\NativeArray::compile --- Library/Expression/NativeArray.php | 38 +++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index 788b259261..21a9f41685 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -180,7 +180,6 @@ public function compile($expression, CompilationContext $compilationContext) if ($this->expecting) { if ($this->expectingVariable) { $symbolVariable = $this->expectingVariable; - $symbolVariable->initVariant($compilationContext); if ('variable' != $symbolVariable->getType() && 'array' != $symbolVariable->getType()) { throw new CompilerException('Cannot use variable type: '.$symbolVariable->getType().' as an array', $expression); } @@ -191,17 +190,19 @@ public function compile($expression, CompilationContext $compilationContext) $symbolVariable = $compilationContext->symbolTable->getTempVariableForWrite('array', $compilationContext, $expression); } - /*+ - * Mark the variable as an array - */ - $symbolVariable->setDynamicTypes('array'); - - $codePrinter = $compilationContext->codePrinter; - if (!isset($expression['left'])) { + if ($this->expectingVariable) { + $symbolVariable->initVariant($compilationContext); + } + /*+ + * Mark the variable as an array + */ + $symbolVariable->setDynamicTypes('array'); return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); } + $codePrinter = $compilationContext->codePrinter; + $compilationContext->headersManager->add('kernel/array'); /** @@ -212,8 +213,23 @@ public function compile($expression, CompilationContext $compilationContext) if ($arrayLength >= 33 && \function_exists('gmp_nextprime')) { $arrayLength = gmp_strval(gmp_nextprime($arrayLength - 1)); } - $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null); + $oldSymbolVariable = $symbolVariable; + if ($symbolVariable->geVariantInits() >= 1) { + $symbolVariable = $compilationContext->symbolTable->addTemp('variable', $compilationContext); + $symbolVariable->initVariant($compilationContext); + $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null); + $symbolVariable->setDynamicTypes('array'); + } else { + if ($this->expectingVariable) { + $symbolVariable->initVariant($compilationContext); + } + /*+ + * Mark the variable as an array + */ + $symbolVariable->setDynamicTypes('array'); + $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null); + } foreach ($expression['left'] as $item) { if (isset($item['key'])) { $key = null; @@ -429,6 +445,10 @@ public function compile($expression, CompilationContext $compilationContext) } } + if ($oldSymbolVariable->getName() != $symbolVariable->getName()) { + $codePrinter->output('ZVAL_COPY_VALUE('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); + $symbolVariable = $oldSymbolVariable; + } return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); } } From d08bb6f1e7100a90bd253da2deb448f31a86718a Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Tue, 26 Feb 2019 11:31:25 +0800 Subject: [PATCH 3/7] Add method Zephir\Backends\ZendEngine3\Backend::assignArrayProperty --- Library/Backends/ZendEngine2/Backend.php | 10 +++++++--- Library/Backends/ZendEngine3/Backend.php | 14 ++++++++++++++ Library/Expression/NativeArray.php | 5 +++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Library/Backends/ZendEngine2/Backend.php b/Library/Backends/ZendEngine2/Backend.php index 890d653d3f..44b81e7068 100644 --- a/Library/Backends/ZendEngine2/Backend.php +++ b/Library/Backends/ZendEngine2/Backend.php @@ -1107,11 +1107,15 @@ public function updateStaticProperty($classEntry, $property, $value, Compilation public function assignArrayProperty(Variable $variable, $property, $key, $value, CompilationContext $context) { - $value = $this->resolveValue($value, $context); + $resolveValue = $this->resolveValue($value, $context); if (isset($key)) { - $context->codePrinter->output('zephir_update_property_array('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$this->getVariableCode($key).', '.$value.' TSRMLS_CC);'); + $context->codePrinter->output('zephir_update_property_array('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$this->getVariableCode($key).', '.$resolveValue.' TSRMLS_CC);'); } else { - $context->codePrinter->output('zephir_update_property_array_append('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$value.' TSRMLS_CC);'); + $context->codePrinter->output('zephir_update_property_array_append('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$resolveValue.' TSRMLS_CC);'); + } + if (\is_object($value) && $value instanceof Variable && $value->isTemporal()) { + $context->codePrinter->output('zval_ptr_dtor('.$resolveValue.');'); + $context->codePrinter->output('ZVAL_UNDEF('.$resolveValue.');'); } } diff --git a/Library/Backends/ZendEngine3/Backend.php b/Library/Backends/ZendEngine3/Backend.php index 3100ef4463..d08e3c2fb5 100644 --- a/Library/Backends/ZendEngine3/Backend.php +++ b/Library/Backends/ZendEngine3/Backend.php @@ -683,6 +683,20 @@ public function updateStaticProperty($classEntry, $property, $value, Compilation $context->codePrinter->output('zend_update_static_property('.$classEntry.', ZEND_STRL("'.$property.'"), '.$value.');'); } + public function assignArrayProperty(Variable $variable, $property, $key, $value, CompilationContext $context) + { + $resolveValue = $this->resolveValue($value, $context); + if (isset($key)) { + $context->codePrinter->output('zephir_update_property_array('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$this->getVariableCode($key).', '.$resolveValue.');'); + } else { + $context->codePrinter->output('zephir_update_property_array_append('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$resolveValue.');'); + } + if (\is_object($value) && $value instanceof Variable && $value->isTemporal()) { + $context->codePrinter->output('zval_ptr_dtor('.$resolveValue.');'); + $context->codePrinter->output('ZVAL_UNDEF('.$resolveValue.');'); + } + } + public function callMethod($symbolVariable, Variable $variable, $methodName, $cachePointer, $params, CompilationContext $context) { $paramStr = null != $params ? ', '.implode(', ', $params) : ''; diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index 21a9f41685..133e8696c1 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -214,7 +214,7 @@ public function compile($expression, CompilationContext $compilationContext) $arrayLength = gmp_strval(gmp_nextprime($arrayLength - 1)); } $oldSymbolVariable = $symbolVariable; - if ($symbolVariable->geVariantInits() >= 1) { + if ($this->expectingVariable && $symbolVariable->geVariantInits() >= 1) { $symbolVariable = $compilationContext->symbolTable->addTemp('variable', $compilationContext); $symbolVariable->initVariant($compilationContext); $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null); @@ -446,7 +446,8 @@ public function compile($expression, CompilationContext $compilationContext) } if ($oldSymbolVariable->getName() != $symbolVariable->getName()) { - $codePrinter->output('ZVAL_COPY_VALUE('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); + $oldSymbolVariable->initVariant($compilationContext); + $codePrinter->output('ZVAL_COPY('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); $symbolVariable = $oldSymbolVariable; } return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); From 3908b9e6a94b4e23c2e991ea5ef76c73f9038b80 Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Tue, 26 Feb 2019 12:00:29 +0800 Subject: [PATCH 4/7] Added test for #1140 and #1159 --- Library/Expression/NativeArray.php | 2 +- test/nativearray.zep | 20 ++++++++++++++++++++ unit-tests/Extension/NativeArrayTest.php | 12 ++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index 133e8696c1..81a24c8049 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -447,7 +447,7 @@ public function compile($expression, CompilationContext $compilationContext) if ($oldSymbolVariable->getName() != $symbolVariable->getName()) { $oldSymbolVariable->initVariant($compilationContext); - $codePrinter->output('ZVAL_COPY('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); + $codePrinter->output('ZEPHIR_CPY_WRT('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); $symbolVariable = $oldSymbolVariable; } return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); diff --git a/test/nativearray.zep b/test/nativearray.zep index c60e49c87d..136a3e902b 100644 --- a/test/nativearray.zep +++ b/test/nativearray.zep @@ -2,6 +2,8 @@ namespace Test; class NativeArray { + protected prefixes = []; + public function testArray1() -> array { var a; @@ -628,4 +630,22 @@ class NativeArray } return works; } + + public function Issue1140(string prefix, string baseDir) + { + if !isset this->prefixes[prefix] { + let this->prefixes[prefix] = []; + } + array_push(this->prefixes[prefix], baseDir); + return this->prefixes; + } + + public function Issue1159() + { + var myvar; + let myvar = 1; + + let myvar = [myvar]; + return myvar; + } } diff --git a/unit-tests/Extension/NativeArrayTest.php b/unit-tests/Extension/NativeArrayTest.php index b831978ca9..1e0446e7af 100644 --- a/unit-tests/Extension/NativeArrayTest.php +++ b/unit-tests/Extension/NativeArrayTest.php @@ -160,4 +160,16 @@ public function testIssue709() $t = new NativeArray(); $this->assertTrue($t->Issue709()); } + + public function testIssue1140() + { + $t = new NativeArray(); + $this->assertSame(['phalcon' => '/var/www/html/phalcon'], $t->Issue1140('phalcon', '/var/www/html/phalcon')); + } + + public function testIssue1159() + { + $t = new NativeArray(); + $this->assertSame([1], $t->Issue1159()); + } } From dd4fafba98e661d0c71799672174258590482c16 Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Tue, 26 Feb 2019 13:08:23 +0800 Subject: [PATCH 5/7] Updated Zephir\Backends\ZendEngine2\Backend::assignArrayProperty --- Library/Backends/ZendEngine2/Backend.php | 3 +-- Library/Expression/NativeArray.php | 5 ----- unit-tests/Extension/NativeArrayTest.php | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/Library/Backends/ZendEngine2/Backend.php b/Library/Backends/ZendEngine2/Backend.php index 44b81e7068..230bae3173 100644 --- a/Library/Backends/ZendEngine2/Backend.php +++ b/Library/Backends/ZendEngine2/Backend.php @@ -1114,8 +1114,7 @@ public function assignArrayProperty(Variable $variable, $property, $key, $value, $context->codePrinter->output('zephir_update_property_array_append('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$resolveValue.' TSRMLS_CC);'); } if (\is_object($value) && $value instanceof Variable && $value->isTemporal()) { - $context->codePrinter->output('zval_ptr_dtor('.$resolveValue.');'); - $context->codePrinter->output('ZVAL_UNDEF('.$resolveValue.');'); + $value->initVariant($context); } } diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index 81a24c8049..c0beaec225 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -445,11 +445,6 @@ public function compile($expression, CompilationContext $compilationContext) } } - if ($oldSymbolVariable->getName() != $symbolVariable->getName()) { - $oldSymbolVariable->initVariant($compilationContext); - $codePrinter->output('ZEPHIR_CPY_WRT('.$compilationContext->backend->getVariableCode($oldSymbolVariable).', '.$compilationContext->backend->getVariableCode($symbolVariable).');'); - $symbolVariable = $oldSymbolVariable; - } return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); } } diff --git a/unit-tests/Extension/NativeArrayTest.php b/unit-tests/Extension/NativeArrayTest.php index 1e0446e7af..c853a55fb1 100644 --- a/unit-tests/Extension/NativeArrayTest.php +++ b/unit-tests/Extension/NativeArrayTest.php @@ -164,7 +164,7 @@ public function testIssue709() public function testIssue1140() { $t = new NativeArray(); - $this->assertSame(['phalcon' => '/var/www/html/phalcon'], $t->Issue1140('phalcon', '/var/www/html/phalcon')); + $this->assertSame(['phalcon' => ['/var/www/html/phalcon']], $t->Issue1140('phalcon', '/var/www/html/phalcon')); } public function testIssue1159() From b4873c702791aa75a3876988a592c6fc40707154 Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Tue, 26 Feb 2019 13:14:53 +0800 Subject: [PATCH 6/7] Updated Zephir\Backends\ZendEngine3\Backend::assignArrayProperty --- Library/Backends/ZendEngine3/Backend.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Library/Backends/ZendEngine3/Backend.php b/Library/Backends/ZendEngine3/Backend.php index d08e3c2fb5..5690426708 100644 --- a/Library/Backends/ZendEngine3/Backend.php +++ b/Library/Backends/ZendEngine3/Backend.php @@ -692,8 +692,7 @@ public function assignArrayProperty(Variable $variable, $property, $key, $value, $context->codePrinter->output('zephir_update_property_array_append('.$this->getVariableCode($variable).', SL("'.$property.'"), '.$resolveValue.');'); } if (\is_object($value) && $value instanceof Variable && $value->isTemporal()) { - $context->codePrinter->output('zval_ptr_dtor('.$resolveValue.');'); - $context->codePrinter->output('ZVAL_UNDEF('.$resolveValue.');'); + $value->initVariant($context); } } From 31da3515ff4700bbba380b752308157dec375f2d Mon Sep 17 00:00:00 2001 From: Dreamszhu Date: Tue, 26 Feb 2019 13:50:30 +0800 Subject: [PATCH 7/7] Fix code style --- Library/Expression/NativeArray.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/Expression/NativeArray.php b/Library/Expression/NativeArray.php index c0beaec225..902fa73c30 100644 --- a/Library/Expression/NativeArray.php +++ b/Library/Expression/NativeArray.php @@ -198,6 +198,7 @@ public function compile($expression, CompilationContext $compilationContext) * Mark the variable as an array */ $symbolVariable->setDynamicTypes('array'); + return new CompiledExpression('array', $symbolVariable->getRealName(), $expression); } @@ -216,9 +217,8 @@ public function compile($expression, CompilationContext $compilationContext) $oldSymbolVariable = $symbolVariable; if ($this->expectingVariable && $symbolVariable->geVariantInits() >= 1) { $symbolVariable = $compilationContext->symbolTable->addTemp('variable', $compilationContext); - $symbolVariable->initVariant($compilationContext); + $symbolVariable->initVariant($compilationContext); $compilationContext->backend->initArray($symbolVariable, $compilationContext, $arrayLength > 0 ? $arrayLength : null); - $symbolVariable->setDynamicTypes('array'); } else { if ($this->expectingVariable) {