Bug 1850887 - Remove GC_WAIT_FOR_IDLE_* telemetry r=smaug
[gecko.git] / js / public / RealmOptions.h
blobf7ad00220e68cfdcf9904d60915fafcba303ecd4
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
21 #include "js/RefCounted.h"
23 struct JS_PUBLIC_API JSContext;
24 class JS_PUBLIC_API JSObject;
26 namespace JS {
28 class JS_PUBLIC_API Compartment;
29 class JS_PUBLIC_API Realm;
30 class JS_PUBLIC_API Zone;
32 } // namespace JS
34 namespace JS {
36 /**
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.
51 ExistingCompartment,
54 /**
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 {
59 Disabled,
60 EnabledWithCleanupSome,
61 EnabledWithoutCleanupSome
64 struct LocaleString : js::RefCounted<LocaleString> {
65 const char* chars_;
67 explicit LocaleString(const char* chars) : chars_(chars) {}
69 auto chars() const { return chars_; }
72 /**
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 {
81 public:
82 RealmCreationOptions() : comp_(nullptr) {}
84 JSTraceOp getTrace() const { return traceGlobal_; }
85 RealmCreationOptions& setTrace(JSTraceOp op) {
86 traceGlobal_ = op;
87 return *this;
90 Zone* zone() const {
91 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::NewCompartmentInExistingZone);
92 return zone_;
94 Compartment* compartment() const {
95 MOZ_ASSERT(compSpec_ == CompartmentSpecifier::ExistingCompartment);
96 return comp_;
98 CompartmentSpecifier compartmentSpecifier() const { return compSpec_; }
100 // Set the compartment/zone to use for the realm. See CompartmentSpecifier
101 // above.
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
111 // this global.
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;
120 return *this;
123 // Determines whether this realm should preserve JIT code on non-shrinking
124 // GCs.
125 bool preserveJitCode() const { return preserveJitCode_; }
126 RealmCreationOptions& setPreserveJitCode(bool flag) {
127 preserveJitCode_ = flag;
128 return *this;
131 // Determines whether 1) the global Atomic property is defined and atomic
132 // operations are supported, and 2) whether shared-memory operations are
133 // supported.
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;
149 return *this;
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
157 // error is thrown.
159 // In the web embedding context, shared memory object cloning is disabled
160 // either because
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) {
186 weakRefs_ = spec;
187 return *this;
190 bool getToSourceEnabled() const { return toSource_; }
191 RealmCreationOptions& setToSourceEnabled(bool flag) {
192 toSource_ = flag;
193 return *this;
196 bool getPropertyErrorMessageFixEnabled() const {
197 return propertyErrorMessageFix_;
199 RealmCreationOptions& setPropertyErrorMessageFixEnabled(bool flag) {
200 propertyErrorMessageFix_ = flag;
201 return *this;
204 bool getIteratorHelpersEnabled() const { return iteratorHelpers_; }
205 RealmCreationOptions& setIteratorHelpersEnabled(bool flag) {
206 iteratorHelpers_ = flag;
207 return *this;
210 bool getShadowRealmsEnabled() const { return shadowRealms_; }
211 RealmCreationOptions& setShadowRealmsEnabled(bool flag) {
212 shadowRealms_ = flag;
213 return *this;
216 bool getWellFormedUnicodeStringsEnabled() const {
217 return wellFormedUnicodeStrings_;
219 RealmCreationOptions& setWellFormedUnicodeStringsEnabled(bool flag) {
220 wellFormedUnicodeStrings_ = flag;
221 return *this;
224 bool getArrayGroupingEnabled() const { return arrayGrouping_; }
225 RealmCreationOptions& setArrayGroupingEnabled(bool flag) {
226 arrayGrouping_ = flag;
227 return *this;
230 #ifdef NIGHTLY_BUILD
231 bool getNewSetMethodsEnabled() const { return newSetMethods_; }
232 RealmCreationOptions& setNewSetMethodsEnabled(bool flag) {
233 newSetMethods_ = flag;
234 return *this;
237 bool getArrayBufferTransferEnabled() const { return arrayBufferTransfer_; }
238 RealmCreationOptions& setArrayBufferTransferEnabled(bool flag) {
239 arrayBufferTransfer_ = flag;
240 return *this;
242 #endif
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;
251 return *this;
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;
260 return *this;
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) {
267 forceUTC_ = flag;
268 return *this;
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;
280 return *this;
283 uint64_t profilerRealmID() const { return profilerRealmID_; }
284 RealmCreationOptions& setProfilerRealmID(uint64_t id) {
285 profilerRealmID_ = id;
286 return *this;
289 private:
290 JSTraceOp traceGlobal_ = nullptr;
291 CompartmentSpecifier compSpec_ = CompartmentSpecifier::NewCompartmentAndZone;
292 union {
293 Compartment* comp_;
294 Zone* zone_;
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;
311 #ifdef NIGHTLY_BUILD
312 // Pref for new Set.prototype methods.
313 bool newSetMethods_ = false;
314 // Pref for ArrayBuffer.prototype.transfer{,ToFixedLength}() methods.
315 bool arrayBufferTransfer_ = false;
316 #endif
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 {
328 public:
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;
336 return *this;
339 bool clampAndJitterTime() const { return clampAndJitterTime_; }
340 RealmBehaviors& setClampAndJitterTime(bool flag) {
341 clampAndJitterTime_ = flag;
342 return *this;
345 class Override {
346 public:
347 Override() : mode_(Default) {}
349 bool get(bool defaultValue) const {
350 if (mode_ == Default) {
351 return defaultValue;
353 return mode_ == ForceTrue;
356 void set(bool overrideValue) {
357 mode_ = overrideValue ? ForceTrue : ForceFalse;
360 void reset() { mode_ = Default; }
362 private:
363 enum Mode { Default, ForceTrue, ForceFalse };
365 Mode mode_;
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() {
373 isNonLive_ = true;
374 return *this;
377 private:
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 {
389 public:
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
398 // realm is created.
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_; }
409 private:
410 RealmCreationOptions creationOptions_;
411 RealmBehaviors behaviors_;
414 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
415 Realm* realm);
417 extern JS_PUBLIC_API const RealmCreationOptions& RealmCreationOptionsRef(
418 JSContext* cx);
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);
426 } // namespace JS
428 #endif // js_RealmOptions_h