• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
isolate_data()33 inline IsolateData* Realm::isolate_data() const {
34   return env_->isolate_data();
35 }
36 
env()37 inline Environment* Realm::env() const {
38   return env_;
39 }
40 
isolate()41 inline v8::Isolate* Realm::isolate() const {
42   return isolate_;
43 }
44 
has_run_bootstrapping_code()45 inline bool Realm::has_run_bootstrapping_code() const {
46   return has_run_bootstrapping_code_;
47 }
48 
49 // static
50 template <typename T, typename U>
GetBindingData(const v8::PropertyCallbackInfo<U> & info)51 inline T* Realm::GetBindingData(const v8::PropertyCallbackInfo<U>& info) {
52   return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
53 }
54 
55 // static
56 template <typename T>
GetBindingData(const v8::FunctionCallbackInfo<v8::Value> & info)57 inline T* Realm::GetBindingData(
58     const v8::FunctionCallbackInfo<v8::Value>& info) {
59   return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
60 }
61 
62 // static
63 template <typename T>
GetBindingData(v8::Local<v8::Context> context)64 inline T* Realm::GetBindingData(v8::Local<v8::Context> context) {
65   BindingDataStore* map =
66       static_cast<BindingDataStore*>(context->GetAlignedPointerFromEmbedderData(
67           ContextEmbedderIndex::kBindingDataStoreIndex));
68   DCHECK_NOT_NULL(map);
69   constexpr size_t binding_index = static_cast<size_t>(T::binding_type_int);
70   static_assert(binding_index < std::tuple_size_v<BindingDataStore>);
71   auto ptr = (*map)[binding_index];
72   if (UNLIKELY(!ptr)) return nullptr;
73   T* result = static_cast<T*>(ptr.get());
74   DCHECK_NOT_NULL(result);
75   DCHECK_EQ(result->realm(), GetCurrent(context));
76   return result;
77 }
78 
79 template <typename T>
AddBindingData(v8::Local<v8::Context> context,v8::Local<v8::Object> target)80 inline T* Realm::AddBindingData(v8::Local<v8::Context> context,
81                                 v8::Local<v8::Object> target) {
82   DCHECK_EQ(GetCurrent(context), this);
83   // This won't compile if T is not a BaseObject subclass.
84   BaseObjectPtr<T> item = MakeDetachedBaseObject<T>(this, target);
85   BindingDataStore* map =
86       static_cast<BindingDataStore*>(context->GetAlignedPointerFromEmbedderData(
87           ContextEmbedderIndex::kBindingDataStoreIndex));
88   DCHECK_NOT_NULL(map);
89   constexpr size_t binding_index = static_cast<size_t>(T::binding_type_int);
90   static_assert(binding_index < std::tuple_size_v<BindingDataStore>);
91   CHECK(!(*map)[binding_index]);  // Should not insert the binding twice.
92   (*map)[binding_index] = item;
93   DCHECK_EQ(GetBindingData<T>(context), item.get());
94   return item.get();
95 }
96 
binding_data_store()97 inline BindingDataStore* Realm::binding_data_store() {
98   return &binding_data_store_;
99 }
100 
101 template <typename T>
ForEachBaseObject(T && iterator)102 void Realm::ForEachBaseObject(T&& iterator) const {
103   cleanup_queue_.ForEachBaseObject(std::forward<T>(iterator));
104 }
105 
modify_base_object_count(int64_t delta)106 void Realm::modify_base_object_count(int64_t delta) {
107   base_object_count_ += delta;
108 }
109 
base_object_created_after_bootstrap()110 int64_t Realm::base_object_created_after_bootstrap() const {
111   return base_object_count_ - base_object_created_by_bootstrap_;
112 }
113 
base_object_count()114 int64_t Realm::base_object_count() const {
115   return base_object_count_;
116 }
117 
118 #define V(PropertyName, TypeName)                                              \
119   inline v8::Local<TypeName> Realm::PropertyName() const {                     \
120     return PersistentToLocal::Strong(PropertyName##_);                         \
121   }                                                                            \
122   inline void Realm::set_##PropertyName(v8::Local<TypeName> value) {           \
123     PropertyName##_.Reset(isolate(), value);                                   \
124   }
PER_REALM_STRONG_PERSISTENT_VALUES(V)125 PER_REALM_STRONG_PERSISTENT_VALUES(V)
126 #undef V
127 
128 v8::Local<v8::Context> Realm::context() const {
129   return PersistentToLocal::Strong(context_);
130 }
131 
AddCleanupHook(CleanupQueue::Callback fn,void * arg)132 void Realm::AddCleanupHook(CleanupQueue::Callback fn, void* arg) {
133   cleanup_queue_.Add(fn, arg);
134 }
135 
RemoveCleanupHook(CleanupQueue::Callback fn,void * arg)136 void Realm::RemoveCleanupHook(CleanupQueue::Callback fn, void* arg) {
137   cleanup_queue_.Remove(fn, arg);
138 }
139 
HasCleanupHooks()140 bool Realm::HasCleanupHooks() const {
141   return !cleanup_queue_.empty();
142 }
143 
144 }  // namespace node
145 
146 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
147 
148 #endif  // SRC_NODE_REALM_INL_H_
149