diff --git a/Library/Backends/ZendEngine2/Backend.php b/Library/Backends/ZendEngine2/Backend.php index 890d653d3f..230bae3173 100644 --- a/Library/Backends/ZendEngine2/Backend.php +++ b/Library/Backends/ZendEngine2/Backend.php @@ -1107,11 +1107,14 @@ 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()) { + $value->initVariant($context); } } diff --git a/Library/Backends/ZendEngine3/Backend.php b/Library/Backends/ZendEngine3/Backend.php index 3100ef4463..5690426708 100644 --- a/Library/Backends/ZendEngine3/Backend.php +++ b/Library/Backends/ZendEngine3/Backend.php @@ -683,6 +683,19 @@ 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()) { + $value->initVariant($context); + } + } + 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 788b259261..902fa73c30 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,20 @@ 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 +214,22 @@ 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 ($this->expectingVariable && $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; 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. */ 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..c853a55fb1 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()); + } }