Skip to content

Commit

Permalink
Merge pull request #1919 from phalcon/development
Browse files Browse the repository at this point in the history
0.12.3
  • Loading branch information
sergeyklay authored Sep 22, 2019
2 parents 4ab69bd + c5226ea commit bedd68b
Show file tree
Hide file tree
Showing 29 changed files with 628 additions and 84 deletions.
2 changes: 1 addition & 1 deletion .ci/build-phar.sh
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ if [ ! -f "./zephir.phar" ] || [ ! -x "./zephir.phar" ]; then
fi

mkdir -p "$HOME/bin"
mv "./zephir.phar" "$HOME/bin/zephir"
cp "./zephir.phar" "$HOME/bin/zephir"
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ matrix:
- php: '7.4snapshot'

cache:
apt: true
timeout: 604800
directories:
- $HOME/.composer/cache
Expand Down
11 changes: 10 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
## [0.12.3] - 2019-09-22
### Fixed
- Fixed concatenation support of strings with double numbers
[#1893](https://github.com/phalcon/zephir/issues/1893)
- Fixed 'void' return type hint being ignored
[#1908](https://github.com/phalcon/zephir/issues/1908)
- Fixed updating array properties
[#1915](https://github.com/phalcon/zephir/issues/1915)

## [0.12.2] - 2019-08-05
### Added
Expand Down Expand Up @@ -210,7 +218,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Fixed casting resource to int (only ZendEngine 3)
[#1524](https://github.com/phalcon/zephir/issues/1524)

[Unreleased]: https://github.com/phalcon/zephir/compare/0.12.2...HEAD
[Unreleased]: https://github.com/phalcon/zephir/compare/0.12.3...HEAD
[0.12.3]: https://github.com/phalcon/zephir/compare/0.12.2...0.12.3
[0.12.2]: https://github.com/phalcon/zephir/compare/0.12.1...0.12.2
[0.12.1]: https://github.com/phalcon/zephir/compare/0.12.0...0.12.1
[0.12.0]: https://github.com/phalcon/zephir/compare/0.11.12...0.12.0
Expand Down
65 changes: 64 additions & 1 deletion Library/ArgInfoDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ public function render()
) {
$this->richRenderStart();

if (false == $this->hasParameters()) {
if (false == $this->hasParameters() && false == $this->functionLike->isVoid()) {
$this->codePrinter->output('ZEND_END_ARG_INFO()');
$this->codePrinter->outputBlankLine();
}
Expand Down Expand Up @@ -156,6 +156,65 @@ private function richRenderStart()
return;
}

if ($this->functionLike->isVoid()) {
$this->codePrinter->output('#if PHP_VERSION_ID >= 70100');
$this->codePrinter->output('#if PHP_VERSION_ID >= 70200');
$this->codePrinter->output(
sprintf(
'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, %d)',
$this->name,
(int) $this->returnByRef,
$this->functionLike->getNumberOfRequiredParameters(),
$this->getReturnType(),
(int) $this->functionLike->areReturnTypesNullCompatible()
)
);

$this->codePrinter->output('#else');

$this->codePrinter->output(
sprintf(
'ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(%s, %d, %d, %s, NULL, %d)',
$this->name,
(int) $this->returnByRef,
$this->functionLike->getNumberOfRequiredParameters(),
$this->getReturnType(),
(int) $this->functionLike->areReturnTypesNullCompatible()
)
);

$this->codePrinter->output('#endif');

if (false == $this->hasParameters()) {
$this->codePrinter->output('ZEND_END_ARG_INFO()');
}

$this->codePrinter->output('#else');

if (true == $this->hasParameters()) {
$this->codePrinter->output(
sprintf(
'ZEND_BEGIN_ARG_INFO_EX(%s, 0, %d, %d)',
$this->name,
(int) $this->returnByRef,
$this->functionLike->getNumberOfRequiredParameters()
)
);
}

$this->codePrinter->output(
sprintf(
'#define %s NULL',
$this->name
)
);

$this->codePrinter->output('#endif');
$this->codePrinter->outputBlankLine();

return;
}

$this->codePrinter->output('#if PHP_VERSION_ID >= 70200');
$this->codePrinter->output(
sprintf(
Expand Down Expand Up @@ -357,6 +416,10 @@ private function getReturnType()
return 'IS_STRING';
}

if ($this->functionLike->isVoid()) {
return 'IS_VOID';
}

if (\array_key_exists('array', $this->functionLike->getReturnTypes())) {
return 'IS_ARRAY';
}
Expand Down
12 changes: 10 additions & 2 deletions Library/ClassMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -2322,7 +2322,7 @@ public function getArgInfoName(ClassDefinition $classDefinition = null)
*
* Examples:
*
* - FALSE: function foo() -> void;
* - TRUE: function foo() -> void;
* - TRUE: function foo() -> null;
* - TRUE: function foo() -> bool|string|..;
* - TRUE: function foo() -> <\stdClass>;
Expand All @@ -2334,7 +2334,10 @@ public function getArgInfoName(ClassDefinition $classDefinition = null)
*/
public function isReturnTypesHintDetermined()
{
if (0 == \count($this->returnTypes) || $this->isVoid()) {
if ($this->isVoid()) {
return true;
}
if (0 == \count($this->returnTypes)) {
return false;
}

Expand Down Expand Up @@ -2376,6 +2379,11 @@ public function isReturnTypesHintDetermined()
*/
public function areReturnTypesCompatible()
{
// void
if ($this->isVoid()) {
return true;
}

// null | T1 | T2
if (\count($this->returnTypes) > 2) {
return false;
Expand Down
146 changes: 104 additions & 42 deletions Library/Operators/Other/ConcatOperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use function Zephir\add_slashes;
use Zephir\CompilationContext;
use Zephir\CompiledExpression;
use Zephir\Exception;
use Zephir\Exception\CompilerException;
use Zephir\Expression;
use Zephir\Operators\BaseOperator;
Expand All @@ -32,6 +33,8 @@ class ConcatOperator extends BaseOperator
* @param CompilationContext $compilationContext
*
* @return CompiledExpression
*
* @throws CompilerException
*/
public function compile($expression, CompilationContext $compilationContext)
{
Expand All @@ -58,7 +61,9 @@ public function compile($expression, CompilationContext $compilationContext)

$expected->setDynamicTypes('string');
$expectedCode = $compilationContext->backend->getVariableCode($expected);
$compilationContext->codePrinter->output('ZEPHIR_CONCAT_'.strtoupper($optimized[0]).'('.$expectedCode.', '.$optimized[1].');');
$compilationContext->codePrinter->output(
sprintf('ZEPHIR_CONCAT_%s(%s, %s);', strtoupper($optimized[0]), $expectedCode, $optimized[1])
);

return new CompiledExpression('variable', $expected->getName(), $expression);
}
Expand All @@ -67,35 +72,15 @@ public function compile($expression, CompilationContext $compilationContext)
* If the expression cannot be optimized, fall back to the standard compilation.
*/
$leftExpr = new Expression($expression['left']);
switch ($expression['left']['type']) {
case 'array-access':
case 'property-access':
$leftExpr->setReadOnly(true);
break;

default:
$leftExpr->setReadOnly($this->readOnly);
break;
}
$left = $leftExpr->compile($compilationContext);
$left = $this->compileExpression($leftExpr, $compilationContext, $expression['left']['type']);

if ('variable' == $left->getType()) {
$variableLeft = $compilationContext->symbolTable->getVariableForRead($left->getCode(), $compilationContext, $expression['right']);
$variableLeft = $compilationContext->backend->getVariableCode($variableLeft);
}

$rightExpr = new Expression($expression['right']);
switch ($expression['left']['type']) {
case 'array-access':
case 'property-access':
$rightExpr->setReadOnly(true);
break;

default:
$rightExpr->setReadOnly($this->readOnly);
break;
}
$right = $rightExpr->compile($compilationContext);
$right = $this->compileExpression($rightExpr, $compilationContext, $expression['left']['type']);

if ('variable' == $right->getType()) {
$variableRight = $compilationContext->symbolTable->getVariableForRead($right->getCode(), $compilationContext, $expression['right']);
Expand Down Expand Up @@ -128,11 +113,12 @@ public function compile($expression, CompilationContext $compilationContext)
* @param bool $isFullString
*
* @return array
*
* @throws CompilerException
*/
private function _getOptimizedConcat($expression, CompilationContext $compilationContext, &$isFullString)
{
$originalExpr = $expression;

$isFullString = true;

$parts = [];
Expand All @@ -156,21 +142,15 @@ private function _getOptimizedConcat($expression, CompilationContext $compilatio
foreach ($parts as $part) {
$expr = new Expression($part);
$expr->setStringOperation(true);
switch ($part['type']) {
case 'array-access':
case 'property-access':
$expr->setReadOnly(true);
break;
$compiledExpr = $this->compileExpression($expr, $compilationContext, $part['type']);

default:
$expr->setReadOnly($this->readOnly);
break;
}

$compiledExpr = $expr->compile($compilationContext);
switch ($compiledExpr->getType()) {
case 'variable':
$variable = $compilationContext->symbolTable->getVariableForRead($compiledExpr->getCode(), $compilationContext, $originalExpr);
$variable = $compilationContext->symbolTable->getVariableForRead(
$compiledExpr->getCode(),
$compilationContext,
$originalExpr
);
switch ($variable->getType()) {
case 'variable':
$key .= 'v';
Expand All @@ -184,15 +164,44 @@ private function _getOptimizedConcat($expression, CompilationContext $compilatio
break;

case 'int':
case 'uint':
case 'long':
case 'ulong':
$key .= 'v';
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite(
'variable',
$compilationContext
);
$compilationContext->backend->assignLong(
$tempVariable,
$compiledExpr->getCode(),
$compilationContext
);
$concatParts[] = $compilationContext->backend->getVariableCode($tempVariable);
break;

case 'double':
$key .= 'v';
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite('variable', $compilationContext, $originalExpr);
$compilationContext->backend->assignLong($tempVariable, $compiledExpr->getCode(), $compilationContext);
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite(
'variable',
$compilationContext
);
$compilationContext->backend->assignDouble(
$tempVariable,
$compiledExpr->getCode(),
$compilationContext
);
$concatParts[] = $compilationContext->backend->getVariableCode($tempVariable);
break;

default:
throw new CompilerException('Variable type: '.$variable->getType().' cannot be used in concat operation', $compiledExpr->getOriginal());
throw new CompilerException(
sprintf(
'Variable type: %s cannot be used in concat operation',
$variable->getType()
),
$compiledExpr->getOriginal()
);
}
break;

Expand All @@ -202,20 +211,73 @@ private function _getOptimizedConcat($expression, CompilationContext $compilatio
break;

case 'int':
case 'uint':
case 'long':
case 'ulong':
$key .= 'v';
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite('variable', $compilationContext, $originalExpr);
$compilationContext->codePrinter->output('ZVAL_LONG(&'.$tempVariable->getName().', '.$compiledExpr->getCode().');');
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite(
'variable',
$compilationContext
);
$compilationContext->codePrinter->output(
sprintf(
'ZVAL_LONG(&%s, %s);',
$tempVariable->getName(),
$compiledExpr->getCode()
)
);
$concatParts[] = '&'.$tempVariable->getName();
break;

case 'double':
$key .= 'v';
$tempVariable = $compilationContext->symbolTable->getTempLocalVariableForWrite(
'variable',
$compilationContext
);
$compilationContext->codePrinter->output(
sprintf(
'ZVAL_DOUBLE(&%s, %s);',
$tempVariable->getName(),
$compiledExpr->getCode()
)
);
$concatParts[] = '&'.$tempVariable->getName();
break;

default:
throw new CompilerException('Variable type: '.$compiledExpr->getType().' cannot be used in concat operation', $compiledExpr->getOriginal());
throw new CompilerException(
sprintf(
'Variable type: %s cannot be used in concat operation',
$compiledExpr->getType()
),
$compiledExpr->getOriginal()
);
}
}

$compilationContext->stringsManager->addConcatKey($key);

return [$key, implode(', ', $concatParts)];
}

private function compileExpression(Expression $expression, CompilationContext $context, $type)
{
try {
switch ($type) {
case 'array-access':
case 'property-access':
$expression->setReadOnly(true);
break;

default:
$expression->setReadOnly($this->readOnly);
break;
}

return $expression->compile($context);
} catch (Exception $e) {
throw new CompilerException($e->getMessage(), $expression->getExpression());
}
}
}
Loading

0 comments on commit bedd68b

Please sign in to comment.