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/. */ 6 7 #ifndef js_Realm_h 8 #define js_Realm_h 9 10 #include "jspubtd.h" 11 #include "js/GCPolicyAPI.h" 12 #include "js/TypeDecls.h" // forward-declaration of JS::Realm 13 14 namespace js { 15 namespace gc { 16 JS_PUBLIC_API void TraceRealm(JSTracer* trc, JS::Realm* realm, 17 const char* name); 18 JS_PUBLIC_API bool RealmNeedsSweep(JS::Realm* realm); 19 } // namespace gc 20 } // namespace js 21 22 namespace JS { 23 24 // Each Realm holds a strong reference to its GlobalObject, and vice versa. 25 template <> 26 struct GCPolicy<Realm*> : public NonGCPointerPolicy<Realm*> { 27 static void trace(JSTracer* trc, Realm** vp, const char* name) { 28 if (*vp) { 29 ::js::gc::TraceRealm(trc, *vp, name); 30 } 31 } 32 static bool needsSweep(Realm** vp) { 33 return *vp && ::js::gc::RealmNeedsSweep(*vp); 34 } 35 }; 36 37 // Get the current realm, if any. The ECMAScript spec calls this "the current 38 // Realm Record". 39 extern JS_PUBLIC_API Realm* GetCurrentRealmOrNull(JSContext* cx); 40 41 namespace shadow { 42 43 class Realm { 44 protected: 45 JS::Compartment* compartment_; 46 47 explicit Realm(JS::Compartment* comp) : compartment_(comp) {} 48 49 public: 50 JS::Compartment* compartment() { return compartment_; } 51 static shadow::Realm* get(JS::Realm* realm) { 52 return reinterpret_cast<shadow::Realm*>(realm); 53 } 54 }; 55 56 }; // namespace shadow 57 58 // Return the compartment that contains a given realm. 59 inline JS::Compartment* GetCompartmentForRealm(Realm* realm) { 60 return shadow::Realm::get(realm)->compartment(); 61 } 62 63 // Return an object's realm. All objects except cross-compartment wrappers are 64 // created in a particular realm, which never changes. Returns null if obj is 65 // a cross-compartment wrapper. 66 extern JS_PUBLIC_API Realm* GetObjectRealmOrNull(JSObject* obj); 67 68 // Get the value of the "private data" internal field of the given Realm. 69 // This field is initially null and is set using SetRealmPrivate. 70 // It's a pointer to embeddding-specific data that SpiderMonkey never uses. 71 extern JS_PUBLIC_API void* GetRealmPrivate(Realm* realm); 72 73 // Set the "private data" internal field of the given Realm. 74 extern JS_PUBLIC_API void SetRealmPrivate(Realm* realm, void* data); 75 76 typedef void (*DestroyRealmCallback)(JSFreeOp* fop, Realm* realm); 77 78 // Set the callback SpiderMonkey calls just before garbage-collecting a realm. 79 // Embeddings can use this callback to free private data associated with the 80 // realm via SetRealmPrivate. 81 // 82 // By the time this is called, the global object for the realm has already been 83 // collected. 84 extern JS_PUBLIC_API void SetDestroyRealmCallback( 85 JSContext* cx, DestroyRealmCallback callback); 86 87 typedef void (*RealmNameCallback)(JSContext* cx, Handle<Realm*> realm, 88 char* buf, size_t bufsize); 89 90 // Set the callback SpiderMonkey calls to get the name of a realm, for 91 // diagnostic output. 92 extern JS_PUBLIC_API void SetRealmNameCallback(JSContext* cx, 93 RealmNameCallback callback); 94 95 // Get the global object for the given realm. This only returns nullptr during 96 // GC, between collecting the global object and destroying the Realm. 97 extern JS_PUBLIC_API JSObject* GetRealmGlobalOrNull(Handle<Realm*> realm); 98 99 // Initialize standard JS class constructors, prototypes, and any top-level 100 // functions and constants associated with the standard classes (e.g. isNaN 101 // for Number). 102 extern JS_PUBLIC_API bool InitRealmStandardClasses(JSContext* cx); 103 104 /* 105 * Ways to get various per-Realm objects. All the getters declared below operate 106 * on the JSContext's current Realm. 107 */ 108 109 extern JS_PUBLIC_API JSObject* GetRealmObjectPrototype(JSContext* cx); 110 111 extern JS_PUBLIC_API JSObject* GetRealmFunctionPrototype(JSContext* cx); 112 113 extern JS_PUBLIC_API JSObject* GetRealmArrayPrototype(JSContext* cx); 114 115 extern JS_PUBLIC_API JSObject* GetRealmErrorPrototype(JSContext* cx); 116 117 extern JS_PUBLIC_API JSObject* GetRealmIteratorPrototype(JSContext* cx); 118 119 // Implements https://tc39.github.io/ecma262/#sec-getfunctionrealm 120 // 7.3.22 GetFunctionRealm ( obj ) 121 // 122 // WARNING: may return a realm in a different compartment! 123 // 124 // Will throw an exception and return nullptr when a security wrapper or revoked 125 // proxy is encountered. 126 extern JS_PUBLIC_API Realm* GetFunctionRealm(JSContext* cx, 127 HandleObject objArg); 128 129 } // namespace JS 130 131 #endif // js_Realm_h 132