Merge mozilla-central to autoland. a=merge CLOSED TREE
[gecko.git] / js / public / RealmOptions.h
blobb3ab20915a097dfa7d011e66f2615083ffe3fe97
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 /*
8 * Options specified when creating a realm to determine its behavior, immutable
9 * options determining the behavior of an existing realm, and mutable options on
10 * an existing realm that may be changed when desired.
13 #ifndef js_RealmOptions_h
14 #define js_RealmOptions_h
16 #include "mozilla/Assertions.h" // MOZ_ASSERT
17 #include "mozilla/Maybe.h"
19 #include "jstypes.h" // JS_PUBLIC_API
21 #include "js/Class.h" // JSTraceOp
22 #include "js/RefCounted.h"
24 struct JS_PUBLIC_API JSContext;
25 class JS_PUBLIC_API JSObject;
27 namespace JS {
29 class JS_PUBLIC_API Compartment;
30 class JS_PUBLIC_API Realm;
31 class JS_PUBLIC_API Zone;
33 } // namespace JS
35 namespace JS {
37 /**
38 * Specification for which compartment/zone a newly created realm should use.
40 enum class CompartmentSpecifier {
41 // Create a new realm and compartment in the single runtime wide system
42 // zone. The meaning of this zone is left to the embedder.
43 NewCompartmentInSystemZone,
45 // Create a new realm and compartment in a particular existing zone.
46 NewCompartmentInExistingZone,
48 // Create a new zone/compartment.
49 NewCompartmentAndZone,
51 // Create a new realm in an existing compartment.
52 ExistingCompartment,
55 struct LocaleString : js::RefCounted<LocaleString> {
56 const char* chars_;
58 explicit LocaleString(const char* chars) : chars_(chars) {}
60 auto chars() const { return chars_; }
63 /**
64 * RealmCreationOptions specifies options relevant to creating a new realm, that
65 * are either immutable characteristics of that realm or that are discarded
66 * after the realm has been created.
68 * Access to these options on an existing realm is read-only: if you need
69 * particular selections, you must make them before you create the realm.
71 class JS_PUBLIC_API RealmCreationOptions {
72 public:
73 RealmCreationOptions() : comp_(nullptr) {}
75 JSTraceOp getTrace() const { return traceGlobal_; }
76 RealmCreationOptions& setTrace(JSTraceOp op) {
77 traceGlobal_ = op;
78 return *this;
81 Zone* zone() const {
82 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::NewCompartmentInExistingZone);
83 return zone_;
85 Compartment* compartment() const {
86 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::ExistingCompartment);
87 return comp_;
89 CompartmentSpecifier compartmentSpecifier() const { return compSpec_; }
91 // Set the compartment/zone to use for the realm. See CompartmentSpecifier
92 // above.
93 RealmCreationOptions& setNewCompartmentInSystemZone();
94 RealmCreationOptions& setNewCompartmentInExistingZone(JSObject* obj);
95 RealmCreationOptions& setNewCompartmentAndZone();
96 RealmCreationOptions& setExistingCompartment(JSObject* obj);
97 RealmCreationOptions& setExistingCompartment(Compartment* compartment);
99 // Certain compartments are implementation details of the embedding, and
100 // references to them should never leak out to script. This flag causes this
101 // realm to skip firing onNewGlobalObject and makes addDebuggee a no-op for
102 // this global.
104 // Debugger visibility is per-compartment, not per-realm (it's only practical
105 // to enforce visibility on compartment boundaries), so if a realm is being
106 // created in an extant compartment, its requested visibility must match that
107 // of the compartment.
108 bool invisibleToDebugger() const { return invisibleToDebugger_; }
109 RealmCreationOptions& setInvisibleToDebugger(bool flag) {
110 invisibleToDebugger_ = flag;
111 return *this;
114 // Determines whether this realm should preserve JIT code on non-shrinking
115 // GCs.
116 bool preserveJitCode() const { return preserveJitCode_; }
117 RealmCreationOptions& setPreserveJitCode(bool flag) {
118 preserveJitCode_ = flag;
119 return *this;
122 // Determines whether 1) the global Atomic property is defined and atomic
123 // operations are supported, and 2) whether shared-memory operations are
124 // supported.
125 bool getSharedMemoryAndAtomicsEnabled() const;
126 RealmCreationOptions& setSharedMemoryAndAtomicsEnabled(bool flag);
128 // Determines (if getSharedMemoryAndAtomicsEnabled() is true) whether the
129 // global SharedArrayBuffer property is defined. If the property is not
130 // defined, shared array buffer functionality can only be invoked if the
131 // host/embedding specifically acts to expose it.
133 // This option defaults to true: embeddings unable to tolerate a global
134 // SharedAraryBuffer property must opt out of it.
135 bool defineSharedArrayBufferConstructor() const {
136 return defineSharedArrayBufferConstructor_;
138 RealmCreationOptions& setDefineSharedArrayBufferConstructor(bool flag) {
139 defineSharedArrayBufferConstructor_ = flag;
140 return *this;
143 // Structured clone operations support the cloning of shared memory objects
144 // (SharedArrayBuffer or or a shared WASM Memory object) *optionally* -- at
145 // the discretion of the embedder code that performs the cloning. When a
146 // structured clone operation encounters a shared memory object and cloning
147 // shared memory objects has not been enabled, the clone fails and an
148 // error is thrown.
150 // In the web embedding context, shared memory object cloning is disabled
151 // either because
153 // 1) *no* way of supporting it is available (because the
154 // Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP
155 // headers are not respected to force the page into its own process), or
156 // 2) the aforementioned HTTP headers don't specify that the page should be
157 // opened in its own process.
159 // These two scenarios demand different error messages, and this option can be
160 // used to specify which scenario is in play.
162 // In the former case, if COOP/COEP support is not enabled, set this option to
163 // false. (This is the default.)
165 // In the latter case, if COOP/COEP weren't used to force this page into its
166 // own process, set this option to true.
168 // (Embeddings that are not the web and do not wish to support structured
169 // cloning of shared memory objects will get a "bad" web-centric error message
170 // no matter what. At present, SpiderMonkey does not offer a way for such
171 // embeddings to use an embedding-specific error message.)
172 bool getCoopAndCoepEnabled() const;
173 RealmCreationOptions& setCoopAndCoepEnabled(bool flag);
175 bool getToSourceEnabled() const { return toSource_; }
176 RealmCreationOptions& setToSourceEnabled(bool flag) {
177 toSource_ = flag;
178 return *this;
181 // This flag doesn't affect JS engine behavior. It is used by Gecko to
182 // mark whether content windows and workers are "Secure Context"s. See
183 // https://w3c.github.io/webappsec-secure-contexts/
184 // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
185 bool secureContext() const { return secureContext_; }
186 RealmCreationOptions& setSecureContext(bool flag) {
187 secureContext_ = flag;
188 return *this;
191 // Non-standard option to freeze certain builtin constructors and seal their
192 // prototypes. Also defines these constructors on the global as non-writable
193 // and non-configurable.
194 bool freezeBuiltins() const { return freezeBuiltins_; }
195 RealmCreationOptions& setFreezeBuiltins(bool flag) {
196 freezeBuiltins_ = flag;
197 return *this;
200 // Force all date/time methods in JavaScript to use the UTC timezone for
201 // fingerprinting protection.
202 bool forceUTC() const { return forceUTC_; }
203 RealmCreationOptions& setForceUTC(bool flag) {
204 forceUTC_ = flag;
205 return *this;
208 RefPtr<LocaleString> locale() const { return locale_; }
209 RealmCreationOptions& setLocaleCopyZ(const char* locale);
211 // Always use the fdlibm implementation of math functions instead of the
212 // platform native libc implementations. Useful for fingerprinting protection
213 // and cross-platform consistency.
214 bool alwaysUseFdlibm() const { return alwaysUseFdlibm_; }
215 RealmCreationOptions& setAlwaysUseFdlibm(bool flag) {
216 alwaysUseFdlibm_ = flag;
217 return *this;
220 uint64_t profilerRealmID() const { return profilerRealmID_; }
221 RealmCreationOptions& setProfilerRealmID(uint64_t id) {
222 profilerRealmID_ = id;
223 return *this;
226 private:
227 JSTraceOp traceGlobal_ = nullptr;
228 CompartmentSpecifier compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
229 union {
230 Compartment* comp_;
231 Zone* zone_;
233 uint64_t profilerRealmID_ = 0;
234 RefPtr<LocaleString> locale_;
235 bool invisibleToDebugger_ = false;
236 bool preserveJitCode_ = false;
237 bool sharedMemoryAndAtomics_ = false;
238 bool defineSharedArrayBufferConstructor_ = true;
239 bool coopAndCoep_ = false;
240 bool toSource_ = false;
242 bool secureContext_ = false;
243 bool freezeBuiltins_ = false;
244 bool forceUTC_ = false;
245 bool alwaysUseFdlibm_ = false;
248 // This is a wrapper for mozilla::RTPCallerType, that can't easily
249 // be exposed to the JS engine for layering reasons.
250 struct RTPCallerTypeToken {
251 uint8_t value;
255 * RealmBehaviors specifies behaviors of a realm that can be changed after the
256 * realm's been created.
258 class JS_PUBLIC_API RealmBehaviors {
259 public:
260 RealmBehaviors() = default;
262 // When a JS::ReduceMicrosecondTimePrecisionCallback callback is defined via
263 // JS::SetReduceMicrosecondTimePrecisionCallback, a JS::RTPCallerTypeToken (a
264 // wrapper for mozilla::RTPCallerType) needs to be set for every Realm.
265 mozilla::Maybe<RTPCallerTypeToken> reduceTimerPrecisionCallerType() const {
266 return rtpCallerType;
268 RealmBehaviors& setReduceTimerPrecisionCallerType(RTPCallerTypeToken type) {
269 rtpCallerType = mozilla::Some(type);
270 return *this;
273 // For certain globals, we know enough about the code that will run in them
274 // that we can discard script source entirely.
275 bool discardSource() const { return discardSource_; }
276 RealmBehaviors& setDiscardSource(bool flag) {
277 discardSource_ = flag;
278 return *this;
281 bool clampAndJitterTime() const { return clampAndJitterTime_; }
282 RealmBehaviors& setClampAndJitterTime(bool flag) {
283 clampAndJitterTime_ = flag;
284 return *this;
287 // A Realm can stop being "live" in all the ways that matter before its global
288 // is actually GCed. Consumers that tear down parts of a Realm or its global
289 // before that point should set isNonLive accordingly.
290 bool isNonLive() const { return isNonLive_; }
291 RealmBehaviors& setNonLive() {
292 isNonLive_ = true;
293 return *this;
296 private:
297 mozilla::Maybe<RTPCallerTypeToken> rtpCallerType;
298 bool discardSource_ = false;
299 bool clampAndJitterTime_ = true;
300 bool isNonLive_ = false;
304 * RealmOptions specifies realm characteristics: both those that can't be
305 * changed on a realm once it's been created (RealmCreationOptions), and those
306 * that can be changed on an existing realm (RealmBehaviors).
308 class JS_PUBLIC_API RealmOptions {
309 public:
310 explicit RealmOptions() : creationOptions_(), behaviors_() {}
312 RealmOptions(const RealmCreationOptions& realmCreation,
313 const RealmBehaviors& realmBehaviors)
314 : creationOptions_(realmCreation), behaviors_(realmBehaviors) {}
316 // RealmCreationOptions specify fundamental realm characteristics that must
317 // be specified when the realm is created, that can't be changed after the
318 // realm is created.
319 RealmCreationOptions& creationOptions() { return creationOptions_; }
320 const RealmCreationOptions& creationOptions() const {
321 return creationOptions_;
324 // RealmBehaviors specify realm characteristics that can be changed after
325 // the realm is created.
326 RealmBehaviors& behaviors() { return behaviors_; }
327 const RealmBehaviors& behaviors() const { return behaviors_; }
329 private:
330 RealmCreationOptions creationOptions_;
331 RealmBehaviors behaviors_;
334 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
335 Realm* realm);
337 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
338 JSContext* cx);
340 extern JS_PUBLIC_API const RealmBehaviors& RealmBehaviorsRef(Realm* realm);
342 extern JS_PUBLIC_API const RealmBehaviors& RealmBehaviorsRef(JSContext* cx);
344 extern JS_PUBLIC_API void SetRealmNonLive(Realm* realm);
346 // This behaves like RealmBehaviors::setReduceTimerPrecisionCallerType, but
347 // can be used even after the Realm has already been created.
348 extern JS_PUBLIC_API void SetRealmReduceTimerPrecisionCallerType(
349 Realm* realm, RTPCallerTypeToken type);
351 } // namespace JS
353 #endif // js_RealmOptions_h