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/. */
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
18 #include "jstypes.h" // JS_PUBLIC_API
20 #include "js/Class.h" // JSTraceOp
21 #include "js/RefCounted.h"
23 struct JS_PUBLIC_API JSContext
;
24 class JS_PUBLIC_API JSObject
;
28 class JS_PUBLIC_API Compartment
;
29 class JS_PUBLIC_API Realm
;
30 class JS_PUBLIC_API Zone
;
37 * Specification for which compartment/zone a newly created realm should use.
39 enum class CompartmentSpecifier
{
40 // Create a new realm and compartment in the single runtime wide system
41 // zone. The meaning of this zone is left to the embedder.
42 NewCompartmentInSystemZone
,
44 // Create a new realm and compartment in a particular existing zone.
45 NewCompartmentInExistingZone
,
47 // Create a new zone/compartment.
48 NewCompartmentAndZone
,
50 // Create a new realm in an existing compartment.
55 * Specification for whether weak refs should be enabled and if so whether the
56 * FinalizationRegistry.cleanupSome method should be present.
58 enum class WeakRefSpecifier
{
60 EnabledWithCleanupSome
,
61 EnabledWithoutCleanupSome
64 struct LocaleString
: js::RefCounted
<LocaleString
> {
67 explicit LocaleString(const char* chars
) : chars_(chars
) {}
69 auto chars() const { return chars_
; }
73 * RealmCreationOptions specifies options relevant to creating a new realm, that
74 * are either immutable characteristics of that realm or that are discarded
75 * after the realm has been created.
77 * Access to these options on an existing realm is read-only: if you need
78 * particular selections, you must make them before you create the realm.
80 class JS_PUBLIC_API RealmCreationOptions
{
82 RealmCreationOptions() : comp_(nullptr) {}
84 JSTraceOp
getTrace() const { return traceGlobal_
; }
85 RealmCreationOptions
& setTrace(JSTraceOp op
) {
91 MOZ_ASSERT(compSpec_
== CompartmentSpecifier::NewCompartmentInExistingZone
);
94 Compartment
* compartment() const {
95 MOZ_ASSERT(compSpec_
== CompartmentSpecifier::ExistingCompartment
);
98 CompartmentSpecifier
compartmentSpecifier() const { return compSpec_
; }
100 // Set the compartment/zone to use for the realm. See CompartmentSpecifier
102 RealmCreationOptions
& setNewCompartmentInSystemZone();
103 RealmCreationOptions
& setNewCompartmentInExistingZone(JSObject
* obj
);
104 RealmCreationOptions
& setNewCompartmentAndZone();
105 RealmCreationOptions
& setExistingCompartment(JSObject
* obj
);
106 RealmCreationOptions
& setExistingCompartment(Compartment
* compartment
);
108 // Certain compartments are implementation details of the embedding, and
109 // references to them should never leak out to script. This flag causes this
110 // realm to skip firing onNewGlobalObject and makes addDebuggee a no-op for
113 // Debugger visibility is per-compartment, not per-realm (it's only practical
114 // to enforce visibility on compartment boundaries), so if a realm is being
115 // created in an extant compartment, its requested visibility must match that
116 // of the compartment.
117 bool invisibleToDebugger() const { return invisibleToDebugger_
; }
118 RealmCreationOptions
& setInvisibleToDebugger(bool flag
) {
119 invisibleToDebugger_
= flag
;
123 // Determines whether this realm should preserve JIT code on non-shrinking
125 bool preserveJitCode() const { return preserveJitCode_
; }
126 RealmCreationOptions
& setPreserveJitCode(bool flag
) {
127 preserveJitCode_
= flag
;
131 // Determines whether 1) the global Atomic property is defined and atomic
132 // operations are supported, and 2) whether shared-memory operations are
134 bool getSharedMemoryAndAtomicsEnabled() const;
135 RealmCreationOptions
& setSharedMemoryAndAtomicsEnabled(bool flag
);
137 // Determines (if getSharedMemoryAndAtomicsEnabled() is true) whether the
138 // global SharedArrayBuffer property is defined. If the property is not
139 // defined, shared array buffer functionality can only be invoked if the
140 // host/embedding specifically acts to expose it.
142 // This option defaults to true: embeddings unable to tolerate a global
143 // SharedAraryBuffer property must opt out of it.
144 bool defineSharedArrayBufferConstructor() const {
145 return defineSharedArrayBufferConstructor_
;
147 RealmCreationOptions
& setDefineSharedArrayBufferConstructor(bool flag
) {
148 defineSharedArrayBufferConstructor_
= flag
;
152 // Structured clone operations support the cloning of shared memory objects
153 // (SharedArrayBuffer or or a shared WASM Memory object) *optionally* -- at
154 // the discretion of the embedder code that performs the cloning. When a
155 // structured clone operation encounters a shared memory object and cloning
156 // shared memory objects has not been enabled, the clone fails and an
159 // In the web embedding context, shared memory object cloning is disabled
162 // 1) *no* way of supporting it is available (because the
163 // Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP
164 // headers are not respected to force the page into its own process), or
165 // 2) the aforementioned HTTP headers don't specify that the page should be
166 // opened in its own process.
168 // These two scenarios demand different error messages, and this option can be
169 // used to specify which scenario is in play.
171 // In the former case, if COOP/COEP support is not enabled, set this option to
172 // false. (This is the default.)
174 // In the latter case, if COOP/COEP weren't used to force this page into its
175 // own process, set this option to true.
177 // (Embeddings that are not the web and do not wish to support structured
178 // cloning of shared memory objects will get a "bad" web-centric error message
179 // no matter what. At present, SpiderMonkey does not offer a way for such
180 // embeddings to use an embedding-specific error message.)
181 bool getCoopAndCoepEnabled() const;
182 RealmCreationOptions
& setCoopAndCoepEnabled(bool flag
);
184 WeakRefSpecifier
getWeakRefsEnabled() const { return weakRefs_
; }
185 RealmCreationOptions
& setWeakRefsEnabled(WeakRefSpecifier spec
) {
190 bool getToSourceEnabled() const { return toSource_
; }
191 RealmCreationOptions
& setToSourceEnabled(bool flag
) {
196 bool getPropertyErrorMessageFixEnabled() const {
197 return propertyErrorMessageFix_
;
199 RealmCreationOptions
& setPropertyErrorMessageFixEnabled(bool flag
) {
200 propertyErrorMessageFix_
= flag
;
204 bool getIteratorHelpersEnabled() const { return iteratorHelpers_
; }
205 RealmCreationOptions
& setIteratorHelpersEnabled(bool flag
) {
206 iteratorHelpers_
= flag
;
210 bool getShadowRealmsEnabled() const { return shadowRealms_
; }
211 RealmCreationOptions
& setShadowRealmsEnabled(bool flag
) {
212 shadowRealms_
= flag
;
216 bool getWellFormedUnicodeStringsEnabled() const {
217 return wellFormedUnicodeStrings_
;
219 RealmCreationOptions
& setWellFormedUnicodeStringsEnabled(bool flag
) {
220 wellFormedUnicodeStrings_
= flag
;
224 bool getArrayGroupingEnabled() const { return arrayGrouping_
; }
225 RealmCreationOptions
& setArrayGroupingEnabled(bool flag
) {
226 arrayGrouping_
= flag
;
231 bool getNewSetMethodsEnabled() const { return newSetMethods_
; }
232 RealmCreationOptions
& setNewSetMethodsEnabled(bool flag
) {
233 newSetMethods_
= flag
;
237 bool getArrayBufferTransferEnabled() const { return arrayBufferTransfer_
; }
238 RealmCreationOptions
& setArrayBufferTransferEnabled(bool flag
) {
239 arrayBufferTransfer_
= flag
;
244 // This flag doesn't affect JS engine behavior. It is used by Gecko to
245 // mark whether content windows and workers are "Secure Context"s. See
246 // https://w3c.github.io/webappsec-secure-contexts/
247 // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
248 bool secureContext() const { return secureContext_
; }
249 RealmCreationOptions
& setSecureContext(bool flag
) {
250 secureContext_
= flag
;
254 // Non-standard option to freeze certain builtin constructors and seal their
255 // prototypes. Also defines these constructors on the global as non-writable
256 // and non-configurable.
257 bool freezeBuiltins() const { return freezeBuiltins_
; }
258 RealmCreationOptions
& setFreezeBuiltins(bool flag
) {
259 freezeBuiltins_
= flag
;
263 // Force all date/time methods in JavaScript to use the UTC timezone for
264 // fingerprinting protection.
265 bool forceUTC() const { return forceUTC_
; }
266 RealmCreationOptions
& setForceUTC(bool flag
) {
271 RefPtr
<LocaleString
> locale() const { return locale_
; }
272 RealmCreationOptions
& setLocaleCopyZ(const char* locale
);
274 // Always use the fdlibm implementation of math functions instead of the
275 // platform native libc implementations. Useful for fingerprinting protection
276 // and cross-platform consistency.
277 bool alwaysUseFdlibm() const { return alwaysUseFdlibm_
; }
278 RealmCreationOptions
& setAlwaysUseFdlibm(bool flag
) {
279 alwaysUseFdlibm_
= flag
;
283 uint64_t profilerRealmID() const { return profilerRealmID_
; }
284 RealmCreationOptions
& setProfilerRealmID(uint64_t id
) {
285 profilerRealmID_
= id
;
290 JSTraceOp traceGlobal_
= nullptr;
291 CompartmentSpecifier compSpec_
= CompartmentSpecifier::NewCompartmentAndZone
;
296 uint64_t profilerRealmID_
= 0;
297 RefPtr
<LocaleString
> locale_
;
298 WeakRefSpecifier weakRefs_
= WeakRefSpecifier::Disabled
;
299 bool invisibleToDebugger_
= false;
300 bool preserveJitCode_
= false;
301 bool sharedMemoryAndAtomics_
= false;
302 bool defineSharedArrayBufferConstructor_
= true;
303 bool coopAndCoep_
= false;
304 bool toSource_
= false;
305 bool propertyErrorMessageFix_
= false;
306 bool iteratorHelpers_
= false;
307 bool shadowRealms_
= false;
308 // Pref for String.prototype.{is,to}WellFormed() methods.
309 bool wellFormedUnicodeStrings_
= true;
310 bool arrayGrouping_
= true;
312 // Pref for new Set.prototype methods.
313 bool newSetMethods_
= false;
314 // Pref for ArrayBuffer.prototype.transfer{,ToFixedLength}() methods.
315 bool arrayBufferTransfer_
= false;
317 bool secureContext_
= false;
318 bool freezeBuiltins_
= false;
319 bool forceUTC_
= false;
320 bool alwaysUseFdlibm_
= false;
324 * RealmBehaviors specifies behaviors of a realm that can be changed after the
325 * realm's been created.
327 class JS_PUBLIC_API RealmBehaviors
{
329 RealmBehaviors() = default;
331 // For certain globals, we know enough about the code that will run in them
332 // that we can discard script source entirely.
333 bool discardSource() const { return discardSource_
; }
334 RealmBehaviors
& setDiscardSource(bool flag
) {
335 discardSource_
= flag
;
339 bool clampAndJitterTime() const { return clampAndJitterTime_
; }
340 RealmBehaviors
& setClampAndJitterTime(bool flag
) {
341 clampAndJitterTime_
= flag
;
347 Override() : mode_(Default
) {}
349 bool get(bool defaultValue
) const {
350 if (mode_
== Default
) {
353 return mode_
== ForceTrue
;
356 void set(bool overrideValue
) {
357 mode_
= overrideValue
? ForceTrue
: ForceFalse
;
360 void reset() { mode_
= Default
; }
363 enum Mode
{ Default
, ForceTrue
, ForceFalse
};
368 // A Realm can stop being "live" in all the ways that matter before its global
369 // is actually GCed. Consumers that tear down parts of a Realm or its global
370 // before that point should set isNonLive accordingly.
371 bool isNonLive() const { return isNonLive_
; }
372 RealmBehaviors
& setNonLive() {
378 bool discardSource_
= false;
379 bool clampAndJitterTime_
= true;
380 bool isNonLive_
= false;
384 * RealmOptions specifies realm characteristics: both those that can't be
385 * changed on a realm once it's been created (RealmCreationOptions), and those
386 * that can be changed on an existing realm (RealmBehaviors).
388 class JS_PUBLIC_API RealmOptions
{
390 explicit RealmOptions() : creationOptions_(), behaviors_() {}
392 RealmOptions(const RealmCreationOptions
& realmCreation
,
393 const RealmBehaviors
& realmBehaviors
)
394 : creationOptions_(realmCreation
), behaviors_(realmBehaviors
) {}
396 // RealmCreationOptions specify fundamental realm characteristics that must
397 // be specified when the realm is created, that can't be changed after the
399 RealmCreationOptions
& creationOptions() { return creationOptions_
; }
400 const RealmCreationOptions
& creationOptions() const {
401 return creationOptions_
;
404 // RealmBehaviors specify realm characteristics that can be changed after
405 // the realm is created.
406 RealmBehaviors
& behaviors() { return behaviors_
; }
407 const RealmBehaviors
& behaviors() const { return behaviors_
; }
410 RealmCreationOptions creationOptions_
;
411 RealmBehaviors behaviors_
;
414 extern JS_PUBLIC_API
const RealmCreationOptions
& RealmCreationOptionsRef(
417 extern JS_PUBLIC_API
const RealmCreationOptions
& RealmCreationOptionsRef(
420 extern JS_PUBLIC_API
const RealmBehaviors
& RealmBehaviorsRef(Realm
* realm
);
422 extern JS_PUBLIC_API
const RealmBehaviors
& RealmBehaviorsRef(JSContext
* cx
);
424 extern JS_PUBLIC_API
void SetRealmNonLive(Realm
* realm
);
428 #endif // js_RealmOptions_h