Skip to content

Commit

Permalink
Merge pull request phalcon#23 from Cinderella-Man/fcall-ut
Browse files Browse the repository at this point in the history
Support for dynamic function names
  • Loading branch information
Phalcon committed Oct 28, 2013
2 parents 6fb62bf + 58e3b54 commit 69ed374
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 23 deletions.
10 changes: 10 additions & 0 deletions Library/ClassMethod.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,16 @@ public function __construct(ClassDefinition $classDefinition, $visibility, $name
}
}

/**
* Getter for statements block
*
* @return StatementsBlock $statements Statements block
*/
public function getStatementsBlock()
{
return $this->_statements;
}

/**
* Checks for visibility congruence
*
Expand Down
79 changes: 56 additions & 23 deletions Library/FunctionCall.php
Original file line number Diff line number Diff line change
Expand Up @@ -426,29 +426,62 @@ protected function _callDynamic($expression, $compilationContext)
*/
$compilationContext->symbolTable->mustGrownStack(true);

/*if (!isset($expression['parameters'])) {
if ($this->isExpectingReturn()) {
if ($this->mustInitSymbolVariable()) {
$symbolVariable->initVariant($compilationContext);
}
$codePrinter->output('zephir_call_func(' . $symbolVariable->getName() . ', "' . $funcName . '");');
} else {
$codePrinter->output('zephir_call_func_noret("' . $funcName . '");');
}
} else {
if (count($params)) {
if ($this->isExpectingReturn()) {
if ($this->mustInitSymbolVariable()) {
$symbolVariable->initVariant($compilationContext);
}
$codePrinter->output('zephir_call_func_p' . count($params) . '(' . $symbolVariable->getName() . ', "' . $funcName . '", ' . join(', ', $params) . ');');
} else {
$codePrinter->output('zephir_call_func_p' . count($params) . '_noret("' . $funcName . '", ' . join(', ', $params) . ');');
}
} else {
$codePrinter->output('zephir_call_func_noret("' . $funcName . '");');
}
}*/
/**
* Find last value of variable
*/
$methodStatements = $compilationContext->currentMethod->getStatementsBlock()->getStatements();
$varName = $expression['name'];
$lastValue = null;
foreach ($methodStatements as $statement) {

if (isset($statement['line'])
&& $statement['line'] <= $expression['line']
&& isset($statement['type'])
&& $statement['type'] === 'let'
&& isset($statement['assignments'])
&& is_array($statement['assignments'])
) {

foreach ($statement['assignments'] as $assignment) {

if (isset($assignment['variable'])
&& $assignment['variable'] === $varName
&& isset($assignment['expr']['value'])
) {
$lastValue = $assignment['expr']['value'];
}
}
}
}

if ($lastValue) {

$funcName = $lastValue;

if (!isset($expression['parameters'])) {
if ($this->isExpectingReturn()) {
if ($this->mustInitSymbolVariable()) {
$symbolVariable->initVariant($compilationContext);
}
$codePrinter->output('zephir_call_func(' . $symbolVariable->getName() . ', "' . $funcName . '");');
} else {
$codePrinter->output('zephir_call_func_noret("' . $funcName . '");');
}
} else {
if (count($params)) {
if ($this->isExpectingReturn()) {
if ($this->mustInitSymbolVariable()) {
$symbolVariable->initVariant($compilationContext);
}
$codePrinter->output('zephir_call_func_p' . count($params) . '(' . $symbolVariable->getName() . ', "' . $funcName . '", ' . join(', ', $params) . ');');
} else {
$codePrinter->output('zephir_call_func_p' . count($params) . '_noret("' . $funcName . '", ' . join(', ', $params) . ');');
}
} else {
$codePrinter->output('zephir_call_func_noret("' . $funcName . '");');
}
}
}

/**
* We can mark temporary variables generated as idle
Expand Down
7 changes: 7 additions & 0 deletions test/fcall.zep
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,11 @@ class Fcall
return strpos("hello", "h");
}

public function testCall1FromVar()
{
var funcName;
let funcName = "strpos";
return {funcName}("hello", "l");
}

}
6 changes: 6 additions & 0 deletions unit-tests/fcall.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?php

$t = new Test\Fcall();

assert($t->testCall1() === 0);
assert($t->testCall1FromVar() === 2);

0 comments on commit 69ed374

Please sign in to comment.