Bug 1690340 - Part 4: Insert the "Page Source" before the "Extensions for Developers...
[gecko.git] / js / public / RealmOptions.h
blobdf6f9276181ffd928e835320198734b1bb49eb57
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
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;
25 namespace JS {
27 class JS_PUBLIC_API Compartment;
28 class JS_PUBLIC_API Realm;
29 class JS_PUBLIC_API Zone;
31 } // namespace JS
33 namespace JS {
35 /**
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.
50 ExistingCompartment,
52 // Internal use only. Create the self-hosting compartment.
53 NewCompartmentInSelfHostingZone,
56 /**
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 {
61 Disabled,
62 EnabledWithCleanupSome,
63 EnabledWithoutCleanupSome
66 /**
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 {
75 public:
76 RealmCreationOptions() : comp_(nullptr) {}
78 JSTraceOp getTrace() const { return traceGlobal_; }
79 RealmCreationOptions& setTrace(JSTraceOp op) {
80 traceGlobal_ = op;
81 return *this;
84 Zone* zone() const {
85 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::NewCompartmentInExistingZone);
86 return zone_;
88 Compartment* compartment() const {
89 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::ExistingCompartment);
90 return comp_;
92 CompartmentSpecifier compartmentSpecifier() const { return compSpec_; }
94 // Set the compartment/zone to use for the realm. See CompartmentSpecifier
95 // above.
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
106 // this global.
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;
115 return *this;
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
121 // realms.
122 bool mergeable() const { return mergeable_; }
123 RealmCreationOptions& setMergeable(bool flag) {
124 mergeable_ = flag;
125 return *this;
128 // Determines whether this realm should preserve JIT code on non-shrinking
129 // GCs.
130 bool preserveJitCode() const { return preserveJitCode_; }
131 RealmCreationOptions& setPreserveJitCode(bool flag) {
132 preserveJitCode_ = flag;
133 return *this;
136 // Determines whether 1) the global Atomic property is defined and atomic
137 // operations are supported, and 2) whether shared-memory operations are
138 // supported.
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;
154 return *this;
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
162 // error is thrown.
164 // In the web embedding context, shared memory object cloning is disabled
165 // either because
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) {
191 streams_ = flag;
192 return *this;
195 bool getReadableByteStreamsEnabled() const { return readableByteStreams_; }
196 RealmCreationOptions& setReadableByteStreamsEnabled(bool flag) {
197 readableByteStreams_ = flag;
198 return *this;
201 bool getBYOBStreamReadersEnabled() const { return byobStreamReaders_; }
202 RealmCreationOptions& setBYOBStreamReadersEnabled(bool enabled) {
203 byobStreamReaders_ = enabled;
204 return *this;
207 bool getWritableStreamsEnabled() const { return writableStreams_; }
208 RealmCreationOptions& setWritableStreamsEnabled(bool enabled) {
209 writableStreams_ = enabled;
210 return *this;
213 bool getReadableStreamPipeToEnabled() const { return readableStreamPipeTo_; }
214 RealmCreationOptions& setReadableStreamPipeToEnabled(bool enabled) {
215 readableStreamPipeTo_ = enabled;
216 return *this;
219 WeakRefSpecifier getWeakRefsEnabled() const { return weakRefs_; }
220 RealmCreationOptions& setWeakRefsEnabled(WeakRefSpecifier spec) {
221 weakRefs_ = spec;
222 return *this;
225 bool getToSourceEnabled() const { return toSource_; }
226 RealmCreationOptions& setToSourceEnabled(bool flag) {
227 toSource_ = flag;
228 return *this;
231 bool getPropertyErrorMessageFixEnabled() const {
232 return propertyErrorMessageFix_;
234 RealmCreationOptions& setPropertyErrorMessageFixEnabled(bool flag) {
235 propertyErrorMessageFix_ = flag;
236 return *this;
239 bool getIteratorHelpersEnabled() const { return iteratorHelpers_; }
240 RealmCreationOptions& setIteratorHelpersEnabled(bool flag) {
241 iteratorHelpers_ = flag;
242 return *this;
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;
252 return *this;
255 uint64_t profilerRealmID() const { return profilerRealmID_; }
256 RealmCreationOptions& setProfilerRealmID(uint64_t id) {
257 profilerRealmID_ = id;
258 return *this;
261 private:
262 JSTraceOp traceGlobal_ = nullptr;
263 CompartmentSpecifier compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
264 union {
265 Compartment* comp_;
266 Zone* zone_;
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 {
292 public:
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;
300 return *this;
303 bool disableLazyParsing() const { return disableLazyParsing_; }
304 RealmBehaviors& setDisableLazyParsing(bool flag) {
305 disableLazyParsing_ = flag;
306 return *this;
309 bool clampAndJitterTime() const { return clampAndJitterTime_; }
310 RealmBehaviors& setClampAndJitterTime(bool flag) {
311 clampAndJitterTime_ = flag;
312 return *this;
315 class Override {
316 public:
317 Override() : mode_(Default) {}
319 bool get(bool defaultValue) const {
320 if (mode_ == Default) {
321 return defaultValue;
323 return mode_ == ForceTrue;
326 void set(bool overrideValue) {
327 mode_ = overrideValue ? ForceTrue : ForceFalse;
330 void reset() { mode_ = Default; }
332 private:
333 enum Mode { Default, ForceTrue, ForceFalse };
335 Mode mode_;
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() {
343 isNonLive_ = true;
344 return *this;
347 private:
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 {
360 public:
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
369 // realm is created.
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_; }
380 private:
381 RealmCreationOptions creationOptions_;
382 RealmBehaviors behaviors_;
385 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
386 Realm* realm);
388 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
389 JSContext* cx);
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);
397 } // namespace JS
399 #endif // js_RealmOptions_h