Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / public / Realm.h
blob3421a9fed3b2b4e4a6b512786d8a445814dde805
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 #ifndef js_Realm_h
8 #define js_Realm_h
10 #include "js/shadow/Realm.h" // JS::shadow::Realm
12 #include "js/GCPolicyAPI.h"
13 #include "js/TypeDecls.h" // forward-declaration of JS::Realm
15 /************************************************************************/
17 // [SMDOC] Realms
19 // Data associated with a global object. In the browser each frame has its
20 // own global/realm.
22 namespace js {
23 namespace gc {
24 JS_PUBLIC_API void TraceRealm(JSTracer* trc, JS::Realm* realm,
25 const char* name);
26 } // namespace gc
27 } // namespace js
29 namespace JS {
30 class JS_PUBLIC_API AutoRequireNoGC;
32 // Each Realm holds a weak reference to its GlobalObject.
33 template <>
34 struct GCPolicy<Realm*> : public NonGCPointerPolicy<Realm*> {
35 static void trace(JSTracer* trc, Realm** vp, const char* name) {
36 if (*vp) {
37 ::js::gc::TraceRealm(trc, *vp, name);
42 // Get the current realm, if any. The ECMAScript spec calls this "the current
43 // Realm Record".
44 extern JS_PUBLIC_API Realm* GetCurrentRealmOrNull(JSContext* cx);
46 // Return the compartment that contains a given realm.
47 inline JS::Compartment* GetCompartmentForRealm(Realm* realm) {
48 return shadow::Realm::get(realm)->compartment();
51 // Return an object's realm. All objects except cross-compartment wrappers are
52 // created in a particular realm, which never changes. Returns null if obj is
53 // a cross-compartment wrapper.
54 extern JS_PUBLIC_API Realm* GetObjectRealmOrNull(JSObject* obj);
56 // Get the value of the "private data" internal field of the given Realm.
57 // This field is initially null and is set using SetRealmPrivate.
58 // It's a pointer to embeddding-specific data that SpiderMonkey never uses.
59 extern JS_PUBLIC_API void* GetRealmPrivate(Realm* realm);
61 // Set the "private data" internal field of the given Realm.
62 extern JS_PUBLIC_API void SetRealmPrivate(Realm* realm, void* data);
64 typedef void (*DestroyRealmCallback)(JS::GCContext* gcx, Realm* realm);
66 // Set the callback SpiderMonkey calls just before garbage-collecting a realm.
67 // Embeddings can use this callback to free private data associated with the
68 // realm via SetRealmPrivate.
70 // By the time this is called, the global object for the realm has already been
71 // collected.
72 extern JS_PUBLIC_API void SetDestroyRealmCallback(
73 JSContext* cx, DestroyRealmCallback callback);
75 using RealmNameCallback = void (*)(JSContext* cx, Realm* realm, char* buf,
76 size_t bufsize,
77 const JS::AutoRequireNoGC& nogc);
79 // Set the callback SpiderMonkey calls to get the name of a realm, for
80 // diagnostic output.
81 extern JS_PUBLIC_API void SetRealmNameCallback(JSContext* cx,
82 RealmNameCallback callback);
84 // Get the global object for the given realm. This only returns nullptr during
85 // GC, between collecting the global object and destroying the Realm.
86 extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Realm* realm);
88 // Initialize standard JS class constructors, prototypes, and any top-level
89 // functions and constants associated with the standard classes (e.g. isNaN
90 // for Number).
91 extern JS_PUBLIC_API bool InitRealmStandardClasses(JSContext* cx);
93 // If the current realm has the non-standard freezeBuiltins option set to true,
94 // freeze the constructor object and seal the prototype.
95 extern JS_PUBLIC_API bool MaybeFreezeCtorAndPrototype(JSContext* cx,
96 HandleObject ctor,
97 HandleObject maybeProto);
100 * Ways to get various per-Realm objects. All the getters declared below operate
101 * on the JSContext's current Realm.
104 extern JS_PUBLIC_API JSObject* GetRealmObjectPrototype(JSContext* cx);
105 extern JS_PUBLIC_API JS::Handle<JSObject*> GetRealmObjectPrototypeHandle(
106 JSContext* cx);
108 extern JS_PUBLIC_API JSObject* GetRealmFunctionPrototype(JSContext* cx);
110 extern JS_PUBLIC_API JSObject* GetRealmArrayPrototype(JSContext* cx);
112 extern JS_PUBLIC_API JSObject* GetRealmErrorPrototype(JSContext* cx);
114 extern JS_PUBLIC_API JSObject* GetRealmIteratorPrototype(JSContext* cx);
116 extern JS_PUBLIC_API JSObject* GetRealmAsyncIteratorPrototype(JSContext* cx);
118 // Returns an object that represents the realm, that can be referred from
119 // other realm/compartment.
120 // See the consumer in `MaybeCrossOriginObjectMixins::EnsureHolder` for details.
121 extern JS_PUBLIC_API JSObject* GetRealmKeyObject(JSContext* cx);
123 // Implements https://tc39.github.io/ecma262/#sec-getfunctionrealm
124 // 7.3.22 GetFunctionRealm ( obj )
126 // WARNING: may return a realm in a different compartment!
128 // Will throw an exception and return nullptr when a security wrapper or revoked
129 // proxy is encountered.
130 extern JS_PUBLIC_API Realm* GetFunctionRealm(JSContext* cx,
131 HandleObject objArg);
133 /** NB: This API is infallible; a nullptr return value does not indicate error.
135 * |target| must not be a cross-compartment wrapper because CCWs are not
136 * associated with a single realm.
138 * Entering a realm roots the realm and its global object until the matching
139 * JS::LeaveRealm() call.
141 extern JS_PUBLIC_API JS::Realm* EnterRealm(JSContext* cx, JSObject* target);
143 extern JS_PUBLIC_API void LeaveRealm(JSContext* cx, JS::Realm* oldRealm);
145 } // namespace JS
148 * At any time, a JSContext has a current (possibly-nullptr) realm. The
149 * preferred way to change the current realm is with JSAutoRealm:
151 * void foo(JSContext* cx, JSObject* obj) {
152 * // in some realm 'r'
154 * JSAutoRealm ar(cx, obj); // constructor enters
155 * // in the realm of 'obj'
156 * } // destructor leaves
157 * // back in realm 'r'
160 * The object passed to JSAutoRealm must *not* be a cross-compartment wrapper,
161 * because CCWs are not associated with a single realm.
163 * For more complicated uses that don't neatly fit in a C++ stack frame, the
164 * realm can be entered and left using separate function calls:
166 * void foo(JSContext* cx, JSObject* obj) {
167 * // in 'oldRealm'
168 * JS::Realm* oldRealm = JS::EnterRealm(cx, obj);
169 * // in the realm of 'obj'
170 * JS::LeaveRealm(cx, oldRealm);
171 * // back in 'oldRealm'
174 * Note: these calls must still execute in a LIFO manner w.r.t all other
175 * enter/leave calls on the context. Furthermore, only the return value of a
176 * JS::EnterRealm call may be passed as the 'oldRealm' argument of
177 * the corresponding JS::LeaveRealm call.
179 * Entering a realm roots the realm and its global object for the lifetime of
180 * the JSAutoRealm.
183 class MOZ_RAII JS_PUBLIC_API JSAutoRealm {
184 JSContext* cx_;
185 JS::Realm* oldRealm_;
187 public:
188 JSAutoRealm(JSContext* cx, JSObject* target);
189 JSAutoRealm(JSContext* cx, JSScript* target);
190 ~JSAutoRealm();
193 class MOZ_RAII JS_PUBLIC_API JSAutoNullableRealm {
194 JSContext* cx_;
195 JS::Realm* oldRealm_;
197 public:
198 explicit JSAutoNullableRealm(JSContext* cx, JSObject* targetOrNull);
199 ~JSAutoNullableRealm();
202 #endif // js_Realm_h