void ClassVariable::onParse(AnalysisResultPtr ar) { ModifierExpressionPtr modifiers = ar->getScope()->setModifiers(m_modifiers); for (int i = 0; i < m_declaration->getCount(); i++) { VariableTablePtr variables = ar->getScope()->getVariables(); ExpressionPtr exp = (*m_declaration)[i]; if (exp->is(Expression::KindOfAssignmentExpression)) { AssignmentExpressionPtr assignment = dynamic_pointer_cast<AssignmentExpression>(exp); ExpressionPtr var = assignment->getVariable(); const std::string &name = dynamic_pointer_cast<SimpleVariable>(var)->getName(); if (variables->isPresent(name)) { ar->getCodeError()->record(CodeError::DeclaredVariableTwice, exp); } IParseHandlerPtr ph = dynamic_pointer_cast<IParseHandler>(exp); ph->onParse(ar); } else { const std::string &name = dynamic_pointer_cast<SimpleVariable>(exp)->getName(); if (variables->isPresent(name)) { ar->getCodeError()->record(CodeError::DeclaredVariableTwice, exp); } variables->add(name, TypePtr(), false, ar, exp, m_modifiers); } } ar->getScope()->setModifiers(modifiers); }
TypePtr NewObjectExpression::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { reset(); ConstructPtr self = shared_from_this(); if (!m_name.empty()) { ClassScopePtr cls = ar->resolveClass(m_name); if (cls) { m_name = cls->getName(); } if (!cls || cls->isRedeclaring()) { if (cls) { m_redeclared = true; ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } if (!cls && ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UnknownClass, self); } if (m_params) m_params->inferAndCheck(ar, NEW_TYPE(Any), false); return NEW_TYPE(Object); } if (cls->isVolatile()) { ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } m_dynamic = cls->derivesFromRedeclaring(); m_validClass = true; FunctionScopePtr func = cls->findConstructor(ar, true); if (!func) { if (m_params) { if (!m_dynamic && m_params->getCount()) { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::BadConstructorCall, self); } m_params->setOutputCount(0); } m_params->inferAndCheck(ar, NEW_TYPE(Any), false); } } else { m_extraArg = func->inferParamTypes(ar, self, m_params, m_validClass); m_variableArgument = func->isVariableArgument(); } return Type::CreateObjectType(m_name); } else { ar->containsDynamicClass(); if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseDynamicClass, self); } if (m_params) { m_params->markParams(false); } } m_nameExp->inferAndCheck(ar, Type::String, false); if (m_params) m_params->inferAndCheck(ar, NEW_TYPE(Any), false); return Type::Variant;//NEW_TYPE(Object); }
void GlobalStatement::outputCPP(CodeGenerator &cg, AnalysisResultPtr ar) { if (m_dynamicGlobal) { cg.printf("throw_fatal(\"dynamic global\");\n"); } else if (!ar->getScope()->inPseudoMain() || !isTopLevel()) { BlockScopePtr scope = ar->getScope(); if (m_exp->getCount() > 1) cg.indentBegin("{\n"); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; if (exp->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp); const string &name = var->getName(); VariableTablePtr variables = scope->getVariables(); if (variables->needLocalCopy(name)) { cg.printf("%s%s = ref(g->%s);\n", Option::VariablePrefix, name.c_str(), variables->getGlobalVariableName(ar, name).c_str()); } } else { // type inference should have set m_dynamicGlobal to true. ASSERT(false); } } if (m_exp->getCount() > 1) cg.indentEnd("}\n"); } }
void ForEachStatement::inferTypes(AnalysisResultPtr ar) { if (ar->isFirstPass() && !m_array->is(Expression::KindOfSimpleVariable) && !m_array->is(Expression::KindOfArrayElementExpression) && !m_array->is(Expression::KindOfObjectPropertyExpression)) { ConstructPtr self = shared_from_this(); ar->getCodeError()->record(self, CodeError::ComplexForEach, self); } m_array->inferAndCheck(ar, Type::Array, true); if (m_name) { m_name->inferAndCheck(ar, NEW_TYPE(Primitive), true); } m_value->inferAndCheck(ar, Type::Variant, true); if (m_ref) { TypePtr actualType = m_array->getActualType(); if (!actualType || actualType->is(Type::KindOfVariant) || actualType->is(Type::KindOfObject)) { ar->forceClassVariants(); } } if (m_stmt) { ar->getScope()->incLoopNestedLevel(); m_stmt->inferTypes(ar); ar->getScope()->decLoopNestedLevel(); } }
void SimpleVariable::analyzeProgram(AnalysisResultPtr ar) { Expression::analyzeProgram(ar); if (m_name == "argc" || m_name == "argv") { // special case: they are NOT superglobals when not in global scope if (ar->getScope() == ar) { m_superGlobal = BuiltinSymbols::IsSuperGlobal(m_name); m_superGlobalType = BuiltinSymbols::GetSuperGlobalType(m_name); } } else { m_superGlobal = BuiltinSymbols::IsSuperGlobal(m_name); m_superGlobalType = BuiltinSymbols::GetSuperGlobalType(m_name); } if (m_superGlobal) { ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } if (m_name == "this" && ar->getClassScope()) { FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(ar->getScope()); func->setContainsThis(); m_this = true; } else if (m_name == "GLOBALS") { m_globals = true; } if (!(m_context & AssignmentLHS)) { BlockScopePtr scope = ar->getScope(); FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(scope); if (func) { func->getVariables()->addUsed(m_name); } } }
void WhileStatement::inferTypes(AnalysisResultPtr ar) { m_condition->inferAndCheck(ar, Type::Boolean, false); if (m_stmt) { ar->getScope()->incLoopNestedLevel(); m_stmt->inferTypes(ar); ar->getScope()->decLoopNestedLevel(); } }
TypePtr AssignmentExpression:: inferTypesImpl(AnalysisResultPtr ar, TypePtr type, bool coerce, ExpressionPtr variable, ExpressionPtr value /* = ExpressionPtr() */) { TypePtr ret = type; if (value) { if (coerce) { ret = value->inferAndCheck(ar, type, coerce); } else { ret = value->inferAndCheck(ar, NEW_TYPE(Some), coerce); } } BlockScopePtr scope = ar->getScope(); if (variable->is(Expression::KindOfConstantExpression)) { // ...as in ClassConstant statement ConstantExpressionPtr exp = dynamic_pointer_cast<ConstantExpression>(variable); bool p; scope->getConstants()->check(exp->getName(), ret, true, ar, variable, p); } else if (variable->is(Expression::KindOfDynamicVariable)) { // simptodo: not too sure about this ar->getFileScope()->setAttribute(FileScope::ContainsLDynamicVariable); } else if (variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); if (var->getName() == "this" && ar->getClassScope()) { if (ar->isFirstPass()) { ar->getCodeError()->record(variable, CodeError::ReassignThis, variable); } } if (ar->getPhase() == AnalysisResult::LastInference && value) { if (!value->getExpectedType()) { value->setExpectedType(variable->getActualType()); } } } // if the value may involve object, consider the variable as "referenced" // so that objects are not destructed prematurely. bool referenced = true; if (value && value->isScalar()) referenced = false; if (ret && ret->isNoObjectInvolved()) referenced = false; if (referenced && variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); const std::string &name = var->getName(); VariableTablePtr variables = ar->getScope()->getVariables(); variables->addReferenced(name); } TypePtr vt = variable->inferAndCheck(ar, ret, true); if (!coerce && type->is(Type::KindOfAny)) { ret = vt; } return ret; }
StatementPtr WhileStatement::postOptimize(AnalysisResultPtr ar) { ar->postOptimize(m_condition); if (m_stmt) { ar->getScope()->incLoopNestedLevel(); ar->postOptimize(m_stmt); ar->getScope()->decLoopNestedLevel(); } return StatementPtr(); }
StatementPtr ForStatement::postOptimize(AnalysisResultPtr ar) { ar->postOptimize(m_exp1); ar->postOptimize(m_exp2); ar->postOptimize(m_exp3); if (m_stmt) { ar->getScope()->incLoopNestedLevel(); ar->postOptimize(m_stmt); ar->getScope()->decLoopNestedLevel(); } return StatementPtr(); }
void ForStatement::inferTypes(AnalysisResultPtr ar) { if (m_exp1) m_exp1->inferAndCheck(ar, NEW_TYPE(Any), false); if (m_exp2) m_exp2->inferAndCheck(ar, Type::Boolean, false); if (m_stmt) { ar->getScope()->incLoopNestedLevel(); m_stmt->inferTypes(ar); if (m_exp3) m_exp3->inferAndCheck(ar, NEW_TYPE(Any), false); ar->getScope()->decLoopNestedLevel(); } else { if (m_exp3) m_exp3->inferAndCheck(ar, NEW_TYPE(Any), false); } }
void ArrayElementExpression::outputPHP(CodeGenerator &cg, AnalysisResultPtr ar) { if (Option::ConvertSuperGlobals && m_global && !m_dynamicGlobal && ar && (ar->getScope() == ar || ar->getScope()-> getVariables()->isConvertibleSuperGlobal(m_globalName))) { cg_printf("$%s", m_globalName.c_str()); } else { m_variable->outputPHP(cg, ar); cg_printf("["); if (m_offset) m_offset->outputPHP(cg, ar); cg_printf("]"); } }
void MethodStatement::addParamRTTI(AnalysisResultPtr ar) { FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(ar->getScope()); VariableTablePtr variables = func->getVariables(); if (variables->getAttribute(VariableTable::ContainsDynamicVariable) || variables->getAttribute(VariableTable::ContainsExtract)) { return; } for (int i = 0; i < m_params->getCount(); i++) { ParameterExpressionPtr param = dynamic_pointer_cast<ParameterExpression>((*m_params)[i]); const string ¶mName = param->getName(); if (variables->isLvalParam(paramName)) continue; TypePtr paramType = param->getActualType(); if ((paramType->is(Type::KindOfVariant) || paramType->is(Type::KindOfSome)) && !param->isRef()) { param->setHasRTTI(); ClassScopePtr cls = ar->getClassScope(); ar->addParamRTTIEntry(cls, func, paramName); const string funcId = ar->getFuncId(cls, func); ar->addRTTIFunction(funcId); } } }
bool AliasManager::optimize(AnalysisResultPtr ar, MethodStatementPtr m) { m_arp = ar; m_variables = ar->getScope()->getVariables(); if (!m_variables->isPseudoMainTable()) { m_variables->clearUsed(); } if (ExpressionListPtr pPtr = m->getParams()) { ExpressionList ¶ms = *pPtr; for (int i = params.getCount(); i--; ) { ParameterExpressionPtr p = spc(ParameterExpression, params[i]); AliasInfo &ai = m_aliasInfo[p->getName()]; if (p->isRef()) { ai.setIsRefTo(); } } } collectAliasInfoRecur(m->getStmts()); for (AliasInfoMap::iterator it = m_aliasInfo.begin(), end = m_aliasInfo.end(); it != end; ++it) { if (m_variables->isGlobal(it->first) || m_variables->isStatic(it->first)) { it->second.setIsGlobal(); } } canonicalizeRecur(m->getStmts()); return m_changed; }
void CatchStatement::analyzeProgramImpl(AnalysisResultPtr ar) { addUserClass(ar, m_className); if (ar->isFirstPass()) { ar->getScope()->getVariables()->addUsed(m_variable); } if (m_stmt) m_stmt->analyzeProgram(ar); }
void CatchStatement::inferTypes(AnalysisResultPtr ar) { ClassScopePtr cls = ar->findClass(m_className); TypePtr type; m_valid = cls; if (!m_valid) { if (ar->isFirstPass()) { ConstructPtr self = shared_from_this(); ar->getCodeError()->record(self, CodeError::UnknownClass, self); } type = NEW_TYPE(Object); } else if (cls->isRedeclaring()) { type = NEW_TYPE(Object); } else { type = Type::CreateObjectType(m_className); } BlockScopePtr scope = ar->getScope(); VariableTablePtr variables = scope->getVariables(); variables->add(m_variable, type, false, ar, shared_from_this(), ModifierExpressionPtr(), false); if (ar->isFirstPass()) { FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(scope); if (func && variables->isParameter(m_variable)) { variables->addLvalParam(m_variable); } } if (m_stmt) m_stmt->inferTypes(ar); }
TypePtr DynamicFunctionCall::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { reset(); ConstructPtr self = shared_from_this(); if (!m_className.empty()) { ClassScopePtr cls = ar->resolveClass(m_className); if (!cls || cls->isRedeclaring()) { if (cls) { m_redeclared = true; ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } if (!cls && ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UnknownClass, self); } } else { m_validClass = true; } } ar->containsDynamicFunctionCall(); if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseDynamicFunction, self); } m_nameExp->inferAndCheck(ar, Type::String, false); if (m_params) { for (int i = 0; i < m_params->getCount(); i++) { (*m_params)[i]->inferAndCheck(ar, Type::Variant, true); } } return Type::Variant; }
TypePtr DynamicVariable::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { ConstructPtr self = shared_from_this(); if (m_context & (LValue | RefValue)) { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseLDynamicVariable, self); } ar->getScope()->getVariables()->forceVariants(ar); ar->getScope()-> getVariables()->setAttribute(VariableTable::ContainsLDynamicVariable); } else { if (ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UseRDynamicVariable, self); } } m_exp->inferAndCheck(ar, Type::String, false); return m_implementedType = Type::Variant; }
TypePtr AssignmentExpression::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { if (VariableTable::m_hookHandler) { VariableTable::m_hookHandler(ar, ar->getScope()->getVariables().get(), m_variable, beforeAssignmentExpressionInferTypes); } TypePtr ret = inferAssignmentTypes(ar, type, coerce, m_variable, m_value); if (VariableTable::m_hookHandler) { VariableTable::m_hookHandler(ar, ar->getScope()->getVariables().get(), m_variable, afterAssignmentExpressionInferTypes); } return ret; }
void CatchStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { if (m_valid) { cg.indentBegin("if (e.instanceof(\"%s\")) {\n", m_className.c_str()); VariableTablePtr variables = ar->getScope()->getVariables(); cg.printf("%s = e;\n", variables->getVariableName(ar, m_variable).c_str()); } else { cg.indentBegin("if (false) {\n"); } if (m_stmt) m_stmt->outputCPP(cg, ar); cg.indentEnd("}"); }
void AssignmentExpression::analyzeProgram(AnalysisResultPtr ar) { m_variable->analyzeProgram(ar); m_value->analyzeProgram(ar); if (ar->getPhase() == AnalysisResult::AnalyzeAll) { if (m_ref && m_variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(m_variable); const std::string &name = var->getName(); VariableTablePtr variables = ar->getScope()->getVariables(); variables->addUsed(name); } if (m_variable->is(Expression::KindOfConstantExpression)) { ConstantExpressionPtr exp = dynamic_pointer_cast<ConstantExpression>(m_variable); if (!m_value->isScalar()) { ar->getScope()->getConstants()->setDynamic(ar, exp->getName()); } } } }
TypePtr ClassConstantExpression::inferTypes(AnalysisResultPtr ar, TypePtr type, bool coerce) { m_valid = false; ConstructPtr self = shared_from_this(); ClassScopePtr cls = ar->resolveClass(m_className); if (!cls || cls->isRedeclaring()) { if (cls) { m_redeclared = true; ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } if (!cls && ar->isFirstPass()) { ar->getCodeError()->record(self, CodeError::UnknownClass, self); } return type; } if (cls->getConstants()->isDynamic(m_varName)) { ar->getScope()->getVariables()-> setAttribute(VariableTable::NeedGlobalPointer); } if (cls->getConstants()->isExplicitlyDeclared(m_varName)) { string name = m_className + "::" + m_varName; ConstructPtr decl = cls->getConstants()->getDeclaration(m_varName); if (decl) { // No decl means an extension class. ar->getDependencyGraph()->add(DependencyGraph::KindOfConstant, ar->getName(), name, shared_from_this(), name, decl); } m_valid = true; } bool present; TypePtr t = cls->checkConst(m_varName, type, coerce, ar, shared_from_this(), present); if (present) { m_valid = true; } return t; }
void IncludeExpression::analyzeProgram(AnalysisResultPtr ar) { if (ar->isFirstPass()) { ConstructPtr self = shared_from_this(); if (m_op == T_INCLUDE || m_op == T_REQUIRE) { ar->getCodeError()->record(self, CodeError::UseInclude, self); } } string include = getCurrentInclude(ar); if (!include.empty()) { if (ar->getPhase() == AnalysisResult::AnalyzeInclude) { analyzeInclude(ar, include); } } if (!ar->getScope()->inPseudoMain()) { VariableTablePtr var = ar->getScope()->getVariables(); var->setAttribute(VariableTable::ContainsLDynamicVariable); var->forceVariants(ar); } UnaryOpExpression::analyzeProgram(ar); }
void SimpleVariable::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { if (m_this) { ASSERT((getContext() & ObjectContext) == 0); if (hasContext(LValue)) { // LValue and not ObjectContext must be $this = or $this[..] = // Wrap with Variant to avoid compiler error cg_printf("Variant(GET_THIS())"); } else { cg_printf("GET_THIS()"); } } else if (m_superGlobal) { VariableTablePtr variables = ar->getScope()->getVariables(); string name = variables->getGlobalVariableName(cg, ar, m_name); cg_printf("g->%s", name.c_str()); } else if (m_globals) { cg_printf("get_global_array_wrapper()"); } else { const char *prefix = ar->getScope()->getVariables()->getVariablePrefix(ar, m_name); cg_printf("%s%s", prefix, cg.formatLabel(m_name).c_str()); } }
void ParameterExpression::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { FunctionScopePtr func = dynamic_pointer_cast<FunctionScope>(ar->getScope()); VariableTablePtr variables = func->getVariables(); TypePtr paramType = func->getParamType(cg.getItemIndex()); bool isCVarRef = false; if (cg.getContext() == CodeGenerator::CppStaticMethodWrapper || (!variables->isLvalParam(m_name) && !variables->getAttribute(VariableTable::ContainsDynamicVariable) && !variables->getAttribute(VariableTable::ContainsExtract) && !m_ref)) { if (paramType->is(Type::KindOfVariant) || paramType->is(Type::KindOfSome)) { cg_printf("CVarRef"); isCVarRef = true; } else if (paramType->is(Type::KindOfArray)) cg_printf("CArrRef"); else if (paramType->is(Type::KindOfString)) cg_printf("CStrRef"); else paramType->outputCPPDecl(cg, ar); } else { paramType->outputCPPDecl(cg, ar); } cg_printf(" %s%s", Option::VariablePrefix, m_name.c_str()); if (m_defaultValue) { CodeGenerator::Context context = cg.getContext(); bool comment = context == CodeGenerator::CppImplementation || (context == CodeGenerator::CppDeclaration && func->isInlined()); if (comment) { cg_printf(" // "); } cg_printf(" = "); ConstantExpressionPtr con = dynamic_pointer_cast<ConstantExpression>(m_defaultValue); if (isCVarRef && con && con->isNull()) { cg_printf("null_variant"); } else { if (comment) { cg.setContext(CodeGenerator::CppParameterDefaultValueImpl); } else { cg.setContext(CodeGenerator::CppParameterDefaultValueDecl); } m_defaultValue->outputCPP(cg, ar); cg.setContext(context); } if (comment) { cg_printf("\n"); } } }
void StaticStatement::outputCPPImpl(CodeGenerator &cg, AnalysisResultPtr ar) { BlockScopePtr scope = ar->getScope(); if (scope->inPseudoMain()) { if (m_exp->getCount() > 1) cg_indentBegin("{\n"); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; if (exp->is(Expression::KindOfAssignmentExpression)) { exp->outputCPP(cg, ar); cg_printf(";\n"); } else { ASSERT(false); } } if (m_exp->getCount() > 1) cg_indentEnd("}\n"); return; } VariableTablePtr variables = scope->getVariables(); if (m_exp->getCount() > 1) cg_indentBegin("{\n"); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; if (exp->is(Expression::KindOfAssignmentExpression)) { AssignmentExpressionPtr assignment_exp = dynamic_pointer_cast<AssignmentExpression>(exp); ExpressionPtr variable = assignment_exp->getVariable(); SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); var->setContext(Expression::Declaration); const std::string &name = var->getName(); if (variables->needLocalCopy(name)) { cg_printf("%s%s = ref(%s%s);\n", Option::VariablePrefix, name.c_str(), Option::StaticVariablePrefix, name.c_str()); } cg_indentBegin("if (!%s%s%s) {\n", Option::InitPrefix, Option::StaticVariablePrefix, name.c_str()); exp->outputCPP(cg, ar); cg_printf(";\n"); cg_printf("%s%s%s = true;\n", Option::InitPrefix, Option::StaticVariablePrefix, name.c_str()); cg_indentEnd("}\n"); } else { ASSERT(false); } } if (m_exp->getCount() > 1) cg_indentEnd("}\n"); }
void StaticStatement::analyzeProgramImpl(AnalysisResultPtr ar) { m_exp->analyzeProgram(ar); BlockScopePtr scope = ar->getScope(); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; ExpressionPtr variable; ExpressionPtr value; if (ar->getPhase() == AnalysisResult::AnalyzeInclude) { // turn static $a; into static $a = null; if (exp->is(Expression::KindOfSimpleVariable)) { variable = dynamic_pointer_cast<SimpleVariable>(exp); exp = AssignmentExpressionPtr (new AssignmentExpression(exp->getLocation(), Expression::KindOfAssignmentExpression, variable, CONSTANT("null"), false)); (*m_exp)[i] = exp; } } if (exp->is(Expression::KindOfAssignmentExpression)) { AssignmentExpressionPtr assignment_exp = dynamic_pointer_cast<AssignmentExpression>(exp); variable = assignment_exp->getVariable(); value = assignment_exp->getValue(); } else { ASSERT(false); } SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(variable); if (ar->getPhase() == AnalysisResult::AnalyzeInclude) { if (scope->getVariables()->setStaticInitVal(var->getName(), value)) { ar->getCodeError()->record(CodeError::DeclaredStaticVariableTwice, exp); } } else if (ar->getPhase() == AnalysisResult::AnalyzeAll) { // update initial value const string &name = var->getName(); ExpressionPtr initValue = (dynamic_pointer_cast<Expression> (scope->getVariables()->getStaticInitVal(name)))->clone(); exp = AssignmentExpressionPtr (new AssignmentExpression(exp->getLocation(), Expression::KindOfAssignmentExpression, variable, initValue, false)); (*m_exp)[i] = exp; } } }
void GlobalStatement::inferTypes(AnalysisResultPtr ar) { BlockScopePtr scope = ar->getScope(); scope->getVariables()->setAttribute(VariableTable::InsideGlobalStatement); for (int i = 0; i < m_exp->getCount(); i++) { ExpressionPtr exp = (*m_exp)[i]; if (exp->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(exp); VariableTablePtr variables = scope->getVariables(); const std::string &name = var->getName(); /* If we have already seen this variable in the current scope and it is not a global variable, record this variable as "redeclared" which will force Variant type. */ variables->checkRedeclared(name, KindOfGlobalStatement); /* If this is not a top-level global statement, the variable also needs to be Variant type. This should not be a common use case in php code. */ if (!isTopLevel()) { variables->addNestedGlobal(name); } var->setContext(Expression::Declaration); var->inferAndCheck(ar, NEW_TYPE(Any), true); if (variables->needLocalCopy(name)) { variables->forceVariant(ar, name); variables->setAttribute(VariableTable::NeedGlobalPointer); } ConstructPtr decl = ar->getVariables()->getDeclaration(var->getName()); if (decl) { ar->getDependencyGraph()->add(DependencyGraph::KindOfGlobalVariable, ar->getName(), var->getName(), var, var->getName(), decl); } } else { if (ar->isFirstPass()) { ar->getCodeError()->record(shared_from_this(), CodeError::UseDynamicGlobal, exp); } m_dynamicGlobal = true; } } FunctionScopePtr func = ar->getFunctionScope(); scope->getVariables()->clearAttribute(VariableTable::InsideGlobalStatement); }
ExpressionPtr AssignmentExpression::postOptimize(AnalysisResultPtr ar) { ar->postOptimize(m_variable); ar->postOptimize(m_value); if (m_variable->is(Expression::KindOfSimpleVariable)) { SimpleVariablePtr var = dynamic_pointer_cast<SimpleVariable>(m_variable); const std::string &name = var->getName(); VariableTablePtr variables = ar->getScope()->getVariables(); if (variables->checkUnused(name)) { variables->addUnused(name); if (m_value->getContainedEffects() != getContainedEffects()) { s_effectsTag++; } return m_value; } } return ExpressionPtr(); }
void MethodStatement::onParse(AnalysisResultPtr ar) { ClassScopePtr classScope = dynamic_pointer_cast<ClassScope>(ar->getScope()); classScope->addFunction(ar, onParseImpl(ar)); if (m_name == "__construct") { classScope->setAttribute(ClassScope::HasConstructor); } else if (m_name == "__destruct") { classScope->setAttribute(ClassScope::HasDestructor); } if (m_name == "__call") { classScope->setAttribute(ClassScope::HasUnknownMethodHandler); } else if (m_name == "__get") { classScope->setAttribute(ClassScope::HasUnknownPropHandler); } m_className = classScope->getName(); }
void ArrayElementExpression::outputCPPExistTest(CodeGenerator &cg, AnalysisResultPtr ar, int op) { switch (op) { case T_ISSET: cg_printf("isset("); break; case T_EMPTY: cg_printf("empty("); break; default: ASSERT(false); } if (m_global) { if (!m_globalName.empty()) { VariableTablePtr variables = ar->getScope()->getVariables(); string name = variables->getGlobalVariableName(cg, ar, m_globalName); cg_printf("g->%s", name.c_str()); } else { cg_printf("get_variable_table()->get("); m_offset->outputCPP(cg, ar); cg_printf(")"); } } else { m_variable->outputCPP(cg, ar); cg_printf(", "); m_offset->outputCPP(cg, ar); ScalarExpressionPtr sc = dynamic_pointer_cast<ScalarExpression>(m_offset); if (sc) { int64 hash = sc->getHash(); if (hash >= 0) { cg_printf(", 0x%016llXLL", hash); } if (sc->isLiteralString()) { String s(sc->getLiteralString()); int64 n; if (!s.get()->isStrictlyInteger(n)) { cg_printf(", true"); // skip toKey() at run time } } } } cg_printf(")"); }