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
22 struct JS_PUBLIC_API JSContext
;
23 class JS_PUBLIC_API JSObject
;
27 class JS_PUBLIC_API Compartment
;
28 class JS_PUBLIC_API Realm
;
29 class JS_PUBLIC_API Zone
;
36 * Specification for which compartment/zone a newly created realm should use.
38 enum class CompartmentSpecifier
{
39 // Create a new realm and compartment in the single runtime wide system
40 // zone. The meaning of this zone is left to the embedder.
41 NewCompartmentInSystemZone
,
43 // Create a new realm and compartment in a particular existing zone.
44 NewCompartmentInExistingZone
,
46 // Create a new zone/compartment.
47 NewCompartmentAndZone
,
49 // Create a new realm in an existing compartment.
52 // Internal use only. Create the self-hosting compartment.
53 NewCompartmentInSelfHostingZone
,
57 * Specification for whether weak refs should be enabled and if so whether the
58 * FinalizationRegistry.cleanupSome method should be present.
60 enum class WeakRefSpecifier
{
62 EnabledWithCleanupSome
,
63 EnabledWithoutCleanupSome
67 * RealmCreationOptions specifies options relevant to creating a new realm, that
68 * are either immutable characteristics of that realm or that are discarded
69 * after the realm has been created.
71 * Access to these options on an existing realm is read-only: if you need
72 * particular selections, you must make them before you create the realm.
74 class JS_PUBLIC_API RealmCreationOptions
{
76 RealmCreationOptions() : comp_(nullptr) {}
78 JSTraceOp
getTrace() const { return traceGlobal_
; }
79 RealmCreationOptions
& setTrace(JSTraceOp op
) {
85 MOZ_ASSERT(compSpec_
== CompartmentSpecifier::NewCompartmentInExistingZone
);
88 Compartment
* compartment() const {
89 MOZ_ASSERT(compSpec_
== CompartmentSpecifier::ExistingCompartment
);
92 CompartmentSpecifier
compartmentSpecifier() const { return compSpec_
; }
94 // Set the compartment/zone to use for the realm. See CompartmentSpecifier
96 RealmCreationOptions
& setNewCompartmentInSystemZone();
97 RealmCreationOptions
& setNewCompartmentInExistingZone(JSObject
* obj
);
98 RealmCreationOptions
& setNewCompartmentAndZone();
99 RealmCreationOptions
& setExistingCompartment(JSObject
* obj
);
100 RealmCreationOptions
& setExistingCompartment(Compartment
* compartment
);
101 RealmCreationOptions
& setNewCompartmentInSelfHostingZone();
103 // Certain compartments are implementation details of the embedding, and
104 // references to them should never leak out to script. This flag causes this
105 // realm to skip firing onNewGlobalObject and makes addDebuggee a no-op for
108 // Debugger visibility is per-compartment, not per-realm (it's only practical
109 // to enforce visibility on compartment boundaries), so if a realm is being
110 // created in an extant compartment, its requested visibility must match that
111 // of the compartment.
112 bool invisibleToDebugger() const { return invisibleToDebugger_
; }
113 RealmCreationOptions
& setInvisibleToDebugger(bool flag
) {
114 invisibleToDebugger_
= flag
;
118 // Realms used for off-thread compilation have their contents merged into a
119 // target realm when the compilation is finished. This is only allowed if
120 // this flag is set. The invisibleToDebugger flag must also be set for such
122 bool mergeable() const { return mergeable_
; }
123 RealmCreationOptions
& setMergeable(bool flag
) {
128 // Determines whether this realm should preserve JIT code on non-shrinking
130 bool preserveJitCode() const { return preserveJitCode_
; }
131 RealmCreationOptions
& setPreserveJitCode(bool flag
) {
132 preserveJitCode_
= flag
;
136 // Determines whether 1) the global Atomic property is defined and atomic
137 // operations are supported, and 2) whether shared-memory operations are
139 bool getSharedMemoryAndAtomicsEnabled() const;
140 RealmCreationOptions
& setSharedMemoryAndAtomicsEnabled(bool flag
);
142 // Determines (if getSharedMemoryAndAtomicsEnabled() is true) whether the
143 // global SharedArrayBuffer property is defined. If the property is not
144 // defined, shared array buffer functionality can only be invoked if the
145 // host/embedding specifically acts to expose it.
147 // This option defaults to true: embeddings unable to tolerate a global
148 // SharedAraryBuffer property must opt out of it.
149 bool defineSharedArrayBufferConstructor() const {
150 return defineSharedArrayBufferConstructor_
;
152 RealmCreationOptions
& setDefineSharedArrayBufferConstructor(bool flag
) {
153 defineSharedArrayBufferConstructor_
= flag
;
157 // Structured clone operations support the cloning of shared memory objects
158 // (SharedArrayBuffer or or a shared WASM Memory object) *optionally* -- at
159 // the discretion of the embedder code that performs the cloning. When a
160 // structured clone operation encounters a shared memory object and cloning
161 // shared memory objects has not been enabled, the clone fails and an
164 // In the web embedding context, shared memory object cloning is disabled
167 // 1) *no* way of supporting it is available (because the
168 // Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy HTTP
169 // headers are not respected to force the page into its own process), or
170 // 2) the aforementioned HTTP headers don't specify that the page should be
171 // opened in its own process.
173 // These two scenarios demand different error messages, and this option can be
174 // used to specify which scenario is in play.
176 // In the former case, if COOP/COEP support is not enabled, set this option to
177 // false. (This is the default.)
179 // In the latter case, if COOP/COEP weren't used to force this page into its
180 // own process, set this option to true.
182 // (Embeddings that are not the web and do not wish to support structured
183 // cloning of shared memory objects will get a "bad" web-centric error message
184 // no matter what. At present, SpiderMonkey does not offer a way for such
185 // embeddings to use an embedding-specific error message.)
186 bool getCoopAndCoepEnabled() const;
187 RealmCreationOptions
& setCoopAndCoepEnabled(bool flag
);
189 bool getStreamsEnabled() const { return streams_
; }
190 RealmCreationOptions
& setStreamsEnabled(bool flag
) {
195 bool getReadableByteStreamsEnabled() const { return readableByteStreams_
; }
196 RealmCreationOptions
& setReadableByteStreamsEnabled(bool flag
) {
197 readableByteStreams_
= flag
;
201 bool getBYOBStreamReadersEnabled() const { return byobStreamReaders_
; }
202 RealmCreationOptions
& setBYOBStreamReadersEnabled(bool enabled
) {
203 byobStreamReaders_
= enabled
;
207 bool getWritableStreamsEnabled() const { return writableStreams_
; }
208 RealmCreationOptions
& setWritableStreamsEnabled(bool enabled
) {
209 writableStreams_
= enabled
;
213 bool getReadableStreamPipeToEnabled() const { return readableStreamPipeTo_
; }
214 RealmCreationOptions
& setReadableStreamPipeToEnabled(bool enabled
) {
215 readableStreamPipeTo_
= enabled
;
219 WeakRefSpecifier
getWeakRefsEnabled() const { return weakRefs_
; }
220 RealmCreationOptions
& setWeakRefsEnabled(WeakRefSpecifier spec
) {
225 bool getToSourceEnabled() const { return toSource_
; }
226 RealmCreationOptions
& setToSourceEnabled(bool flag
) {
231 bool getPropertyErrorMessageFixEnabled() const {
232 return propertyErrorMessageFix_
;
234 RealmCreationOptions
& setPropertyErrorMessageFixEnabled(bool flag
) {
235 propertyErrorMessageFix_
= flag
;
239 bool getIteratorHelpersEnabled() const { return iteratorHelpers_
; }
240 RealmCreationOptions
& setIteratorHelpersEnabled(bool flag
) {
241 iteratorHelpers_
= flag
;
245 // This flag doesn't affect JS engine behavior. It is used by Gecko to
246 // mark whether content windows and workers are "Secure Context"s. See
247 // https://w3c.github.io/webappsec-secure-contexts/
248 // https://bugzilla.mozilla.org/show_bug.cgi?id=1162772#c34
249 bool secureContext() const { return secureContext_
; }
250 RealmCreationOptions
& setSecureContext(bool flag
) {
251 secureContext_
= flag
;
255 uint64_t profilerRealmID() const { return profilerRealmID_
; }
256 RealmCreationOptions
& setProfilerRealmID(uint64_t id
) {
257 profilerRealmID_
= id
;
262 JSTraceOp traceGlobal_
= nullptr;
263 CompartmentSpecifier compSpec_
= CompartmentSpecifier::NewCompartmentAndZone
;
268 uint64_t profilerRealmID_
= 0;
269 WeakRefSpecifier weakRefs_
= WeakRefSpecifier::Disabled
;
270 bool invisibleToDebugger_
= false;
271 bool mergeable_
= false;
272 bool preserveJitCode_
= false;
273 bool sharedMemoryAndAtomics_
= false;
274 bool defineSharedArrayBufferConstructor_
= true;
275 bool coopAndCoep_
= false;
276 bool streams_
= false;
277 bool readableByteStreams_
= false;
278 bool byobStreamReaders_
= false;
279 bool writableStreams_
= false;
280 bool readableStreamPipeTo_
= false;
281 bool toSource_
= false;
282 bool propertyErrorMessageFix_
= false;
283 bool iteratorHelpers_
= false;
284 bool secureContext_
= false;
288 * RealmBehaviors specifies behaviors of a realm that can be changed after the
289 * realm's been created.
291 class JS_PUBLIC_API RealmBehaviors
{
293 RealmBehaviors() = default;
295 // For certain globals, we know enough about the code that will run in them
296 // that we can discard script source entirely.
297 bool discardSource() const { return discardSource_
; }
298 RealmBehaviors
& setDiscardSource(bool flag
) {
299 discardSource_
= flag
;
303 bool disableLazyParsing() const { return disableLazyParsing_
; }
304 RealmBehaviors
& setDisableLazyParsing(bool flag
) {
305 disableLazyParsing_
= flag
;
309 bool clampAndJitterTime() const { return clampAndJitterTime_
; }
310 RealmBehaviors
& setClampAndJitterTime(bool flag
) {
311 clampAndJitterTime_
= flag
;
317 Override() : mode_(Default
) {}
319 bool get(bool defaultValue
) const {
320 if (mode_
== Default
) {
323 return mode_
== ForceTrue
;
326 void set(bool overrideValue
) {
327 mode_
= overrideValue
? ForceTrue
: ForceFalse
;
330 void reset() { mode_
= Default
; }
333 enum Mode
{ Default
, ForceTrue
, ForceFalse
};
338 // A Realm can stop being "live" in all the ways that matter before its global
339 // is actually GCed. Consumers that tear down parts of a Realm or its global
340 // before that point should set isNonLive accordingly.
341 bool isNonLive() const { return isNonLive_
; }
342 RealmBehaviors
& setNonLive() {
348 bool discardSource_
= false;
349 bool disableLazyParsing_
= false;
350 bool clampAndJitterTime_
= true;
351 bool isNonLive_
= false;
355 * RealmOptions specifies realm characteristics: both those that can't be
356 * changed on a realm once it's been created (RealmCreationOptions), and those
357 * that can be changed on an existing realm (RealmBehaviors).
359 class JS_PUBLIC_API RealmOptions
{
361 explicit RealmOptions() : creationOptions_(), behaviors_() {}
363 RealmOptions(const RealmCreationOptions
& realmCreation
,
364 const RealmBehaviors
& realmBehaviors
)
365 : creationOptions_(realmCreation
), behaviors_(realmBehaviors
) {}
367 // RealmCreationOptions specify fundamental realm characteristics that must
368 // be specified when the realm is created, that can't be changed after the
370 RealmCreationOptions
& creationOptions() { return creationOptions_
; }
371 const RealmCreationOptions
& creationOptions() const {
372 return creationOptions_
;
375 // RealmBehaviors specify realm characteristics that can be changed after
376 // the realm is created.
377 RealmBehaviors
& behaviors() { return behaviors_
; }
378 const RealmBehaviors
& behaviors() const { return behaviors_
; }
381 RealmCreationOptions creationOptions_
;
382 RealmBehaviors behaviors_
;
385 extern JS_PUBLIC_API
const RealmCreationOptions
& RealmCreationOptionsRef(
388 extern JS_PUBLIC_API
const RealmCreationOptions
& RealmCreationOptionsRef(
391 extern JS_PUBLIC_API
const RealmBehaviors
& RealmBehaviorsRef(Realm
* realm
);
393 extern JS_PUBLIC_API
const RealmBehaviors
& RealmBehaviorsRef(JSContext
* cx
);
395 extern JS_PUBLIC_API
void SetRealmNonLive(Realm
* realm
);
399 #endif // js_RealmOptions_h