summaryrefslogtreecommitdiff
path: root/src/node_realm-inl.h
blob: c6a85d24d1767c423eba9b9ec7205c965e70270e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#ifndef SRC_NODE_REALM_INL_H_
#define SRC_NODE_REALM_INL_H_

#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#include "cleanup_queue-inl.h"
#include "node_realm.h"

namespace node {

inline Realm* Realm::GetCurrent(v8::Isolate* isolate) {
  if (UNLIKELY(!isolate->InContext())) return nullptr;
  v8::HandleScope handle_scope(isolate);
  return GetCurrent(isolate->GetCurrentContext());
}

inline Realm* Realm::GetCurrent(v8::Local<v8::Context> context) {
  if (UNLIKELY(!ContextEmbedderTag::IsNodeContext(context))) return nullptr;
  return static_cast<Realm*>(
      context->GetAlignedPointerFromEmbedderData(ContextEmbedderIndex::kRealm));
}

inline Realm* Realm::GetCurrent(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  return GetCurrent(info.GetIsolate()->GetCurrentContext());
}

template <typename T>
inline Realm* Realm::GetCurrent(const v8::PropertyCallbackInfo<T>& info) {
  return GetCurrent(info.GetIsolate()->GetCurrentContext());
}

inline IsolateData* Realm::isolate_data() const {
  return env_->isolate_data();
}

inline Environment* Realm::env() const {
  return env_;
}

inline v8::Isolate* Realm::isolate() const {
  return isolate_;
}

inline Realm::Kind Realm::kind() const {
  return kind_;
}

inline bool Realm::has_run_bootstrapping_code() const {
  return has_run_bootstrapping_code_;
}

// static
template <typename T, typename U>
inline T* Realm::GetBindingData(const v8::PropertyCallbackInfo<U>& info) {
  return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
}

// static
template <typename T>
inline T* Realm::GetBindingData(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  return GetBindingData<T>(info.GetIsolate()->GetCurrentContext());
}

// static
template <typename T>
inline T* Realm::GetBindingData(v8::Local<v8::Context> context) {
  BindingDataStore* map =
      static_cast<BindingDataStore*>(context->GetAlignedPointerFromEmbedderData(
          ContextEmbedderIndex::kBindingDataStoreIndex));
  DCHECK_NOT_NULL(map);
  constexpr size_t binding_index = static_cast<size_t>(T::binding_type_int);
  static_assert(binding_index < std::tuple_size_v<BindingDataStore>);
  auto ptr = (*map)[binding_index];
  if (UNLIKELY(!ptr)) return nullptr;
  T* result = static_cast<T*>(ptr.get());
  DCHECK_NOT_NULL(result);
  DCHECK_EQ(result->realm(), GetCurrent(context));
  return result;
}

template <typename T, typename... Args>
inline T* Realm::AddBindingData(v8::Local<v8::Context> context,
                                v8::Local<v8::Object> target,
                                Args&&... args) {
  DCHECK_EQ(GetCurrent(context), this);
  // This won't compile if T is not a BaseObject subclass.
  BaseObjectPtr<T> item =
      MakeDetachedBaseObject<T>(this, target, std::forward<Args>(args)...);
  DCHECK_EQ(context->GetAlignedPointerFromEmbedderData(
                ContextEmbedderIndex::kBindingDataStoreIndex),
            &binding_data_store_);
  constexpr size_t binding_index = static_cast<size_t>(T::binding_type_int);
  static_assert(binding_index < std::tuple_size_v<BindingDataStore>);
  // Should not insert the binding twice.
  CHECK(!binding_data_store_[binding_index]);
  binding_data_store_[binding_index] = item;
  DCHECK_EQ(GetBindingData<T>(context), item.get());
  return item.get();
}

inline BindingDataStore* Realm::binding_data_store() {
  return &binding_data_store_;
}

template <typename T>
void Realm::ForEachBaseObject(T&& iterator) const {
  cleanup_queue_.ForEachBaseObject(std::forward<T>(iterator));
}

void Realm::modify_base_object_count(int64_t delta) {
  base_object_count_ += delta;
}

int64_t Realm::base_object_created_after_bootstrap() const {
  return base_object_count_ - base_object_created_by_bootstrap_;
}

int64_t Realm::base_object_count() const {
  return base_object_count_;
}

void Realm::AddCleanupHook(CleanupQueue::Callback fn, void* arg) {
  cleanup_queue_.Add(fn, arg);
}

void Realm::RemoveCleanupHook(CleanupQueue::Callback fn, void* arg) {
  cleanup_queue_.Remove(fn, arg);
}

bool Realm::HasCleanupHooks() const {
  return !cleanup_queue_.empty();
}

}  // namespace node

#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS

#endif  // SRC_NODE_REALM_INL_H_