1 #ifndef SRC_NODE_REALM_INL_H_
2 #define SRC_NODE_REALM_INL_H_
3
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5
6 #include "cleanup_queue-inl.h"
7 #include "node_realm.h"
8
9 namespace node {
10
GetCurrent(v8::Isolate * isolate)11 inline Realm* Realm::GetCurrent(v8::Isolate* isolate) {
12 if (UNLIKELY(!isolate->InContext())) return nullptr;
13 v8::HandleScope handle_scope(isolate);
14 return GetCurrent(isolate->GetCurrentContext());
15 }
16
GetCurrent(v8::Local<v8::Context> context)17 inline Realm* Realm::GetCurrent(v8::Local<v8::Context> context) {
18 if (UNLIKELY(!ContextEmbedderTag::IsNodeContext(context))) return nullptr;
19 return static_cast<Realm*>(
20 context->GetAlignedPointerFromEmbedderData(ContextEmbedderIndex::kRealm));
21 }
22
GetCurrent(const v8::FunctionCallbackInfo<v8::Value> & info)23 inline Realm* Realm::GetCurrent(
24 const v8::FunctionCallbackInfo<v8::Value>& info) {
25 return GetCurrent(info.GetIsolate()->GetCurrentContext());
26 }
27
28 template <typename T>
GetCurrent(const v8::PropertyCallbackInfo<T> & info)29 inline Realm* Realm::GetCurrent(const v8::PropertyCallbackInfo<T>& info) {
30 return GetCurrent(info.GetIsolate()->GetCurrentContext());
31 }
32
env()33 inline Environment* Realm::env() const {
34 return env_;
35 }
36
isolate()37 inline v8::Isolate* Realm::isolate() const {
38 return isolate_;
39 }
40
has_run_bootstrapping_code()41 inline bool Realm::has_run_bootstrapping_code() const {
42 return has_run_bootstrapping_code_;
43 }
44
45 // static
46 template <typename T, typename U>
GetBindingData(const v8::PropertyCallbackInfo<U> & info)47 inline T* Realm::GetBindingData(const v8::PropertyCallbackInfo<U>& info) {
48 return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
49 }
50
51 // static
52 template <typename T>
GetBindingData(const v8::FunctionCallbackInfo<v8::Value> & info)53 inline T* Realm::GetBindingData(
54 const v8::FunctionCallbackInfo<v8::Value>& info) {
55 return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
56 }
57
58 // static
59 template <typename T>
GetBindingData(v8::Local<v8::Context> context)60 inline T* Realm::GetBindingData(v8::Local<v8::Context> context) {
61 BindingDataStore* map =
62 static_cast<BindingDataStore*>(context->GetAlignedPointerFromEmbedderData(
63 ContextEmbedderIndex::kBindingDataStoreIndex));
64 DCHECK_NOT_NULL(map);
65 auto it = map->find(T::type_name);
66 if (UNLIKELY(it == map->end())) return nullptr;
67 T* result = static_cast<T*>(it->second.get());
68 DCHECK_NOT_NULL(result);
69 DCHECK_EQ(result->realm(), GetCurrent(context));
70 return result;
71 }
72
73 template <typename T>
AddBindingData(v8::Local<v8::Context> context,v8::Local<v8::Object> target)74 inline T* Realm::AddBindingData(v8::Local<v8::Context> context,
75 v8::Local<v8::Object> target) {
76 DCHECK_EQ(GetCurrent(context), this);
77 // This won't compile if T is not a BaseObject subclass.
78 BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target);
79 BindingDataStore* map =
80 static_cast<BindingDataStore*>(context->GetAlignedPointerFromEmbedderData(
81 ContextEmbedderIndex::kBindingDataStoreIndex));
82 DCHECK_NOT_NULL(map);
83 auto result = map->emplace(T::type_name, item);
84 CHECK(result.second);
85 DCHECK_EQ(GetBindingData<T>(context), item.get());
86 return item.get();
87 }
88
binding_data_store()89 inline BindingDataStore* Realm::binding_data_store() {
90 return &binding_data_store_;
91 }
92
93 template <typename T>
ForEachBaseObject(T && iterator)94 void Realm::ForEachBaseObject(T&& iterator) const {
95 cleanup_queue_.ForEachBaseObject(std::forward<T>(iterator));
96 }
97
modify_base_object_count(int64_t delta)98 void Realm::modify_base_object_count(int64_t delta) {
99 base_object_count_ += delta;
100 }
101
base_object_created_after_bootstrap()102 int64_t Realm::base_object_created_after_bootstrap() const {
103 return base_object_count_ - base_object_created_by_bootstrap_;
104 }
105
base_object_count()106 int64_t Realm::base_object_count() const {
107 return base_object_count_;
108 }
109
110 #define V(PropertyName, TypeName) \
111 inline v8::Local<TypeName> Realm::PropertyName() const { \
112 return PersistentToLocal::Strong(PropertyName##_); \
113 } \
114 inline void Realm::set_##PropertyName(v8::Local<TypeName> value) { \
115 PropertyName##_.Reset(isolate(), value); \
116 }
PER_REALM_STRONG_PERSISTENT_VALUES(V)117 PER_REALM_STRONG_PERSISTENT_VALUES(V)
118 #undef V
119
120 v8::Local<v8::Context> Realm::context() const {
121 return PersistentToLocal::Strong(context_);
122 }
123
AddCleanupHook(CleanupQueue::Callback fn,void * arg)124 void Realm::AddCleanupHook(CleanupQueue::Callback fn, void* arg) {
125 cleanup_queue_.Add(fn, arg);
126 }
127
RemoveCleanupHook(CleanupQueue::Callback fn,void * arg)128 void Realm::RemoveCleanupHook(CleanupQueue::Callback fn, void* arg) {
129 cleanup_queue_.Remove(fn, arg);
130 }
131
HasCleanupHooks()132 bool Realm::HasCleanupHooks() const {
133 return !cleanup_queue_.empty();
134 }
135
136 } // namespace node
137
138 #endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
139
140 #endif // SRC_NODE_REALM_INL_H_
141