Skip to content

Commit

Permalink
Merge branch 'development' into #2255-php8.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeckerson committed Sep 11, 2021
2 parents 417c147 + 43f3012 commit 465d4eb
Show file tree
Hide file tree
Showing 23 changed files with 333 additions and 22 deletions.
1 change: 0 additions & 1 deletion .ci/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ set -eu
php \
-d extension=ext/modules/stub.so \
vendor/bin/phpunit \
--colors=always \
--bootstrap tests/ext-bootstrap.php \
--testsuite Extension

Expand Down
10 changes: 4 additions & 6 deletions .ci/win-ci-tools.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,11 @@ function InstallZephirParser {
Download and install Zephir parser PHP extension
#>

$BaseUri = "https://github.com/phalcon/php-zephir-parser/releases/download"
$LocalPart = "zephir_parser_${env:PHP_ARCH}_vc${env:VC_VERSION}_php${env:PHP_MINOR}"
$BaseUri = "https://github.com/zephir-lang/php-zephir-parser/releases/download"
$LocalPart = "zephir-parser-php-${env:PHP_MINOR}-${env:BUILD_TYPE}-win32-vc${env:VC_VERSION}-${env:PHP_ARCH}.zip"

$TS = Get-ThreadSafety

$RemoteUrl = "${BaseUri}/v${env:PARSER_VERSION}/${LocalPart}${TS}_${env:PARSER_VERSION}-${env:PARSER_RELEASE}.zip"
$DestinationPath = "C:\Downloads\${LocalPart}${TS}_${env:PARSER_VERSION}-${env:PARSER_RELEASE}.zip"
$RemoteUrl = "${BaseUri}/v${env:PARSER_VERSION}/${LocalPart}"
$DestinationPath = "C:\Downloads\${LocalPart}"

if (-not (Test-Path "${env:PHPROOT}\ext\php_zephir_parser.dll")) {
if (-not [System.IO.File]::Exists($DestinationPath)) {
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-unix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
- development

env:
ZEPHIR_PARSER_VERSION: v1.3.6
ZEPHIR_PARSER_VERSION: v1.3.8

jobs:
linux:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:
- development

env:
PARSER_VERSION: 1.3.6
PARSER_VERSION: 1.3.8
PARSER_RELEASE: 559
PHP_SDK_VERSION: 2.2.0
PHP_DEVPACK: C:\tools\php-devpack
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ The format based on [Keep a Changelog](http://keepachangelog.com)
and this project adheres to [Semantic Versioning](http://semver.org).

## [Unreleased]
### Added
- Added support for `require_once` [#2253](https://github.com/zephir-lang/zephir/issues/2253)

## [0.14.0-beta.3] - 2021-08-06
### Fixed
Expand Down
2 changes: 2 additions & 0 deletions Library/Detectors/WriteDetector.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ public function passExpression(array $expression)
case 'empty':
case 'instanceof':
case 'require':
case 'require_once':
case 'clone':
case 'likely':
case 'unlikely':
Expand Down Expand Up @@ -432,6 +433,7 @@ public function passStatementBlock(array $statements)
case 'scall':
case 'fcall':
case 'require':
case 'require_once':
$this->passCall($statement['expr']);
break;

Expand Down
8 changes: 5 additions & 3 deletions Library/Expression.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
use Zephir\Operators\Other\NewInstanceTypeOperator;
use Zephir\Operators\Other\RangeExclusiveOperator;
use Zephir\Operators\Other\RangeInclusiveOperator;
use Zephir\Operators\Other\RequireOnceOperator;
use Zephir\Operators\Other\RequireOperator;
use Zephir\Operators\Other\ShortTernaryOperator;
use Zephir\Operators\Other\TernaryOperator;
Expand Down Expand Up @@ -575,6 +576,10 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
$compilableExpression = new RequireOperator();
break;

case 'require_once':
$compilableExpression = new RequireOnceOperator();
break;

case 'closure':
$compilableExpression = new Closure();
break;
Expand All @@ -591,9 +596,6 @@ public function compile(CompilationContext $compilationContext): CompiledExpress
throw new CompilerException('Unknown expression: '.$type, $expression);
}

if (!$compilableExpression) {
throw new CompilerException('Unknown expression passed as compilableExpression', $expression);
}
$compilableExpression->setReadOnly($this->isReadOnly());
$compilableExpression->setExpectReturn($this->expecting, $this->expectingVariable);

Expand Down
3 changes: 3 additions & 0 deletions Library/Expression/Builder/Operators/UnaryOperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class UnaryOperator extends AbstractOperator
// y = require a
const OPERATOR_REQUIRE = 'require';

// y = require_once a
const OPERATOR_REQUIRE_ONCE = 'require_once';

// y = clone a
const OPERATOR_CLONE = 'clone';

Expand Down
86 changes: 86 additions & 0 deletions Library/Operators/Other/RequireOnceOperator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

/**
* This file is part of the Zephir.
*
* (c) Phalcon Team <team@zephir-lang.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Operators\Other;

use Zephir\CompilationContext;
use Zephir\CompiledExpression;
use Zephir\Exception;
use Zephir\Expression;
use Zephir\Operators\BaseOperator;

/**
* Require once.
*
* Includes once a plain PHP file
*/
class RequireOnceOperator extends BaseOperator
{
/**
* @param array $expression
* @param CompilationContext $compilationContext
*
* @return CompiledExpression
* @throws Exception
*/
public function compile(array $expression, CompilationContext $compilationContext): CompiledExpression
{
$expr = new Expression($expression['left']);
$expr->setReadOnly(true);
$expr->setExpectReturn(true);

$exprPath = $expr->compile($compilationContext);
if ('variable' === $exprPath->getType()) {
$exprVariable = $compilationContext->symbolTable->getVariableForRead($exprPath->getCode(), $compilationContext, $expression);
$exprVar = $compilationContext->backend->getVariableCode($exprVariable);
if ('variable' === $exprVariable->getType()) {
if ($exprVariable->hasDifferentDynamicType(['undefined', 'string'])) {
$compilationContext->logger->warning(
'Possible attempt to use invalid type as path in "require_once" operator',
['non-valid-require-once', $expression]
);
}
}
} else {
$exprVar = $compilationContext->symbolTable->getTempVariableForWrite('variable', $compilationContext, $expression);
$compilationContext->backend->assignString($exprVar, $exprPath->getCode(), $compilationContext);
$exprVar = $compilationContext->backend->getVariableCode($exprVar);
}

$symbolVariable = false;
if ($this->isExpecting()) {
$symbolVariable = $compilationContext->symbolTable->getTempVariableForObserveOrNullify('variable', $compilationContext);
}

$compilationContext->headersManager->add('kernel/memory');
$compilationContext->headersManager->add('kernel/require');

$codePrinter = $compilationContext->codePrinter;

if ($symbolVariable) {
$codePrinter->output('ZEPHIR_OBSERVE_OR_NULLIFY_PPZV(&'.$symbolVariable->getName().');');
$symbol = $compilationContext->backend->getVariableCodePointer($symbolVariable);
$codePrinter->output('if (zephir_require_once_zval_ret('.$symbol.', '.$exprVar.') == FAILURE) {');
} else {
$codePrinter->output('if (zephir_require_once_zval('.$exprVar.') == FAILURE) {');
}
$codePrinter->output("\t".'RETURN_MM_NULL();');
$codePrinter->output('}');

if ($symbolVariable) {
return new CompiledExpression('variable', $symbolVariable->getName(), $expression);
}

return new CompiledExpression('null', null, $expression);
}
}
2 changes: 2 additions & 0 deletions Library/Passes/CallGathererPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ public function passExpression(array $expression)

case 'clone':
case 'require':
case 'require_once':
$this->passExpression($expression['left']);
break;

Expand Down Expand Up @@ -426,6 +427,7 @@ public function passStatementBlock(array $statements)
break;

case 'require':
case 'require_once':
if (isset($statement['expr'])) {
$this->passExpression($statement['expr']);
}
Expand Down
3 changes: 3 additions & 0 deletions Library/Passes/LocalContextPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ public function passLetStatement(array $statement)
case 'concat':
case 'clone':
case 'require':
case 'require_once':
case 'type-hint':
case 'minus':
case 'new':
Expand Down Expand Up @@ -415,6 +416,7 @@ public function passExpression(array $expression)
case 'empty':
case 'instanceof':
case 'require':
case 'require_once':
case 'clone':
case 'likely':
case 'unlikely'
Expand Down Expand Up @@ -570,6 +572,7 @@ public function passStatementBlock(array $statements)
case 'scall':
case 'fcall':
case 'require':
case 'require_once':
if ('mcall' == $statement['expr']['type']) {
if (isset($statement['expr']['variable'])) {
if ('variable' == $statement['expr']['variable']['type']) {
Expand Down
2 changes: 2 additions & 0 deletions Library/Passes/MutateGathererPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ public function passExpression(array $expression)
case 'empty':
case 'instanceof':
case 'require':
case 'require_once':
case 'clone':
case 'likely':
case 'unlikely':
Expand Down Expand Up @@ -382,6 +383,7 @@ public function passStatementBlock(array $statements)
case 'scall':
case 'fcall':
case 'require':
case 'require_once':
$this->passCall($statement['expr']);
break;

Expand Down
2 changes: 2 additions & 0 deletions Library/Passes/StaticTypeInference.php
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ public function passExpression(array $expression)

case 'clone':
case 'require':
case 'require_once':
return 'variable';

case 'ternary':
Expand Down Expand Up @@ -592,6 +593,7 @@ public function passStatementBlock(array $statements)
case 'scall':
case 'fcall':
case 'require':
case 'require_once':
$this->passCall($statement['expr']);
break;

Expand Down
46 changes: 46 additions & 0 deletions Library/Statements/RequireOnceStatement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

/**
* This file is part of the Zephir.
*
* (c) Phalcon Team <team@zephir-lang.com>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Zephir\Statements;

use Zephir\CompilationContext;
use Zephir\Exception;
use Zephir\Expression;

/**
* RequireOnceStatement.
*
* Require once statement is used to execute PHP scripts in a given path
*/
class RequireOnceStatement extends StatementAbstract
{
/**
* @param CompilationContext $compilationContext
*
* @throws Exception
*/
public function compile(CompilationContext $compilationContext)
{
$expression = [
'type' => 'require_once',
'left' => $this->statement['expr'],
'file' => $this->statement['file'],
'line' => $this->statement['line'],
'char' => $this->statement['char'],
];

$expr = new Expression($expression);
$expr->setExpectReturn(false, null);
$expr->compile($compilationContext);
}
}
7 changes: 7 additions & 0 deletions Library/StatementsBlock.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Zephir;

use Zephir\Operators\Other\RequireOnceOperator;
use Zephir\Passes\MutateGathererPass;
use Zephir\Statements\BreakStatement;
use Zephir\Statements\ContinueStatement;
Expand All @@ -21,6 +22,7 @@
use Zephir\Statements\IfStatement;
use Zephir\Statements\LetStatement;
use Zephir\Statements\LoopStatement;
use Zephir\Statements\RequireOnceStatement;
use Zephir\Statements\RequireStatement;
use Zephir\Statements\ReturnStatement;
use Zephir\Statements\SwitchStatement;
Expand Down Expand Up @@ -256,6 +258,11 @@ public function compile(CompilationContext $compilationContext, $unreachable = f
$requireStatement->compile($compilationContext);
break;

case 'require_once':
$requireOnceStatement = new RequireOnceStatement($statement);
$requireOnceStatement->compile($compilationContext);
break;

case 'loop':
$loopStatement = new LoopStatement($statement);
$loopStatement->compile($compilationContext);
Expand Down
Loading

0 comments on commit 465d4eb

Please sign in to comment.