2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present 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"
25 #include "hphp/runtime/base/config.h"
26 #include "hphp/runtime/base/ini-setting.h"
27 #include "hphp/runtime/base/preg.h"
28 #include "hphp/runtime/base/variable-unserializer.h"
30 #include "hphp/util/hdf.h"
31 #include "hphp/util/logger.h"
32 #include "hphp/util/process.h"
35 ///////////////////////////////////////////////////////////////////////////////
37 hphp_fast_string_set
Option::PackageExcludeDirs
;
38 hphp_fast_string_set
Option::PackageExcludeFiles
;
39 hphp_fast_string_set
Option::PackageExcludePatterns
;
40 hphp_fast_string_set
Option::PackageExcludeStaticDirs
;
41 hphp_fast_string_set
Option::PackageExcludeStaticFiles
;
42 hphp_fast_string_set
Option::PackageExcludeStaticPatterns
;
44 bool Option::CachePHPFile
= false;
46 hphp_fast_string_imap
<std::string
> Option::AutoloadClassMap
;
47 hphp_fast_string_imap
<std::string
> Option::AutoloadFuncMap
;
48 hphp_fast_string_map
<std::string
> Option::AutoloadConstMap
;
49 std::string
Option::AutoloadRoot
;
51 bool Option::GenerateTextHHBC
= false;
52 bool Option::GenerateHhasHHBC
= false;
53 bool Option::GenerateBinaryHHBC
= false;
55 int Option::ParserThreadCount
= 0;
57 // These default sizes were selected by experimentation
58 const int Option::kDefaultParserGroupSize
= 500;
59 const int Option::kDefaultParserDirGroupSizeLimit
= 50000;
61 int Option::ParserGroupSize
= kDefaultParserGroupSize
;
62 int Option::ParserDirGroupSizeLimit
= kDefaultParserDirGroupSizeLimit
;
63 bool Option::ParserAsyncCleanup
= true;
65 std::string
Option::ExternWorkerUseCase
;
66 bool Option::ExternWorkerForceSubprocess
= false;
67 int Option::ExternWorkerTimeoutSecs
= 0;
68 bool Option::ExternWorkerUseExecCache
= true;
69 bool Option::ExternWorkerCleanup
= true;
70 std::string
Option::ExternWorkerWorkingDir
;
72 ///////////////////////////////////////////////////////////////////////////////
75 void Option::LoadRootHdf(const IniSetting::Map
& ini
,
77 const std::string
& name
,
78 std::map
<std::string
, std::string
> &map
) {
79 auto root_map_callback
= [&](const IniSetting::Map
& ini_rm
, const Hdf
& hdf_rm
,
80 const std::string
& /*ini_rm_key*/) {
81 map
[Config::GetString(ini_rm
, hdf_rm
, "root", "", false)] =
82 Config::GetString(ini_rm
, hdf_rm
, "path", "", false);
84 Config::Iterate(root_map_callback
, ini
, roots
, name
);
87 void Option::Load(const IniSetting::Map
& ini
, Hdf
&config
) {
88 LoadRootHdf(ini
, config
, "IncludeRoots", RuntimeOption::IncludeRoots
);
89 LoadRootHdf(ini
, config
, "AutoloadRoots", RuntimeOption::AutoloadRoots
);
91 Config::Bind(PackageExcludeDirs
, ini
, config
, "PackageExcludeDirs");
92 Config::Bind(PackageExcludeFiles
, ini
, config
, "PackageExcludeFiles");
93 Config::Bind(PackageExcludePatterns
, ini
, config
, "PackageExcludePatterns");
94 Config::Bind(PackageExcludeStaticDirs
, ini
,
95 config
, "PackageExcludeStaticDirs");
96 Config::Bind(PackageExcludeStaticFiles
, ini
,
97 config
, "PackageExcludeStaticFiles");
98 Config::Bind(PackageExcludeStaticFiles
, ini
,
99 config
, "PackageExcludeStaticPatterns");
100 Config::Bind(CachePHPFile
, ini
, config
, "CachePHPFile");
102 for (auto& str
: Config::GetStrVector(ini
, config
, "ConstantFunctions")) {
105 if (folly::split('|', str
, func
, value
)) {
106 VariableUnserializer uns
{
107 value
.data(), value
.size(),
108 VariableUnserializer::Type::Internal
,
109 /* allowUnknownSerializableClass = */ false,
113 auto v
= uns
.unserialize();
115 RuntimeOption::ConstantFunctions
[func
] = *v
.asTypedValue();
117 } catch (const Exception
& e
) {
118 // fall through and log
121 Logger::FError("Invalid ConstantFunction: '{}'\n", str
);
126 Config::Bind(RuntimeOption::RepoDebugInfo
,
127 ini
, config
, "Repo.DebugInfo",
128 RuntimeOption::RepoDebugInfo
);
133 // not using Bind here because those maps are enormous and cause performance
134 // problems when showing up later
135 AutoloadClassMap
= Config::GetIFastMap(ini
, config
, "AutoloadMap.class");
136 AutoloadFuncMap
= Config::GetIFastMap(ini
, config
, "AutoloadMap.function");
137 AutoloadConstMap
= Config::GetFastMap(ini
, config
, "AutoloadMap.constant");
138 AutoloadRoot
= Config::GetString(ini
, config
, "AutoloadMap.root");
141 Config::Bind(RuntimeOption::EvalCheckPropTypeHints
, ini
, config
,
142 "CheckPropTypeHints", RuntimeOption::EvalCheckPropTypeHints
);
144 Config::Bind(RuntimeOption::EnableHipHopSyntax
,
145 ini
, config
, "EnableHipHopSyntax",
146 RuntimeOption::EnableHipHopSyntax
);
147 Config::Bind(RuntimeOption::EvalJitEnableRenameFunction
,
148 ini
, config
, "JitEnableRenameFunction",
149 RuntimeOption::EvalJitEnableRenameFunction
);
150 Config::Bind(RuntimeOption::EvalHackArrCompatSerializeNotices
,
151 ini
, config
, "HackArrCompatSerializeNotices",
152 RuntimeOption::EvalHackArrCompatSerializeNotices
);
153 Config::Bind(RuntimeOption::EvalForbidDynamicCallsToFunc
,
154 ini
, config
, "ForbidDynamicCallsToFunc",
155 RuntimeOption::EvalForbidDynamicCallsToFunc
);
156 Config::Bind(RuntimeOption::EvalForbidDynamicCallsToClsMeth
,
157 ini
, config
, "ForbidDynamicCallsToClsMeth",
158 RuntimeOption::EvalForbidDynamicCallsToClsMeth
);
159 Config::Bind(RuntimeOption::EvalForbidDynamicCallsToInstMeth
,
160 ini
, config
, "ForbidDynamicCallsToInstMeth",
161 RuntimeOption::EvalForbidDynamicCallsToInstMeth
);
162 Config::Bind(RuntimeOption::EvalForbidDynamicConstructs
,
163 ini
, config
, "ForbidDynamicConstructs",
164 RuntimeOption::EvalForbidDynamicConstructs
);
165 Config::Bind(RuntimeOption::EvalForbidDynamicCallsWithAttr
,
166 ini
, config
, "ForbidDynamicCallsWithAttr",
167 RuntimeOption::EvalForbidDynamicCallsWithAttr
);
168 Config::Bind(RuntimeOption::EvalLogKnownMethodsAsDynamicCalls
,
169 ini
, config
, "LogKnownMethodsAsDynamicCalls",
170 RuntimeOption::EvalLogKnownMethodsAsDynamicCalls
);
171 Config::Bind(RuntimeOption::EvalNoticeOnBuiltinDynamicCalls
,
172 ini
, config
, "NoticeOnBuiltinDynamicCalls",
173 RuntimeOption::EvalNoticeOnBuiltinDynamicCalls
);
174 Config::Bind(RuntimeOption::EvalAbortBuildOnVerifyError
,
175 ini
, config
, "AbortBuildOnVerifyError",
176 RuntimeOption::EvalAbortBuildOnVerifyError
);
180 Config::Bind(RuntimeOption::CheckIntOverflow
, ini
, config
,
181 "Hack.Lang.CheckIntOverflow",
182 RuntimeOption::CheckIntOverflow
);
183 Config::Bind(RuntimeOption::StrictArrayFillKeys
, ini
, config
,
184 "Hack.Lang.StrictArrayFillKeys",
185 RuntimeOption::StrictArrayFillKeys
);
188 Config::Bind(RuntimeOption::EnableXHP
, ini
, config
, "EnableXHP",
189 RuntimeOption::EnableXHP
);
191 Config::Bind(ParserThreadCount
, ini
, config
, "ParserThreadCount", 0);
192 if (ParserThreadCount
<= 0) {
193 ParserThreadCount
= Process::GetCPUCount();
196 Config::Bind(RuntimeOption::EvalGenerateDocComments
, ini
, config
,
197 "GenerateDocComments", RuntimeOption::EvalGenerateDocComments
);
198 Config::Bind(RuntimeOption::EvalUseHHBBC
, ini
, config
, "UseHHBBC",
199 RuntimeOption::EvalUseHHBBC
);
201 Config::Bind(ParserGroupSize
, ini
, config
,
202 "ParserGroupSize", kDefaultParserGroupSize
);
203 Config::Bind(ParserDirGroupSizeLimit
, ini
, config
,
204 "ParserDirGroupSizeLimit", kDefaultParserDirGroupSizeLimit
);
205 if (ParserGroupSize
<= 0) ParserGroupSize
= kDefaultParserGroupSize
;
206 if (ParserDirGroupSizeLimit
<= 0) {
207 ParserDirGroupSizeLimit
= kDefaultParserDirGroupSizeLimit
;
210 Config::Bind(ParserAsyncCleanup
, ini
, config
,
211 "ParserAsyncCleanup", ParserAsyncCleanup
);
213 Config::Bind(ExternWorkerUseCase
, ini
, config
, "ExternWorker.UseCase",
214 ExternWorkerUseCase
);
215 // Kill switch for extern-worker. Disable all implementations except
217 Config::Bind(ExternWorkerForceSubprocess
, ini
, config
,
218 "ExternWorker.ForceSubprocess", ExternWorkerForceSubprocess
);
219 Config::Bind(ExternWorkerTimeoutSecs
, ini
, config
, "ExternWorker.TimeoutSecs",
220 ExternWorkerTimeoutSecs
);
221 Config::Bind(ExternWorkerUseExecCache
, ini
, config
,
222 "ExternWorker.UseExecCache", ExternWorkerUseExecCache
);
223 Config::Bind(ExternWorkerCleanup
, ini
, config
, "ExternWorker.Cleanup",
224 ExternWorkerCleanup
);
225 Config::Bind(ExternWorkerWorkingDir
, ini
, config
, "ExternWorker.WorkingDir",
226 ExternWorkerWorkingDir
);
229 ///////////////////////////////////////////////////////////////////////////////
231 bool Option::IsFileExcluded(const std::string
& file
,
232 const hphp_fast_string_set
& patterns
) {
233 String
sfile(file
.c_str(), file
.size(), CopyString
);
234 for (auto const& pattern
: patterns
) {
236 Variant ret
= preg_match(String(pattern
.c_str(), pattern
.size(),
237 CopyString
), sfile
, &matches
);
238 if (ret
.toInt64() > 0) {
245 void Option::FilterFiles(std::vector
<std::string
>& files
,
246 const hphp_fast_string_set
& patterns
) {
247 auto const it
= std::remove_if(
250 [&](const std::string
& file
) { return IsFileExcluded(file
, patterns
); });
251 files
.erase(it
, files
.end());
254 //////////////////////////////////////////////////////////////////////