Realm-inl.h (3373B)
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 vm_Realm_inl_h 8 #define vm_Realm_inl_h 9 10 #include "vm/Realm.h" 11 12 #include "gc/Barrier.h" 13 #include "gc/Marking.h" 14 #include "vm/GlobalObject.h" 15 16 #include "vm/JSContext-inl.h" 17 18 inline void JS::Realm::initGlobal(js::GlobalObject& global) { 19 MOZ_ASSERT(global.realm() == this); 20 MOZ_ASSERT(!global_); 21 global_.set(&global); 22 } 23 24 js::GlobalObject* JS::Realm::maybeGlobal() const { 25 MOZ_ASSERT_IF(global_, global_->realm() == this); 26 return global_; 27 } 28 29 inline bool JS::Realm::hasLiveGlobal() const { 30 // The global is swept by traceWeakGlobalEdge when we start sweeping a zone 31 // group. This frees the GlobalObjectData, so the realm must live at least as 32 // long as the global. 33 MOZ_ASSERT_IF(global_, !js::gc::IsAboutToBeFinalized(global_)); 34 return bool(global_); 35 } 36 37 inline bool JS::Realm::hasInitializedGlobal() const { 38 return hasLiveGlobal() && !initializingGlobal_; 39 } 40 41 inline bool JS::Realm::marked() const { 42 // The Realm survives in the following cases: 43 // - its global is live 44 // - it has been entered (to ensure we don't destroy the Realm while we're 45 // allocating its global) 46 // - it was allocated after the start of an incremental GC (as there may be 47 // pointers to it from other GC things) 48 return hasLiveGlobal() || hasBeenEnteredIgnoringJit() || 49 allocatedDuringIncrementalGC_; 50 } 51 52 /* static */ inline js::ObjectRealm& js::ObjectRealm::get(const JSObject* obj) { 53 // Note: obj might be a CCW if we're accessing ObjectRealm::enumerators. 54 // CCWs here are fine because we always return the same ObjectRealm for a 55 // particular (CCW) object. 56 return obj->maybeCCWRealm()->objects_; 57 } 58 59 template <typename T> 60 js::AutoRealm::AutoRealm(JSContext* cx, const T& target) 61 : cx_(cx), origin_(cx->realm()) { 62 cx_->enterRealmOf(target); 63 } 64 65 // Protected constructor that bypasses assertions in enterRealmOf. 66 js::AutoRealm::AutoRealm(JSContext* cx, JS::Realm* target) 67 : cx_(cx), origin_(cx->realm()) { 68 cx_->enterRealm(target); 69 } 70 71 js::AutoRealm::~AutoRealm() { cx_->leaveRealm(origin_); } 72 73 js::AutoFunctionOrCurrentRealm::AutoFunctionOrCurrentRealm(JSContext* cx, 74 HandleObject fun) { 75 JS::Realm* realm = JS::GetFunctionRealm(cx, fun); 76 if (!realm) { 77 cx->clearPendingException(); 78 return; 79 } 80 81 // Enter the function's realm. 82 ar_.emplace(cx, realm); 83 } 84 85 js::AutoAllocInAtomsZone::AutoAllocInAtomsZone(JSContext* cx) 86 : cx_(cx), origin_(cx->realm()) { 87 cx_->enterAtomsZone(); 88 } 89 90 js::AutoAllocInAtomsZone::~AutoAllocInAtomsZone() { 91 cx_->leaveAtomsZone(origin_); 92 } 93 94 js::AutoMaybeLeaveAtomsZone::AutoMaybeLeaveAtomsZone(JSContext* cx) 95 : cx_(cx), wasInAtomsZone_(cx->zone() && cx->zone()->isAtomsZone()) { 96 if (wasInAtomsZone_) { 97 cx_->leaveAtomsZone(nullptr); 98 } 99 } 100 101 js::AutoMaybeLeaveAtomsZone::~AutoMaybeLeaveAtomsZone() { 102 if (wasInAtomsZone_) { 103 cx_->enterAtomsZone(); 104 } 105 } 106 107 js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JS::Realm* target) 108 : AutoRealm(cx, target) {} 109 110 #endif /* vm_Realm_inl_h */