/** * Return a variable in the symbol table, it will be used for a mutating operation * This method implies mutation of one of the members of the variable but no the variables it self * * @param string $name * @param CompilationContext $compilationContext * @param array $statement * @return Variable */ public function getVariableForUpdate($name, CompilationContext $compilationContext, array $statement = null) { /** * Create superglobals just in time */ if ($this->isSuperGlobal($name)) { if (!$this->hasVariable($name)) { /** * @TODO, injecting globals, initialize to null and check first? */ $superVar = new Variable('variable', $name, $compilationContext->currentBranch); $superVar->setIsInitialized(true, $compilationContext, $statement); $superVar->setDynamicTypes('array'); $superVar->increaseMutates(); $superVar->increaseUses(); $superVar->setIsExternal(true); $superVar->setUsed(true, $statement); $this->variables[$name] = $superVar; return $superVar; } } if (!$this->hasVariable($name)) { throw new CompilerException("Cannot mutate variable '" . $name . "' because it wasn't defined", $statement); } $variable = $this->getVariable($name); $variable->increaseUses(); $variable->increaseMutates(); /** * Saves the last place where the variable was mutated * We discard mutations inside loops because iterations could use the value * and Zephir only provides top-down compilation */ $variable->setUsed(true, $statement); return $variable; }
/** * Add the last-call-status flag to the current symbol table * * @param CompilationContext $compilationContext */ public function addCallStatusFlag(CompilationContext $compilationContext) { if (!$compilationContext->symbolTable->hasVariable('ZEPHIR_LAST_CALL_STATUS')) { $callStatus = new Variable('int', 'ZEPHIR_LAST_CALL_STATUS', $compilationContext->currentBranch); $callStatus->setIsInitialized(true, $compilationContext, array()); $callStatus->increaseUses(); $callStatus->setReadOnly(true); $compilationContext->symbolTable->addRawVariable($callStatus); } }
/** * Return a variable in the symbol table, it will be used for a write operation * Some variables aren't writable themselves but their members do * * @param string $name * @param CompilationContext $compilationContext * @param array $statement * @return Variable */ public function getVariableForWrite($name, $compilationContext, $statement = null) { /** * Create superglobals just in time */ if ($this->isSuperGlobal($name)) { if (!$this->hasVariable($name)) { /** * @TODO, injecting globals, initialize to null and check first? */ $compilationContext->codePrinter->output('zephir_get_global(&' . $name . ', SS("' . $name . '") TSRMLS_CC);'); $superVar = new Variable('variable', $name, $compilationContext->currentBranch); $superVar->setIsInitialized(true, $compilationContext, $statement); $superVar->setDynamicTypes('array'); $superVar->increaseMutates(); $superVar->increaseUses(); $this->_variables[$name] = $superVar; return $superVar; } } if (!$this->hasVariable($name)) { throw new CompilerException("Cannot mutate variable '" . $name . "' because it wasn't defined", $statement); } $variable = $this->getVariable($name); $variable->increaseUses(); $variable->increaseMutates(); return $variable; }