Tells the compiler a generated code will track the variable
public trackVariant ( zephir\CompilationContext $compilationContext ) | ||
$compilationContext | zephir\CompilationContext |
/** * Calls static methods on using a dynamic variable as class and a dynamic method * * @param array $expression * @param Variable $symbolVariable * @param boolean $mustInit * @param boolean $isExpecting * @param CompilationContext $compilationContext */ protected function callFromDynamicClassDynamicMethod(array $expression, $symbolVariable, $mustInit, $isExpecting, CompilationContext $compilationContext) { $codePrinter = $compilationContext->codePrinter; /** * Call static methods must grown the stack */ $compilationContext->symbolTable->mustGrownStack(true); if ($mustInit) { $symbolVariable->setMustInitNull(true); $symbolVariable->trackVariant($compilationContext); } $cachePointer = 'NULL'; if (isset($expression['parameters']) && count($expression['parameters'])) { $params = $this->getResolvedParams($expression['parameters'], $compilationContext, $expression); } else { $params = array(); } /** * Obtain the class entry from the variable */ $classNameVariable = $compilationContext->symbolTable->getVariableForRead($expression['class'], $compilationContext, $expression); if ($classNameVariable->isNotVariableAndString()) { throw new CompilerException("Only dynamic/string variables can be used in dynamic classes", $expression); } /** * @todo Validate if the variable is really a string! */ $classEntryVariable = $compilationContext->symbolTable->addTemp('zend_class_entry', $compilationContext); $codePrinter->output($classEntryVariable->getName() . ' = zend_fetch_class(Z_STRVAL_P(' . $classNameVariable->getName() . '), Z_STRLEN_P(' . $classNameVariable->getName() . '), ZEND_FETCH_CLASS_AUTO TSRMLS_CC);'); $classEntry = $classEntryVariable->getName(); /** * Obtain the method name from the variable */ $methodNameVariable = $compilationContext->symbolTable->getVariableForRead($expression['name'], $compilationContext, $expression); if ($methodNameVariable->isNotVariableAndString()) { throw new CompilerException("Only dynamic/string variables can be used in dynamic methods", $expression); } /** * @todo Validate if the variable is really a string! */ $methodName = 'Z_STRVAL_P(' . $methodNameVariable->getName() . ')'; if (!count($params)) { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC(' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ');'); } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC(&' . $symbolVariable->getName() . ', ' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC(NULL, ' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ');'); } } else { if ($isExpecting) { if ($symbolVariable->getName() == 'return_value') { $codePrinter->output('ZEPHIR_RETURN_CALL_CE_STATIC(' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ', ' . join(', ', $params) . ');'); } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC(&' . $symbolVariable->getName() . ', ' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ', ' . join(', ', $params) . ');'); } } else { $codePrinter->output('ZEPHIR_CALL_CE_STATIC(NULL, ' . $classEntry . ', ' . $methodName . ', ' . $cachePointer . ', ' . 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); }