Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
dreamsxin committed Apr 25, 2019
1 parent 942c616 commit 404130d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 4 deletions.
33 changes: 31 additions & 2 deletions Library/ClassMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,11 @@ class ClassMethod
*/
protected $expression;

/**
* @var array|null
*/
protected $staticVariables;

/**
* LocalContextPass.
*
Expand Down Expand Up @@ -184,7 +189,8 @@ public function __construct(
StatementsBlock $statements = null,
$docblock = null,
array $returnType = null,
array $expression = null
array $expression = null,
array $staticVariables = null
) {
$this->checkVisibility($visibility, $name, $expression);

Expand All @@ -195,6 +201,7 @@ public function __construct(
$this->statements = $statements;
$this->docblock = $docblock;
$this->expression = $expression;
$this->staticVariables = $staticVariables;

$this->setReturnTypes($returnType);
}
Expand Down Expand Up @@ -1600,7 +1607,6 @@ public function compile(CompilationContext $compilationContext)
*/
$branch = new Branch();
$branch->setType(Branch::TYPE_EXTERNAL);

/**
* BranchManager helps to create graphs of conditional/loop/root/jump branches.
*/
Expand All @@ -1617,6 +1623,16 @@ public function compile(CompilationContext $compilationContext)
$symbolTable->setLocalContext($localContext);
}

if ($this->staticVariables) {
foreach ($this->staticVariables as $var) {
$localVar = clone $var;
$localVar->setIsExternal(true);
$localVar->setLocalOnly(true);
$localVar->setType('variable');
$symbolTable->addRawVariable($localVar);
}
}

/**
* Parameters has an additional extra mutation.
*/
Expand Down Expand Up @@ -2044,6 +2060,7 @@ public function compile(CompilationContext $compilationContext)
$code .= $initCode.$initVarCode;
$codePrinter->preOutput($code);

$compilationContext->headersManager->add('kernel/object');
/*
* Fetch used superglobals
*/
Expand All @@ -2052,6 +2069,18 @@ public function compile(CompilationContext $compilationContext)
$globalVar = $symbolTable->getVariable($name);
$codePrinter->preOutput("\t".$compilationContext->backend->fetchGlobal($globalVar, $compilationContext, false));
}
if ($variable->isLocalSatic()) {
$staticVar = $symbolTable->getVariable($name);

$codePrinter->preOutput(sprintf(
"\t".'zephir_read_static_property_ce(%s%s, %s, SL("%s"), PH_NOISY_CC%s);',
$staticVar->isDoublePointer() ? '' : '&',
$staticVar->getName(),
$this->classDefinition->getClassEntry(),
$staticVar->getName(),
''
));
}
}

/*
Expand Down
55 changes: 53 additions & 2 deletions Library/Expression/Closure.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,24 @@ public function compile(array $expression, CompilationContext $compilationContex
$block = [];
}

$staticVariables = [];
if (isset($expression['use']) && is_array($expression['use'])) {
foreach ($expression['use'] as $parameter) {
$staticVariables[$parameter['name']] = $compilationContext->symbolTable->getVariable($parameter['name']);
}
}

foreach ($staticVariables as $var) {
$classDefinition->addProperty(new \Zephir\ClassProperty(
$classDefinition,
['public', 'static'],
$var->getName(),
null,
null,
null
));
}

$classMethod = new ClassMethod(
$classDefinition,
['public', 'final'],
Expand All @@ -115,7 +133,8 @@ public function compile(array $expression, CompilationContext $compilationContex
new StatementsBlock($block),
null,
null,
$expression
$expression,
$staticVariables
);
$classDefinition->addMethod($classMethod, $block);

Expand All @@ -133,7 +152,39 @@ public function compile(array $expression, CompilationContext $compilationContex

$symbolVariable->initVariant($compilationContext);
$compilationContext->backend->createClosure($symbolVariable, $classDefinition, $compilationContext);

$compilationContext->headersManager->add('kernel/object');
foreach ($staticVariables as $var) {
if ($var->getType() == 'variable' || $var->getType() == 'array') {
$compilationContext->backend->updateStaticProperty($classDefinition->getClassEntry(), $var->getName(), $var, $compilationContext);
} else {
$tempVariable = $compilationContext->symbolTable->getTempNonTrackedVariable('variable', $compilationContext, true);
switch ($var->getType()) {
case 'int':
case 'uint':
case 'long':
case 'ulong':
case 'char':
case 'uchar':
$compilationContext->backend->assignLong($tempVariable, $var, $compilationContext);
break;
case 'double':
$compilationContext->backend->assignDouble($tempVariable, $var, $compilationContext);
break;
case 'bool':
$compilationContext->backend->assignBool($tempVariable, $var, $compilationContext);
break;
case 'string':
$compilationContext->backend->assignString($tempVariable, $var, $compilationContext);
break;
case 'string':
$compilationContext->backend->assignString($tempVariable, $var, $compilationContext);
break;
default:
break;
}
$compilationContext->backend->updateStaticProperty($classDefinition->getClassEntry(), $var->getName(), $tempVariable, $compilationContext);
}
}
++self::$id;

return new CompiledExpression('variable', $symbolVariable->getRealName(), $expression);
Expand Down
20 changes: 20 additions & 0 deletions Library/Variable.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,16 @@ public function getInitBranches()
return $this->initBranches;
}

/**
* Sets the type of variable.
*
* @param string $type
*/
public function setType($type)
{
$this->type = $type;
}

/**
* Returns the type of variable.
*
Expand Down Expand Up @@ -1041,6 +1051,16 @@ public function isSuperGlobal()
return $this->isExternal && $this->globalsManager->isSuperGlobal($this->name);
}

/**
* Checks if a variable is a local static.
*
* @return bool
*/
public function isLocalSatic()
{
return $this->isExternal && $this->localOnly;
}

/**
* Shortcut is type variable?
*
Expand Down
8 changes: 8 additions & 0 deletions test/closures.zep
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,12 @@ class Closures
{
return x => (x + 100) + (x * 150);
}

public function testUseCommand()
{
var abc = 1;
return function() use (abc) {
return abc + 1;
};
}
}

0 comments on commit 404130d

Please sign in to comment.