1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 # This script generates js/public/PrefsGenerated.h from StaticPrefList.yaml
10 from mozbuild
.preprocessor
import Preprocessor
12 HEADER_TEMPLATE
= """\
13 /* This Source Code Form is subject to the terms of the Mozilla Public
14 * License, v. 2.0. If a copy of the MPL was not distributed with this
15 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
17 #ifndef js_PrefsGenerated_h
18 #define js_PrefsGenerated_h
20 /* This file is generated by js/src/GeneratePrefs.py. Do not edit! */
22 #include "mozilla/Atomics.h"
28 #endif // js_PrefsGenerated_h
32 def load_yaml(yaml_path
):
33 # First invoke the preprocessor to handle #ifdefs in the YAML file.
35 pp
.context
.update(buildconfig
.defines
["ALLDEFINES"])
37 # To make #ifdef DEBUG work, use a similar hack as in emit_code in
38 # generate_static_pref_list.py.
39 if buildconfig
.substs
.get("MOZ_DEBUG"):
40 pp
.context
["DEBUG"] = "1"
42 pp
.out
= six
.StringIO()
43 pp
.do_filter("substitution")
44 pp
.do_include(yaml_path
)
45 contents
= pp
.out
.getvalue()
46 return yaml
.safe_load(contents
)
49 # Returns the C++ type to use for the pref type from the YAML file. Always use
50 # the non-atomic type for return values and arguments. The field type is
51 # determined elsewhere.
52 def get_cpp_type(type):
53 if type in ("bool", "RelaxedAtomicBool"):
55 if type in ("uint32_t", "RelaxedAtomicUint32"):
57 if type in ("int32_t", "RelaxedAtomicInt32"):
59 raise Exception("Unexpected type: {}".format(type))
62 # Returns a C++ expression for the default pref value. Booleans in the YAML file
63 # are converted to Pythonic True or False, so those need special handling.
64 def get_cpp_init_value(val
):
72 def generate_prefs_header(c_out
, yaml_path
):
73 prefs
= load_yaml(yaml_path
)
75 js_options_prefix
= "javascript.options."
78 set_spidermonkey_pref
= pref
.get("set_spidermonkey_pref", False)
79 if set_spidermonkey_pref
not in (False, "startup", "always"):
80 raise Exception("Invalid value for set_spidermonkey_pref")
82 # Ignore prefs that don't have the |set_spidermonkey_pref| attribute.
83 if set_spidermonkey_pref
is False:
86 # Only support prefs with javascript.options prefix.
87 if not pref
["name"].startswith(js_options_prefix
):
88 raise Exception("set_spidermonkey_pref only works for JS prefs")
92 # Remove all non-JS prefs and sort prefs by name.
93 prefs
= list(filter(is_js_pref
, prefs
))
94 prefs
.sort(key
=lambda pref
: pref
["name"])
97 class_fields_inits
= []
100 browser_set_statements
= []
101 browser_set_non_startup_statements
= []
105 name
= name
[len(js_options_prefix
) :]
107 is_startup_pref
= pref
["set_spidermonkey_pref"] == "startup"
109 cpp_name
= name
.replace(".", "_").replace("-", "_")
110 type = get_cpp_type(pref
["type"])
111 init_value
= get_cpp_init_value(pref
["value"])
113 setter_name
= ("setAtStartup_" if is_startup_pref
else "set_") + cpp_name
115 # Use a relaxed atomic for non-startup prefs because those might be changed
118 if not is_startup_pref
:
119 field_type
= "mozilla::Atomic<{}, mozilla::Relaxed>".format(field_type
)
120 class_fields
.append("static {} {}_;".format(field_type
, cpp_name
))
121 class_fields_inits
.append(
122 "{} JS::Prefs::{}_{{{}}};".format(field_type
, cpp_name
, init_value
)
125 is_startup_pref_bool
= "true" if is_startup_pref
else "false"
127 # Generate a MACRO invocation like this:
128 # MACRO("arraybuffer_transfer", arraybuffer_transfer, bool, setAtStartup_arraybuffer_transfer, true)
129 macro_entries
.append(
130 'MACRO("{}", {}, {}, {}, {})'.format(
131 name
, cpp_name
, type, setter_name
, is_startup_pref_bool
135 # Generate a C++ statement to set the JS pref based on Gecko's StaticPrefs:
136 # JS::Prefs::setAtStartup_foo(StaticPrefs::javascript_options_foo());
137 browser_pref_cpp_name
= pref
["name"].replace(".", "_").replace("-", "_")
138 if pref
.get("do_not_use_directly", False):
139 browser_pref_cpp_name
+= "_DoNotUseDirectly"
141 statement
= "JS::Prefs::{}(mozilla::StaticPrefs::{}());".format(
142 setter_name
, browser_pref_cpp_name
144 browser_set_statements
.append(statement
)
146 # For non-startup prefs, also generate code to update the pref after startup.
147 if not is_startup_pref
:
148 browser_set_non_startup_statements
.append(statement
)
152 contents
+= "#define JS_PREF_CLASS_FIELDS \\\n"
153 contents
+= "".join(map(lambda s
: " {}\\\n".format(s
), class_fields
))
156 contents
+= "#define JS_PREF_CLASS_FIELDS_INIT \\\n"
157 contents
+= "".join(map(lambda s
: " {}\\\n".format(s
), class_fields_inits
))
160 contents
+= "#define FOR_EACH_JS_PREF(MACRO) \\\n"
161 contents
+= "".join(map(lambda s
: " {}\\\n".format(s
), macro_entries
))
164 contents
+= "#define SET_JS_PREFS_FROM_BROWSER_PREFS \\\n"
165 contents
+= "".join(map(lambda s
: " {}\\\n".format(s
), browser_set_statements
))
168 contents
+= "#define SET_NON_STARTUP_JS_PREFS_FROM_BROWSER_PREFS \\\n"
170 map(lambda s
: " {}\\\n".format(s
), browser_set_non_startup_statements
)
177 "contents": contents
,