/**
* Calls static methods on the 'self/static' context
*
* @param string $context SELF / STATIC
* @param string $methodName
* @param array $expression
* @param Variable $symbolVariable
* @param boolean $mustInit
* @param boolean $isExpecting
* @param ClassDefinition $classDefinition
* @param CompilationContext $compilationContext
* @param ClassMethod $method
*/
protected function call($context, $methodName, array $expression, $symbolVariable, $mustInit, $isExpecting, ClassDefinition $classDefinition, CompilationContext $compilationContext, ClassMethod $method)
{
if (!in_array($context, array('SELF', 'STATIC'))) {
$context = 'SELF';
}
$codePrinter = $compilationContext->codePrinter;
/**
* Call static methods must grown the stack
*/
$compilationContext->symbolTable->mustGrownStack(true);
if ($mustInit) {
$symbolVariable->setMustInitNull(true);
$symbolVariable->trackVariant($compilationContext);
}
/**
* Check if the method call can have an inline cache
*/
$methodCache = $compilationContext->cacheManager->getStaticMethodCache();
$cachePointer = $methodCache->get($compilationContext, isset($method) ? $method : null, false);
if (isset($expression['parameters']) && count($expression['parameters'])) {
$params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression);
} else {
$params = array();
}
$isInternal = false;
if (isset($method)) {
$isInternal = $method->isInternal();
}
if (!$isInternal) {
if (!count($params)) {
if ($isExpecting) {
if ($symbolVariable->getName() == 'return_value') {
$codePrinter->output('ZEPHIR_RETURN_CALL_' . $context . '("' . $methodName . '", ' . $cachePointer . ');');
} else {
$codePrinter->output('ZEPHIR_CALL_' . $context . '(&' . $symbolVariable->getName() . ', "' . $methodName . '", ' . $cachePointer . ');');
}
} else {
$codePrinter->output('ZEPHIR_CALL_' . $context . '(NULL, "' . $methodName . '", ' . $cachePointer . ');');
}
} else {
if ($isExpecting) {
if ($symbolVariable->getName() == 'return_value') {
$codePrinter->output('ZEPHIR_RETURN_CALL_' . $context . '("' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
} else {
$codePrinter->output('ZEPHIR_CALL_' . $context . '(&' . $symbolVariable->getName() . ', "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
}
} else {
$codePrinter->output('ZEPHIR_CALL_' . $context . '(NULL, "' . $methodName . '", ' . $cachePointer . ', ' . join(', ', $params) . ');');
}
}
} else {
if (!count($params)) {
if ($isExpecting) {
if ($symbolVariable->getName() == 'return_value') {
$codePrinter->output('ZEPHIR_RETURN_CALL_INTERNAL_METHOD_P0(EG(This), ' . $method->getInternalName() . ');');
} else {
$codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_P0(&' . $symbolVariable->getName() . ', EG(This), ' . $method->getInternalName() . ');');
}
} else {
$codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_NORETURN_P0(EG(This), ' . $method->getInternalName() . ');');
}
} else {
if ($isExpecting) {
if ($symbolVariable->getName() == 'return_value') {
$codePrinter->output('ZEPHIR_RETURN_CALL_INTERNAL_METHOD_P' . count($params) . '(EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');');
} else {
$codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_P' . count($params) . '(&' . $symbolVariable->getName() . ', EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');');
}
} else {
$codePrinter->output('ZEPHIR_CALL_INTERNAL_METHOD_NORETURN_P' . count($params) . '(EG(This), ' . $method->getInternalName() . ', ' . join(', ', $params) . ');');
}
}
}
/**
* Temporary variables must be copied if they have more than one reference
*/
foreach ($this->getMustCheckForCopyVariables() as $checkVariable) {
$codePrinter->output('zephir_check_temp_parameter(' . $checkVariable . ');');
}
$this->addCallStatusOrJump($compilationContext);
}