Remove dead hphpc options
[hiphop-php.git] / hphp / compiler / option.cpp
blob9763b319356c4c4c0c480533df7d87f4c565f6e3
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #include "hphp/compiler/option.h"
18 #include "hphp/compiler/analysis/analysis_result.h"
19 #include "hphp/compiler/analysis/file_scope.h"
20 #include "hphp/compiler/analysis/class_scope.h"
21 #include "hphp/compiler/analysis/variable_table.h"
22 #include "hphp/parser/scanner.h"
23 #include "hphp/util/logger.h"
24 #include "hphp/util/db-query.h"
25 #include "hphp/util/util.h"
26 #include "hphp/util/process.h"
27 #include <boost/algorithm/string/trim.hpp>
28 #include "hphp/runtime/base/preg.h"
30 using namespace HPHP;
32 using std::set;
33 using std::map;
34 using std::map;
36 ///////////////////////////////////////////////////////////////////////////////
38 std::string Option::SystemRoot;
39 std::string Option::RootDirectory;
40 set<string> Option::PackageDirectories;
41 set<string> Option::PackageFiles;
42 set<string> Option::PackageExcludeDirs;
43 set<string> Option::PackageExcludeFiles;
44 set<string> Option::PackageExcludePatterns;
45 set<string> Option::PackageExcludeStaticDirs;
46 set<string> Option::PackageExcludeStaticFiles;
47 set<string> Option::PackageExcludeStaticPatterns;
48 bool Option::CachePHPFile = false;
50 vector<string> Option::ParseOnDemandDirs;
52 map<string, string> Option::IncludeRoots;
53 map<string, string> Option::AutoloadRoots;
54 vector<string> Option::IncludeSearchPaths;
55 string Option::DefaultIncludeRoot;
56 map<string, int> Option::DynamicFunctionCalls;
58 bool Option::GeneratePickledPHP = false;
59 bool Option::GenerateInlinedPHP = false;
60 bool Option::GenerateTrimmedPHP = false;
61 bool Option::GenerateInferredTypes = false;
62 bool Option::ConvertSuperGlobals = false;
63 bool Option::ConvertQOpExpressions = false;
64 string Option::ProgramPrologue;
65 string Option::TrimmedPrologue;
66 vector<string> Option::DynamicFunctionPrefixes;
67 vector<string> Option::DynamicFunctionPostfixes;
68 vector<string> Option::DynamicMethodPrefixes;
69 vector<string> Option::DynamicMethodPostfixes;
70 vector<string> Option::DynamicClassPrefixes;
71 vector<string> Option::DynamicClassPostfixes;
72 set<string> Option::DynamicInvokeFunctions;
73 set<string> Option::VolatileClasses;
74 map<string,string> Option::AutoloadClassMap;
75 map<string,string> Option::AutoloadFuncMap;
76 map<string,string> Option::AutoloadConstMap;
77 string Option::AutoloadRoot;
79 map<string, string> Option::FunctionSections;
81 bool Option::GenerateTextHHBC = false;
82 bool Option::GenerateBinaryHHBC = false;
83 string Option::RepoCentralPath;
84 bool Option::RepoDebugInfo = false;
86 string Option::IdPrefix = "$$";
87 string Option::LabelEscape = "$";
89 string Option::LambdaPrefix = "df_";
90 string Option::Tab = " ";
92 const char *Option::UserFilePrefix = "php/";
93 const char *Option::ClassHeaderPrefix = "cls/";
95 bool Option::PreOptimization = false;
96 bool Option::PostOptimization = false;
97 bool Option::SeparateCompilation = false;
98 bool Option::SeparateCompLib = false;
99 bool Option::AnalyzePerfectVirtuals = true;
100 bool Option::HardTypeHints = true;
102 bool Option::KeepStatementsWithNoEffect = false;
104 int Option::ConditionalIncludeExpandLevel = 1;
106 int Option::DependencyMaxProgram = 1;
107 int Option::CodeErrorMaxProgram = 1;
109 Option::EvalLevel Option::EnableEval = NoEval;
111 std::string Option::ProgramName;
113 bool Option::ParseTimeOpts = true;
114 bool Option::EnableHipHopSyntax = false;
115 bool Option::EnableZendCompat = false;
116 bool Option::JitEnableRenameFunction = false;
117 bool Option::EnableHipHopExperimentalSyntax = false;
118 bool Option::EnableShortTags = true;
119 bool Option::EnableAspTags = false;
120 bool Option::EnableXHP = false;
121 bool Option::EnableFinallyStatement = false;
122 int Option::ParserThreadCount = 0;
124 int Option::GetScannerType() {
125 int type = 0;
126 if (EnableShortTags) type |= Scanner::AllowShortTags;
127 if (EnableAspTags) type |= Scanner::AllowAspTags;
128 if (EnableXHP) type |= Scanner::AllowXHPSyntax;
129 if (EnableHipHopSyntax) type |= Scanner::AllowHipHopSyntax;
130 return type;
133 int Option::InvokeFewArgsCount = 6;
134 int Option::InlineFunctionThreshold = -1;
135 bool Option::EliminateDeadCode = true;
136 bool Option::CopyProp = false;
137 bool Option::LocalCopyProp = true;
138 bool Option::StringLoopOpts = true;
139 int Option::AutoInline = 0;
140 bool Option::ControlFlow = true;
141 bool Option::VariableCoalescing = false;
142 bool Option::ArrayAccessIdempotent = false;
143 bool Option::DumpAst = false;
144 bool Option::WholeProgram = true;
145 bool Option::RecordErrors = true;
146 std::string Option::DocJson;
148 bool Option::AllDynamic = true;
149 bool Option::AllVolatile = false;
151 StringBag Option::OptionStrings;
153 bool Option::GenerateDocComments = true;
155 void (*Option::m_hookHandler)(Hdf &config);
156 bool (*Option::PersistenceHook)(BlockScopeRawPtr scope, FileScopeRawPtr file);
158 ///////////////////////////////////////////////////////////////////////////////
159 // load from a PHP file
161 std::string Option::GetSystemRoot() {
162 if (SystemRoot.empty()) {
163 const char *home = getenv("HPHP_HOME");
164 if (!home || !*home) {
165 throw Exception("Environment variable HPHP_HOME is not set, "
166 "and neither is the SystemRoot option.");
168 SystemRoot = home;
169 SystemRoot += "/hphp";
171 return SystemRoot;
174 ///////////////////////////////////////////////////////////////////////////////
175 // load from HDF file
177 void Option::LoadRootHdf(const Hdf &roots, map<string, string> &map) {
178 if (roots.exists()) {
179 for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) {
180 map[hdf["root"].get()] = hdf["path"].get();
185 void Option::LoadRootHdf(const Hdf &roots, vector<string> &vec) {
186 if (roots.exists()) {
187 for (Hdf hdf = roots.firstChild(); hdf.exists(); hdf = hdf.next()) {
188 vec.push_back(hdf.getString(""));
193 void Option::Load(Hdf &config) {
194 LoadRootHdf(config["IncludeRoots"], IncludeRoots);
195 LoadRootHdf(config["AutoloadRoots"], AutoloadRoots);
197 config["PackageFiles"].get(PackageFiles);
198 config["IncludeSearchPaths"].get(IncludeSearchPaths);
199 config["PackageDirectories"].get(PackageDirectories);
200 config["PackageExcludeDirs"].get(PackageExcludeDirs);
201 config["PackageExcludeFiles"].get(PackageExcludeFiles);
202 config["PackageExcludePatterns"].get(PackageExcludePatterns);
203 config["PackageExcludeStaticDirs"].get(PackageExcludeStaticDirs);
204 config["PackageExcludeStaticFiles"].get(PackageExcludeStaticFiles);
205 config["PackageExcludeStaticPatterns"].get(PackageExcludeStaticPatterns);
206 CachePHPFile = config["CachePHPFile"].getBool();
208 config["ParseOnDemandDirs"].get(ParseOnDemandDirs);
211 Hdf cg = config["CodeGeneration"];
212 string tmp;
214 #define READ_CG_OPTION(name) \
215 tmp = cg[#name].getString(); \
216 if (!tmp.empty()) { \
217 name = OptionStrings.add(tmp.c_str()); \
220 READ_CG_OPTION(IdPrefix);
221 READ_CG_OPTION(LabelEscape);
222 READ_CG_OPTION(LambdaPrefix);
225 config["DynamicFunctionPrefix"].get(DynamicFunctionPrefixes);
226 config["DynamicFunctionPostfix"].get(DynamicFunctionPostfixes);
227 config["DynamicMethodPrefix"].get(DynamicMethodPrefixes);
228 config["DynamicInvokeFunctions"].get(DynamicInvokeFunctions);
229 config["VolatileClasses"].get(VolatileClasses);
231 // build map from function names to sections
232 for (Hdf hdf = config["FunctionSections"].firstChild(); hdf.exists();
233 hdf = hdf.next()) {
234 for (Hdf hdfFunc = hdf.firstChild(); hdfFunc.exists();
235 hdfFunc = hdfFunc.next()) {
236 FunctionSections[hdfFunc.getString()] = hdf.getName();
241 Hdf repo = config["Repo"];
243 Hdf repoCentral = repo["Central"];
244 RepoCentralPath = repoCentral["Path"].getString();
246 RepoDebugInfo = repo["DebugInfo"].getBool(false);
250 Hdf autoloadMap = config["AutoloadMap"];
251 autoloadMap["class"].get(AutoloadClassMap);
252 autoloadMap["function"].get(AutoloadFuncMap);
253 autoloadMap["constant"].get(AutoloadConstMap);
254 AutoloadRoot = autoloadMap["root"].getString();
257 HardTypeHints = config["HardTypeHints"].getBool(true);
259 EnableHipHopSyntax = config["EnableHipHopSyntax"].getBool();
260 EnableZendCompat = config["EnableZendCompat"].getBool();
261 JitEnableRenameFunction = config["JitEnableRenameFunction"].getBool();
262 EnableHipHopExperimentalSyntax =
263 config["EnableHipHopExperimentalSyntax"].getBool();
264 EnableShortTags = config["EnableShortTags"].getBool(true);
266 EnableAspTags = config["EnableAspTags"].getBool();
268 EnableXHP = config["EnableXHP"].getBool(false);
270 if (EnableHipHopSyntax) {
271 // If EnableHipHopSyntax is true, it forces EnableXHP to true
272 // regardless of how it was set in the config
273 EnableXHP = true;
276 ParserThreadCount = config["ParserThreadCount"].getInt32(0);
277 if (ParserThreadCount <= 0) {
278 ParserThreadCount = Process::GetCPUCount();
281 EnableFinallyStatement = config["EnableFinallyStatement"].getBool();
283 EnableEval = (EvalLevel)config["EnableEval"].getByte(0);
284 AllDynamic = config["AllDynamic"].getBool(true);
285 AllVolatile = config["AllVolatile"].getBool();
287 GenerateDocComments = config["GenerateDocComments"].getBool(true);
288 EliminateDeadCode = config["EliminateDeadCode"].getBool(true);
289 CopyProp = config["CopyProp"].getBool(false);
290 LocalCopyProp = config["LocalCopyProp"].getBool(true);
291 StringLoopOpts = config["StringLoopOpts"].getBool(true);
292 AutoInline = config["AutoInline"].getInt32(0);
293 ControlFlow = config["ControlFlow"].getBool(true);
294 VariableCoalescing = config["VariableCoalescing"].getBool(false);
295 ArrayAccessIdempotent = config["ArrayAccessIdempotent"].getBool(false);
296 DumpAst = config["DumpAst"].getBool(false);
297 WholeProgram = config["WholeProgram"].getBool(true);
299 // Temporary, during file-cache migration.
300 FileCache::UseNewCache = config["UseNewCache"].getBool(false);
302 if (m_hookHandler) m_hookHandler(config);
304 OnLoad();
307 void Option::Load() {
308 OnLoad();
311 void Option::OnLoad() {
312 // all lambda functions are dynamic automatically
313 DynamicFunctionPrefixes.push_back(LambdaPrefix);
316 ///////////////////////////////////////////////////////////////////////////////
318 bool Option::IsDynamicFunction(bool method, const std::string &name) {
319 if (method) {
320 return IsDynamic(name, DynamicMethodPrefixes, DynamicMethodPostfixes);
322 return IsDynamic(name, DynamicFunctionPrefixes, DynamicFunctionPostfixes);
325 bool Option::IsDynamicClass(const std::string &name) {
326 return IsDynamic(name, DynamicClassPrefixes, DynamicClassPostfixes);
329 bool Option::IsDynamic(const std::string &name,
330 const std::vector<std::string> &prefixes,
331 const std::vector<std::string> &postfixes) {
332 if (name.substr(0, 4) == "dyn_") return true;
334 for (unsigned int i = 0; i < prefixes.size(); i++) {
335 const string &prefix = prefixes[i];
336 if (name.substr(0, prefix.length()) == prefix) {
337 return true;
341 for (unsigned int i = 0; i < postfixes.size(); i++) {
342 const string &postfix = postfixes[i];
343 if (name.length() > postfix.length() &&
344 name.substr(name.length() - postfix.length()) == postfix) {
345 return true;
349 return false;
352 std::string Option::GetAutoloadRoot(const std::string &name) {
353 for (map<string, string>::const_iterator iter = AutoloadRoots.begin();
354 iter != AutoloadRoots.end(); ++iter) {
355 if (name.substr(0, iter->first.length()) == iter->first) {
356 return iter->second;
359 return "";
362 std::string Option::MangleFilename(const std::string &name, bool id) {
363 string ret = UserFilePrefix;
364 ret += name;
366 if (id) {
367 Util::replaceAll(ret, "/", "$");
368 Util::replaceAll(ret, "-", "_");
369 Util::replaceAll(ret, ".", "_");
371 return ret;
374 bool Option::IsFileExcluded(const std::string &file,
375 const std::set<std::string> &patterns) {
376 String sfile(file.c_str(), file.size(), CopyString);
377 for (set<string>::const_iterator iter = patterns.begin();
378 iter != patterns.end(); ++iter) {
379 const std::string &pattern = *iter;
380 Variant matches;
381 Variant ret = preg_match(String(pattern.c_str(), pattern.size(),
382 CopyString), sfile, matches);
383 if (ret.toInt64() > 0) {
384 return true;
387 return false;
390 void Option::FilterFiles(std::vector<std::string> &files,
391 const std::set<std::string> &patterns) {
392 for (int i = files.size() - 1; i >= 0; i--) {
393 if (IsFileExcluded(files[i], patterns)) {
394 files.erase(files.begin() + i);