2 * Copyright (c) 2017, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
15 (* Compiler configuration options, as set by -v key=value on the command line *)
17 option_ints_overflow_to_ints
: bool option;
18 option_enable_hiphop_syntax
: bool;
19 option_php7_scalar_types
: bool;
20 option_enable_xhp
: bool;
21 option_constant_folding
: bool;
22 option_optimize_null_check
: bool;
23 option_optimize_cuf
: bool;
24 option_max_array_elem_size_on_the_stack
: int;
25 option_aliased_namespaces
: (string * string) list
option;
26 option_source_mapping
: bool;
27 option_relabel
: bool;
28 option_php7_uvs
: bool;
29 option_php7_ltr_assign
: bool;
30 option_create_inout_wrapper_functions
: bool;
31 option_reffiness_invariance
: bool;
32 option_hack_arr_compat_notices
: bool;
33 option_dynamic_invoke_functions
: SSet.t
;
34 option_repo_authoritative
: bool;
35 option_jit_enable_rename_function
: bool;
36 option_can_inline_gen_functions
: bool;
37 option_use_msrv_for_inout
: bool;
41 option_ints_overflow_to_ints
= None
;
42 option_enable_hiphop_syntax
= false;
43 option_php7_scalar_types
= false;
44 option_enable_xhp
= false;
45 option_constant_folding
= false;
46 option_optimize_null_check
= false;
47 option_optimize_cuf
= true;
48 option_max_array_elem_size_on_the_stack
= 64;
49 option_aliased_namespaces
= None
;
50 option_source_mapping
= false;
51 option_php7_uvs
= false;
52 option_php7_ltr_assign
= false;
53 (* If true, then renumber labels after generating code for a method
54 * body. Semantic diff doesn't care about labels, but for visual diff against
55 * HHVM it's helpful to renumber in order that the labels match more closely *)
56 option_relabel
= true;
57 option_create_inout_wrapper_functions
= true;
58 option_reffiness_invariance
= false;
59 option_hack_arr_compat_notices
= false;
60 option_dynamic_invoke_functions
= SSet.empty
;
61 option_repo_authoritative
= false;
62 option_jit_enable_rename_function
= false;
63 option_can_inline_gen_functions
= true;
64 option_use_msrv_for_inout
= false;
67 let enable_hiphop_syntax o
= o
.option_enable_hiphop_syntax
68 let php7_scalar_types o
= o
.option_php7_scalar_types
69 let enable_xhp o
= o
.option_enable_xhp
70 let constant_folding o
= o
.option_constant_folding
71 let optimize_null_check o
= o
.option_optimize_null_check
72 let optimize_cuf o
= o
.option_optimize_cuf
73 let max_array_elem_size_on_the_stack o
=
74 o
.option_max_array_elem_size_on_the_stack
75 let aliased_namespaces o
= o
.option_aliased_namespaces
76 let source_mapping o
= o
.option_source_mapping
77 let relabel o
= o
.option_relabel
78 let enable_uniform_variable_syntax o
= o
.option_php7_uvs
79 let php7_ltr_assign o
= o
.option_php7_ltr_assign
80 let create_inout_wrapper_functions o
= o
.option_create_inout_wrapper_functions
81 let reffiness_invariance o
= o
.option_reffiness_invariance
82 let hack_arr_compat_notices o
= o
.option_hack_arr_compat_notices
83 let dynamic_invoke_functions o
= o
.option_dynamic_invoke_functions
84 let repo_authoritative o
= o
.option_repo_authoritative
85 let jit_enable_rename_function o
= o
.option_jit_enable_rename_function
86 let can_inline_gen_functions o
= o
.option_can_inline_gen_functions
87 let use_msrv_for_inout o
= o
.option_use_msrv_for_inout
91 String.concat
", " (SSet.elements
(dynamic_invoke_functions o
)) in
93 [ Printf.sprintf
"enable_hiphop_syntax: %B" @@ enable_hiphop_syntax o
94 ; Printf.sprintf
"php7_scalar_types: %B" @@ php7_scalar_types o
95 ; Printf.sprintf
"enable_xhp: %B" @@ enable_xhp o
96 ; Printf.sprintf
"constant_folding: %B" @@ constant_folding o
97 ; Printf.sprintf
"optimize_null_check: %B" @@ optimize_null_check o
98 ; Printf.sprintf
"optimize_cuf: %B" @@ optimize_cuf o
99 ; Printf.sprintf
"max_array_elem_size_on_the_stack: %d"
100 @@ max_array_elem_size_on_the_stack o
101 ; Printf.sprintf
"source_mapping: %B" @@ source_mapping o
102 ; Printf.sprintf
"relabel: %B" @@ relabel o
103 ; Printf.sprintf
"enable_uniform_variable_syntax: %B"
104 @@ enable_uniform_variable_syntax o
105 ; Printf.sprintf
"php7_ltr_assign: %B" @@ php7_ltr_assign o
106 ; Printf.sprintf
"create_inout_wrapper_functions: %B"
107 @@ create_inout_wrapper_functions o
108 ; Printf.sprintf
"reffiness_invariance: %B" @@ reffiness_invariance o
109 ; Printf.sprintf
"hack_arr_compat_notices: %B" @@ hack_arr_compat_notices o
110 ; Printf.sprintf
"dynamic_invoke_functions: [%s]" dynamic_invokes
111 ; Printf.sprintf
"repo_authoritative: %B" @@ repo_authoritative o
112 ; Printf.sprintf
"jit_enable_rename_function: %B"
113 @@ jit_enable_rename_function o
114 ; Printf.sprintf
"can_inline_gen_functions: %B" @@ can_inline_gen_functions o
115 ; Printf.sprintf
"use_msrv_for_inout: %B" @@ use_msrv_for_inout o
118 (* The Hack.Lang.IntsOverflowToInts setting overrides the
119 * Eval.EnableHipHopSyntax setting *)
120 let ints_overflow_to_ints options
=
121 match options
.option_ints_overflow_to_ints
with
123 | None
-> options
.option_enable_hiphop_syntax
126 match String.lowercase_ascii s
with
127 | "0" | "false" -> false
128 | "1" | "true" -> true
129 | _
-> raise
(Arg.Bad
(s ^
" can't be cast to bool"))
131 let set_option options name
value =
132 match String.lowercase_ascii name
with
133 | "eval.enablehiphopsyntax" ->
134 { options
with option_enable_hiphop_syntax
= as_bool value }
135 | "hack.lang.intsoverflowtoints" ->
136 { options
with option_ints_overflow_to_ints
= Some
(as_bool value) }
137 | "hack.compiler.constantfolding" ->
138 { options
with option_constant_folding
= as_bool value }
139 | "hack.compiler.optimizenullcheck" ->
140 { options
with option_optimize_null_check
= as_bool value }
141 | "hack.compiler.optimizecuf" ->
142 { options
with option_optimize_cuf
= as_bool value }
143 | "hack.compiler.sourcemapping" ->
144 { options
with option_source_mapping
= as_bool value }
145 | "hhvm.php7.scalar_types" ->
146 { options
with option_php7_scalar_types
= as_bool value }
147 | "hhvm.php7.ltr_assign" ->
148 { options
with option_php7_ltr_assign
= as_bool value }
149 | "hhvm.enable_xhp" ->
150 { options
with option_enable_xhp
= as_bool value }
152 { options
with option_php7_uvs
= as_bool value }
153 | "hack.compiler.relabel" ->
154 { options
with option_relabel
= as_bool value }
155 | "eval.createinoutwrapperfunctions" ->
156 { options
with option_create_inout_wrapper_functions
= as_bool value }
157 | "eval.reffinessinvariance" ->
158 { options
with option_reffiness_invariance
= as_bool value }
159 | "eval.hackarrcompatnotices" ->
160 { options
with option_hack_arr_compat_notices
= as_bool value }
161 | "hhvm.repo_authoritative" ->
162 { options
with option_repo_authoritative
= as_bool value }
163 | "eval.jitenablerenamefunction" ->
164 { options
with option_jit_enable_rename_function
= as_bool value }
165 | "eval.disablehphpcopts" ->
166 let v = not
(as_bool value) in
167 { options
with option_optimize_cuf
= v;
168 option_constant_folding
= v;
169 option_can_inline_gen_functions
= v}
170 | "hhvm.use_msrv_for_in_out" ->
171 { options
with option_use_msrv_for_inout
= as_bool value }
174 let get_value_from_config_ config key
=
175 let f k1
(k2
, _
) = k1
= k2
in
176 match List.find config ~
f:(f key
) with
179 begin match List.find
(J.get_object_exn json
) ~
f:(f "global_value") with
181 | Some
(_
, json
) -> Some json
184 let get_value_from_config_int config key
=
185 let json_opt = get_value_from_config_ config key
in
186 Option.map
json_opt ~
f:(fun json
->
187 match J.get_string_exn json
with
189 | x
-> int_of_string x
)
191 let get_value_from_config_kv_list config key
=
192 let json_opt = get_value_from_config_ config key
in
193 Option.map
json_opt ~
f:(fun json
->
195 | J.JSON_Array
[] -> []
197 let keys_with_json = J.get_object_exn json
in
198 List.map ~
f:(fun (k
, v) -> k
, J.get_string_exn
v) keys_with_json)
200 let get_value_from_config_string_array config key
=
201 let json_opt = get_value_from_config_ config key
in
204 | Some
(J.JSON_Array fs
) -> Some
(List.map fs
J.get_string_exn
)
205 | _
-> raise
(Arg.Bad
("Expected list of strings at " ^ key
))
207 let set_value name get set config opts
=
209 let value = get config name
in
210 Option.value_map
value ~
default:opts ~
f:(set opts
)
212 | Arg.Bad why
-> raise
(Arg.Bad
("Option " ^ name ^
": " ^ why
))
213 | Assert_failure _
-> raise
(Arg.Bad
("Option " ^ name ^
": error parsing JSON"))
215 let value_setters = [
216 (set_value "hhvm.aliased_namespaces" get_value_from_config_kv_list @@
217 fun opts
v -> { opts
with option_aliased_namespaces
= Some
v });
218 (set_value "hhvm.force_hh" get_value_from_config_int @@
219 fun opts
v -> { opts
with option_enable_hiphop_syntax
= (v = 1) });
220 (set_value "hhvm.enable_xhp" get_value_from_config_int @@
221 fun opts
v -> { opts
with option_enable_xhp
= (v = 1) });
222 (set_value "hhvm.php7.scalar_types" get_value_from_config_int @@
223 fun opts
v -> { opts
with option_php7_scalar_types
= (v = 1) });
224 (set_value "hhvm.hack.lang.ints_overflow_to_ints" get_value_from_config_int @@
225 fun opts
v -> { opts
with option_ints_overflow_to_ints
= Some
(v = 1) });
226 (set_value "hack.compiler.constant_folding" get_value_from_config_int @@
227 fun opts
v -> { opts
with option_constant_folding
= (v = 1) });
228 (set_value "hack.compiler.optimize_null_checks" get_value_from_config_int @@
229 fun opts
v -> { opts
with option_optimize_null_check
= (v = 1) });
230 (set_value "hhvm.disable_hphpc_opts" get_value_from_config_int @@
231 fun opts
v -> { opts
with option_optimize_cuf
= (v = 0);
232 option_constant_folding
= (v = 0);
233 option_can_inline_gen_functions
= (v = 0) });
234 (set_value "hack.compiler.optimize_cuf" get_value_from_config_int @@
235 fun opts
v -> { opts
with option_optimize_cuf
= (v = 1) });
236 (set_value "hhvm.php7.uvs" get_value_from_config_int @@
237 fun opts
v -> { opts
with option_php7_uvs
= (v = 1) });
238 (set_value "hhvm.php7.ltr_assign" get_value_from_config_int @@
239 fun opts
v -> { opts
with option_php7_ltr_assign
= (v = 1) });
240 (set_value "hhvm.create_in_out_wrapper_functions" get_value_from_config_int @@
241 fun opts
v -> { opts
with option_create_inout_wrapper_functions
= (v = 1)});
242 (set_value "hhvm.reffiness_invariance" get_value_from_config_int @@
243 fun opts
v -> { opts
with option_reffiness_invariance
= (v = 1) });
244 (set_value "hhvm.hack_arr_compat_notices" get_value_from_config_int @@
245 fun opts
v -> { opts
with option_hack_arr_compat_notices
= (v = 1) });
246 (set_value "hhvm.dynamic_invoke_functions" get_value_from_config_string_array @@
247 fun opts
v -> {opts
with option_dynamic_invoke_functions
=
248 SSet.of_list
(List.map
v String.lowercase_ascii
)});
249 (set_value "hhvm.repo.authoritative" get_value_from_config_int @@
250 fun opts
v -> { opts
with option_repo_authoritative
= (v = 1) });
251 (set_value "hhvm.jit_enable_rename_function" get_value_from_config_int @@
252 fun opts
v -> { opts
with option_jit_enable_rename_function
= (v = 1) });
253 (set_value "hhvm.use_msrv_for_in_out" get_value_from_config_int @@
254 fun opts
v -> { opts
with option_use_msrv_for_inout
= (v = 1) });
257 let extract_config_options_from_json ~init config_json
=
258 match config_json
with None
-> init
| Some config_json
->
259 let config = J.get_object_exn config_json
in
260 List.fold_left
value_setters ~init ~
f:(fun opts setter
-> setter
config opts
)
262 (* Construct an instance of Hhbc_options.t from the options passed in as well as
263 * as specified in `-v str` on the command line.
265 let get_options_from_config config_json config_list
=
266 let init = extract_config_options_from_json ~
init:default config_json
in
267 List.fold_left config_list ~
init ~
f:begin
269 match Str.split_delim
(Str.regexp
"=") str
with
270 | [name
; value] -> set_option options name
value
274 let compiler_options = ref default
275 let set_compiler_options o
= compiler_options := o