int analyzeTarget(const ProgramOptions &po, AnalysisResultPtr ar) { int ret = 0; if (!po.noTypeInference) { Option::GenerateInferredTypes = true; } if (Option::GenerateInferredTypes) { Timer timer(Timer::WallTime, "inferring types"); ar->inferTypes(); } return ret; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; // load extension functions first, so system/classes may call them ParseExtFunctions(ar, ExtensionFunctions, false); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = systemlib_path(); if (slib.empty()) { for (const char **cls = SystemClasses; *cls; cls++) { string phpBaseName = "/system/classes/"; phpBaseName += *cls; phpBaseName += ".php"; Parse(ar, phpBaseName, Option::GetSystemRoot() + phpBaseName); } } else { Parse(ar, slib, slib); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ParseExtConsts(ar, ExtensionConsts, false); ParseExtClasses(ar, ExtensionClasses, false); for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) { Option::SepExtensionOptions &options = Option::SepExtensions[i]; string soname = options.soname; if (soname.empty()) { soname = string("lib") + options.name + ".so"; } if (!options.lib_path.empty()) { soname = options.lib_path + "/" + soname; } if (!LoadSepExtensionSymbols(ar, options.name, soname)) { return false; } } if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; // Build function scopes for some of the runtime helper functions // declared in "runtime/base/builtin_functions.h" const char **helper = HelperFunctions; while (*helper) { FunctionScopePtr f = ParseHelperFunction(ar, helper); ASSERT(!s_helperFunctions[f->getName()]); s_helperFunctions[f->getName()] = f; } // load extension functions first, so system/classes may call them ParseExtFunctions(ar, ExtensionFunctions, false); AnalysisResultPtr ar2; // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); for (const char **cls = SystemClasses; *cls; cls++) { string phpBaseName = "/system/classes/"; phpBaseName += *cls; phpBaseName += ".php"; string phpFileName = Option::GetSystemRoot() + phpBaseName; const char *baseName = s_strings.add(phpBaseName.c_str()); const char *fileName = s_strings.add(phpFileName.c_str()); try { Scanner scanner(fileName, Option::ScannerType); Compiler::Parser parser(scanner, baseName, ar); if (!parser.parse()) { Logger::Error("Unable to parse file %s: %s", fileName, parser.getMessage().c_str()); ASSERT(false); } } catch (FileOpenException &e) { Logger::Error("%s", e.getMessage().c_str()); } } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { ASSERT(iter->second.size() == 1); iter->second[0]->setSystem(); ASSERT(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } // parse globals/variables.php and globals/constants.php NoSuperGlobals = true; s_variables = LoadGlobalSymbols("symbols.php")->getVariables(); ar2 = LoadGlobalSymbols("constants.php"); const FileScopePtrVec &fileScopes = ar2->getAllFilesVector(); if (!fileScopes.empty()) { s_constants = fileScopes[0]->getConstants(); } else { Logger::Error("Couldn't load constants.php"); return false; } NoSuperGlobals = false; } else { ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); NoSuperGlobals = true; } s_constants->setDynamic(ar, "SID", true); // load extension constants, classes and dynamics ParseExtConsts(ar, ExtensionConsts, false); ParseExtClasses(ar, ExtensionClasses, false); for (unsigned int i = 0; i < Option::SepExtensions.size(); i++) { Option::SepExtensionOptions &options = Option::SepExtensions[i]; string soname = options.soname; if (soname.empty()) { soname = string("lib") + options.name + ".so"; } if (!options.lib_path.empty()) { soname = options.lib_path + "/" + soname; } if (!LoadSepExtensionSymbols(ar, options.name, soname)) { return false; } } return true; }
bool BuiltinSymbols::Load(AnalysisResultPtr ar, bool extOnly /* = false */) { if (Loaded) return true; Loaded = true; if (g_context.isNull()) init_thread_locals(); ClassInfo::Load(); // load extension functions first, so system/classes may call them ImportExtFunctions(ar, s_functions, ClassInfo::GetSystem()); AnalysisResultPtr ar2 = AnalysisResultPtr(new AnalysisResult()); s_variables = VariableTablePtr(new VariableTable(*ar2.get())); s_constants = ConstantTablePtr(new ConstantTable(*ar2.get())); // parse all PHP files under system/classes if (!extOnly) { ar = AnalysisResultPtr(new AnalysisResult()); ar->loadBuiltinFunctions(); string slib = get_systemlib(); Scanner scanner(slib.c_str(), slib.size(), Option::ScannerType, "systemlib.php"); Compiler::Parser parser(scanner, "systemlib.php", ar); if (!parser.parse()) { Logger::Error("Unable to parse systemlib.php: %s", parser.getMessage().c_str()); assert(false); } ar->analyzeProgram(true); ar->inferTypes(); const StringToFileScopePtrMap &files = ar->getAllFiles(); for (StringToFileScopePtrMap::const_iterator iterFile = files.begin(); iterFile != files.end(); iterFile++) { const StringToClassScopePtrVecMap &classes = iterFile->second->getClasses(); for (StringToClassScopePtrVecMap::const_iterator iter = classes.begin(); iter != classes.end(); ++iter) { assert(iter->second.size() == 1); iter->second[0]->setSystem(); assert(!s_classes[iter->first]); s_classes[iter->first] = iter->second[0]; } } } else { NoSuperGlobals = true; } // load extension constants, classes and dynamics ImportExtConstants(ar, s_constants, ClassInfo::GetSystem()); ImportExtClasses(ar); if (!extOnly) { Array constants = ClassInfo::GetSystemConstants(); LocationPtr loc(new Location); for (ArrayIter it = constants.begin(); it; ++it) { CVarRef key = it.first(); if (!key.isString()) continue; std::string name = key.toCStrRef().data(); if (s_constants->getSymbol(name)) continue; if (name == "true" || name == "false" || name == "null") continue; CVarRef value = it.secondRef(); if (!value.isInitialized() || value.isObject()) continue; ExpressionPtr e = Expression::MakeScalarExpression(ar2, ar2, loc, value); TypePtr t = value.isNull() ? Type::Null : value.isBoolean() ? Type::Boolean : value.isInteger() ? Type::Int64 : value.isDouble() ? Type::Double : value.isArray() ? Type::Array : Type::Variant; s_constants->add(key.toCStrRef().data(), t, e, ar2, e); } s_variables = ar2->getVariables(); for (int i = 0, n = NumGlobalNames(); i < n; ++i) { s_variables->add(GlobalNames[i], Type::Variant, false, ar, ConstructPtr(), ModifierExpressionPtr()); } } s_constants->setDynamic(ar, "SID", true); return true; }
int cppTarget(const ProgramOptions &po, AnalysisResultPtr ar, bool allowSys /* = true */) { int ret = 0; int clusterCount = po.clusterCount; // format CodeGenerator::Output format = CodeGenerator::InvalidOutput; if (po.format == "file") { clusterCount = 0; format = CodeGenerator::FileCPP; } else if (po.format == "cluster") { format = CodeGenerator::ClusterCPP; } else if (po.format == "sys" && allowSys) { clusterCount = 0; format = CodeGenerator::SystemCPP; ar->setSystem(); } else if (po.format == "exe" || po.format == "lib") { format = CodeGenerator::ClusterCPP; } if (format == CodeGenerator::InvalidOutput) { Logger::Error("Unknown format for CPP target: %s", po.format.c_str()); return 1; } if (!po.noTypeInference) { Option::GenerateInferredTypes = true; } if (Option::PreOptimization) { Timer timer(Timer::WallTime, "pre-optimizing"); ar->preOptimize(); } if (!Option::RTTIOutputFile.empty()) { if (!po.rttiDirectory.empty()) { Option::UseRTTIProfileData = true; ar->cloneRTTIFuncs(po.rttiDirectory.c_str()); } else { Option::GenRTTIProfileData = true; } } if (Option::GenerateInferredTypes) { Timer timer(Timer::WallTime, "inferring types"); ar->inferTypes(); } if (Option::PostOptimization) { Timer timer(Timer::WallTime, "post-optimizing"); ar->postOptimize(); } ar->analyzeProgramFinal(); //MethodSlot::genMethodSlot(ar); { Timer timer(Timer::WallTime, "creating CPP files"); if (po.syncDir.empty()) { ar->setOutputPath(po.outputDir); ar->outputAllCPP(format, clusterCount, NULL); } else { ar->setOutputPath(po.syncDir); ar->outputAllCPP(format, clusterCount, &po.outputDir); Util::syncdir(po.outputDir, po.syncDir); boost::filesystem::remove_all(po.syncDir); } } return ret; }
int phpTarget(const ProgramOptions &po, AnalysisResultPtr ar) { int ret = 0; // format int formatCount = 0; if (po.format.find("pickled") != string::npos) { Option::GeneratePickledPHP = true; formatCount++; } if (po.format.find("inlined") != string::npos) { Option::GenerateInlinedPHP = true; formatCount++; } if (po.format.find("trimmed") != string::npos) { Option::GenerateTrimmedPHP = true; formatCount++; } if (po.format.find("typeinfo") != string::npos) { Option::GenerateInferredTypes = true; } if (formatCount == 0) { Logger::Error("Unknown format for PHP target: %s", po.format.c_str()); return 1; } // analyze if (Option::GenerateInferredTypes || Option::ConvertSuperGlobals) { Logger::Info("inferring types..."); ar->inferTypes(); } // generate ar->setOutputPath(po.outputDir); if (Option::GeneratePickledPHP) { Logger::Info("creating pickled PHP files..."); string outputDir = po.outputDir; if (formatCount > 1) outputDir += "/pickled"; mkdir(outputDir.c_str(), 0777); ar->outputAllPHP(CodeGenerator::PickledPHP); } if (Option::GenerateInlinedPHP) { Logger::Info("creating inlined PHP files..."); string outputDir = po.outputDir; if (formatCount > 1) outputDir += "/inlined"; mkdir(outputDir.c_str(), 0777); if (!ar->outputAllPHP(CodeGenerator::InlinedPHP)) { ret = -1; } } if (Option::GenerateTrimmedPHP) { Logger::Info("creating trimmed PHP files..."); string outputDir = po.outputDir; if (formatCount > 1) outputDir += "/trimmed"; mkdir(outputDir.c_str(), 0777); if (!ar->outputAllPHP(CodeGenerator::TrimmedPHP)) { ret = -1; } } return ret; }