Coverage Report

Created: 2025-07-04 09:33

/src/node/deps/v8/include/v8-persistent-handle.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2021 the V8 project authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
#ifndef INCLUDE_V8_PERSISTENT_HANDLE_H_
6
#define INCLUDE_V8_PERSISTENT_HANDLE_H_
7
8
#include "v8-internal.h"            // NOLINT(build/include_directory)
9
#include "v8-local-handle.h"        // NOLINT(build/include_directory)
10
#include "v8-weak-callback-info.h"  // NOLINT(build/include_directory)
11
#include "v8config.h"               // NOLINT(build/include_directory)
12
13
namespace v8 {
14
15
class Isolate;
16
template <class K, class V, class T>
17
class PersistentValueMapBase;
18
template <class V, class T>
19
class PersistentValueVector;
20
template <class T>
21
class Global;
22
template <class T>
23
class PersistentBase;
24
template <class K, class V, class T>
25
class PersistentValueMap;
26
class Value;
27
28
namespace api_internal {
29
V8_EXPORT internal::Address* Eternalize(v8::Isolate* isolate, Value* handle);
30
V8_EXPORT internal::Address* CopyGlobalReference(internal::Address* from);
31
V8_EXPORT void DisposeGlobal(internal::Address* global_handle);
32
V8_EXPORT void MakeWeak(internal::Address** location_addr);
33
V8_EXPORT void* ClearWeak(internal::Address* location);
34
V8_EXPORT void AnnotateStrongRetainer(internal::Address* location,
35
                                      const char* label);
36
V8_EXPORT internal::Address* GlobalizeReference(internal::Isolate* isolate,
37
                                                internal::Address value);
38
V8_EXPORT void MoveGlobalReference(internal::Address** from,
39
                                   internal::Address** to);
40
}  // namespace api_internal
41
42
/**
43
 * Eternal handles are set-once handles that live for the lifetime of the
44
 * isolate.
45
 */
46
template <class T>
47
class Eternal : public api_internal::IndirectHandleBase {
48
 public:
49
68.1M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Private>::Eternal()
Line
Count
Source
49
10.0M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Symbol>::Eternal()
Line
Count
Source
49
2.42M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::String>::Eternal()
Line
Count
Source
49
47.1M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::FunctionTemplate>::Eternal()
Line
Count
Source
49
3.49M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::ObjectTemplate>::Eternal()
Line
Count
Source
49
4.97M
  V8_INLINE Eternal() = default;
50
51
  template <class S>
52
  V8_INLINE Eternal(Isolate* isolate, Local<S> handle) {
53
    Set(isolate, handle);
54
  }
55
56
  // Can only be safely called if already set.
57
138M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
138M
    return Local<T>::FromSlot(slot());
61
138M
  }
v8::Eternal<v8::String>::Get(v8::Isolate*) const
Line
Count
Source
57
121M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
121M
    return Local<T>::FromSlot(slot());
61
121M
  }
v8::Eternal<v8::Private>::Get(v8::Isolate*) const
Line
Count
Source
57
3.33M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
3.33M
    return Local<T>::FromSlot(slot());
61
3.33M
  }
v8::Eternal<v8::Symbol>::Get(v8::Isolate*) const
Line
Count
Source
57
5.29M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
5.29M
    return Local<T>::FromSlot(slot());
61
5.29M
  }
v8::Eternal<v8::FunctionTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
2.91M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
2.91M
    return Local<T>::FromSlot(slot());
61
2.91M
  }
v8::Eternal<v8::ObjectTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
4.96M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
58
    // The eternal handle will never go away, so as with the roots, we don't
59
    // even need to open a handle.
60
4.96M
    return Local<T>::FromSlot(slot());
61
4.96M
  }
62
63
  template <class S>
64
64.9M
  void Set(Isolate* isolate, Local<S> handle) {
65
64.9M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
64.9M
    slot() =
67
64.9M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
64.9M
  }
void v8::Eternal<v8::FunctionTemplate>::Set<v8::FunctionTemplate>(v8::Isolate*, v8::Local<v8::FunctionTemplate>)
Line
Count
Source
64
1.23M
  void Set(Isolate* isolate, Local<S> handle) {
65
1.23M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
1.23M
    slot() =
67
1.23M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
1.23M
  }
void v8::Eternal<v8::ObjectTemplate>::Set<v8::ObjectTemplate>(v8::Isolate*, v8::Local<v8::ObjectTemplate>)
Line
Count
Source
64
4.08M
  void Set(Isolate* isolate, Local<S> handle) {
65
4.08M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
4.08M
    slot() =
67
4.08M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
4.08M
  }
void v8::Eternal<v8::Private>::Set<v8::Private>(v8::Isolate*, v8::Local<v8::Private>)
Line
Count
Source
64
10.0M
  void Set(Isolate* isolate, Local<S> handle) {
65
10.0M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
10.0M
    slot() =
67
10.0M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
10.0M
  }
void v8::Eternal<v8::Symbol>::Set<v8::Symbol>(v8::Isolate*, v8::Local<v8::Symbol>)
Line
Count
Source
64
2.42M
  void Set(Isolate* isolate, Local<S> handle) {
65
2.42M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
2.42M
    slot() =
67
2.42M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
2.42M
  }
void v8::Eternal<v8::String>::Set<v8::String>(v8::Isolate*, v8::Local<v8::String>)
Line
Count
Source
64
47.1M
  void Set(Isolate* isolate, Local<S> handle) {
65
47.1M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
47.1M
    slot() =
67
47.1M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
47.1M
  }
69
};
70
71
namespace api_internal {
72
V8_EXPORT void MakeWeak(internal::Address* location, void* data,
73
                        WeakCallbackInfo<void>::Callback weak_callback,
74
                        WeakCallbackType type);
75
}  // namespace api_internal
76
77
/**
78
 * An object reference that is independent of any handle scope.  Where
79
 * a Local handle only lives as long as the HandleScope in which it was
80
 * allocated, a PersistentBase handle remains valid until it is explicitly
81
 * disposed using Reset().
82
 *
83
 * A persistent handle contains a reference to a storage cell within
84
 * the V8 engine which holds an object value and which is updated by
85
 * the garbage collector whenever the object is moved.  A new storage
86
 * cell can be created using the constructor or PersistentBase::Reset and
87
 * existing handles can be disposed using PersistentBase::Reset.
88
 *
89
 */
90
template <class T>
91
class PersistentBase : public api_internal::IndirectHandleBase {
92
 public:
93
  /**
94
   * If non-empty, destroy the underlying storage cell
95
   * IsEmpty() will return true after this call.
96
   */
97
  V8_INLINE void Reset();
98
99
  /**
100
   * If non-empty, destroy the underlying storage cell
101
   * and create a new one with the contents of other if other is non empty
102
   */
103
  template <class S>
104
  V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
105
106
  /**
107
   * If non-empty, destroy the underlying storage cell
108
   * and create a new one with the contents of other if other is non empty
109
   */
110
  template <class S>
111
  V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other);
112
113
2.78M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
2.78M
    return Local<T>::New(isolate, *this);
115
2.78M
  }
Unexecuted instantiation: v8::PersistentBase<v8::Int8Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Uint8Array>::Get(v8::Isolate*) const
Line
Count
Source
113
538k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
538k
    return Local<T>::New(isolate, *this);
115
538k
  }
Unexecuted instantiation: v8::PersistentBase<v8::Int16Array>::Get(v8::Isolate*) const
Unexecuted instantiation: v8::PersistentBase<v8::Uint16Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Int32Array>::Get(v8::Isolate*) const
Line
Count
Source
113
359k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
359k
    return Local<T>::New(isolate, *this);
115
359k
  }
v8::PersistentBase<v8::Uint32Array>::Get(v8::Isolate*) const
Line
Count
Source
113
942k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
942k
    return Local<T>::New(isolate, *this);
115
942k
  }
Unexecuted instantiation: v8::PersistentBase<v8::Float32Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Float64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
672k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
672k
    return Local<T>::New(isolate, *this);
115
672k
  }
v8::PersistentBase<v8::BigInt64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
269k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
269k
    return Local<T>::New(isolate, *this);
115
269k
  }
Unexecuted instantiation: v8::PersistentBase<v8::Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Function>::Get(v8::Isolate*) const
Line
Count
Source
113
2
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
2
    return Local<T>::New(isolate, *this);
115
2
  }
v8::PersistentBase<v8::Object>::Get(v8::Isolate*) const
Line
Count
Source
113
8
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
8
    return Local<T>::New(isolate, *this);
115
8
  }
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::Get(v8::Isolate*) const
Unexecuted instantiation: v8::PersistentBase<v8::Module>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Value>::Get(v8::Isolate*) const
Line
Count
Source
113
2
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
2
    return Local<T>::New(isolate, *this);
115
2
  }
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::Get(v8::Isolate*) const
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::Get(v8::Isolate*) const
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBufferView>::Get(v8::Isolate*) const
Unexecuted instantiation: v8::PersistentBase<v8::Context>::Get(v8::Isolate*) const
116
117
  template <class S>
118
  V8_INLINE bool operator==(const PersistentBase<S>& that) const {
119
    return internal::HandleHelper::EqualHandles(*this, that);
120
  }
121
122
  template <class S>
123
0
  V8_INLINE bool operator==(const Local<S>& that) const {
124
0
    return internal::HandleHelper::EqualHandles(*this, that);
125
0
  }
Unexecuted instantiation: bool v8::PersistentBase<v8::Context>::operator==<v8::Context>(v8::Local<v8::Context> const&) const
Unexecuted instantiation: bool v8::PersistentBase<v8::Module>::operator==<v8::Module>(v8::Local<v8::Module> const&) const
126
127
  template <class S>
128
  V8_INLINE bool operator!=(const PersistentBase<S>& that) const {
129
    return !operator==(that);
130
  }
131
132
  template <class S>
133
  V8_INLINE bool operator!=(const Local<S>& that) const {
134
    return !operator==(that);
135
  }
136
137
  /**
138
   * Install a finalization callback on this object.
139
   * NOTE: There is no guarantee as to *when* or even *if* the callback is
140
   * invoked. The invocation is performed solely on a best effort basis.
141
   * As always, GC-based finalization should *not* be relied upon for any
142
   * critical form of resource management!
143
   *
144
   * The callback is supposed to reset the handle. No further V8 API may be
145
   * called in this callback. In case additional work involving V8 needs to be
146
   * done, a second callback can be scheduled using
147
   * WeakCallbackInfo<void>::SetSecondPassCallback.
148
   */
149
  template <typename P>
150
  V8_INLINE void SetWeak(P* parameter,
151
                         typename WeakCallbackInfo<P>::Callback callback,
152
                         WeakCallbackType type);
153
154
  /**
155
   * Turns this handle into a weak phantom handle without finalization callback.
156
   * The handle will be reset automatically when the garbage collector detects
157
   * that the object is no longer reachable.
158
   */
159
  V8_INLINE void SetWeak();
160
161
  template <typename P>
162
  V8_INLINE P* ClearWeak();
163
164
  // TODO(dcarney): remove this.
165
116k
  V8_INLINE void ClearWeak() { ClearWeak<void>(); }
v8::PersistentBase<v8::Object>::ClearWeak()
Line
Count
Source
165
116k
  V8_INLINE void ClearWeak() { ClearWeak<void>(); }
Unexecuted instantiation: v8::PersistentBase<v8::Value>::ClearWeak()
166
167
  /**
168
   * Annotates the strong handle with the given label, which is then used by the
169
   * heap snapshot generator as a name of the edge from the root to the handle.
170
   * The function does not take ownership of the label and assumes that the
171
   * label is valid as long as the handle is valid.
172
   */
173
  V8_INLINE void AnnotateStrongRetainer(const char* label);
174
175
  /** Returns true if the handle's reference is weak.  */
176
  V8_INLINE bool IsWeak() const;
177
178
  /**
179
   * Assigns a wrapper class ID to the handle.
180
   */
181
  V8_INLINE void SetWrapperClassId(uint16_t class_id);
182
183
  /**
184
   * Returns the class ID previously assigned to this handle or 0 if no class ID
185
   * was previously assigned.
186
   */
187
  V8_INLINE uint16_t WrapperClassId() const;
188
189
  PersistentBase(const PersistentBase& other) = delete;
190
  void operator=(const PersistentBase&) = delete;
191
192
 private:
193
  friend class Isolate;
194
  friend class Utils;
195
  template <class F>
196
  friend class Local;
197
  template <class F1, class F2>
198
  friend class Persistent;
199
  template <class F>
200
  friend class Global;
201
  template <class F>
202
  friend class PersistentBase;
203
  template <class F>
204
  friend class ReturnValue;
205
  template <class F1, class F2, class F3>
206
  friend class PersistentValueMapBase;
207
  template <class F1, class F2>
208
  friend class PersistentValueVector;
209
  friend class Object;
210
  friend class internal::ValueHelper;
211
212
11.8M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Object>::PersistentBase()
Line
Count
Source
212
1.21M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Array>::PersistentBase()
Line
Count
Source
212
134k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Function>::PersistentBase()
Line
Count
Source
212
7.53M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Context>::PersistentBase()
Line
Count
Source
212
271k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Int32Array>::PersistentBase()
Line
Count
Source
212
403k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint32Array>::PersistentBase()
Line
Count
Source
212
942k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint8Array>::PersistentBase()
Line
Count
Source
212
403k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Float64Array>::PersistentBase()
Line
Count
Source
212
672k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::PersistentBase()
v8::PersistentBase<v8::Value>::PersistentBase()
Line
Count
Source
212
8.51k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::PersistentBase()
v8::PersistentBase<v8::UnboundScript>::PersistentBase()
Line
Count
Source
212
1.13k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::BigInt64Array>::PersistentBase()
Line
Count
Source
212
269k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::PersistentBase()
v8::PersistentBase<v8::ArrayBufferView>::PersistentBase()
Line
Count
Source
212
847
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::PersistentBase()
213
214
  V8_INLINE explicit PersistentBase(internal::Address* location)
215
3.89M
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Object>::PersistentBase(unsigned long*)
Line
Count
Source
215
1.19M
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Context>::PersistentBase(unsigned long*)
Line
Count
Source
215
9.65k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Int32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
403k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
942k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint8Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
403k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Float64Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
672k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Value>::PersistentBase(unsigned long*)
Line
Count
Source
215
8
      : IndirectHandleBase(location) {}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::PersistentBase(unsigned long*)
v8::PersistentBase<v8::BigInt64Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
269k
      : IndirectHandleBase(location) {}
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::PersistentBase(unsigned long*)
Unexecuted instantiation: v8::PersistentBase<v8::SharedArrayBuffer>::PersistentBase(unsigned long*)
Unexecuted instantiation: v8::PersistentBase<v8::Function>::PersistentBase(unsigned long*)
216
217
  V8_INLINE static internal::Address* New(Isolate* isolate, T* that);
218
};
219
220
/**
221
 * Default traits for Persistent. This class does not allow
222
 * use of the copy constructor or assignment operator.
223
 * At present kResetInDestructor is not set, but that will change in a future
224
 * version.
225
 */
226
template <class T>
227
class NonCopyablePersistentTraits {
228
 public:
229
  using NonCopyablePersistent = Persistent<T, NonCopyablePersistentTraits<T>>;
230
  static const bool kResetInDestructor = false;
231
  template <class S, class M>
232
  V8_INLINE static void Copy(const Persistent<S, M>& source,
233
                             NonCopyablePersistent* dest) {
234
    static_assert(sizeof(S) < 0,
235
                  "NonCopyablePersistentTraits::Copy is not instantiable");
236
  }
237
};
238
239
/**
240
 * Helper class traits to allow copying and assignment of Persistent.
241
 * This will clone the contents of storage cell, but not any of the flags, etc.
242
 */
243
template <class T>
244
struct CopyablePersistentTraits {
245
  using CopyablePersistent = Persistent<T, CopyablePersistentTraits<T>>;
246
  static const bool kResetInDestructor = true;
247
  template <class S, class M>
248
  static V8_INLINE void Copy(const Persistent<S, M>& source,
249
                             CopyablePersistent* dest) {
250
    // do nothing, just allow copy
251
  }
252
};
253
254
/**
255
 * A PersistentBase which allows copy and assignment.
256
 *
257
 * Copy, assignment and destructor behavior is controlled by the traits
258
 * class M.
259
 *
260
 * CAVEAT: Persistent objects do not have proper destruction behavior by default
261
 * and as such will leak the object without explicit clear. Consider using
262
 * `v8::Global` instead which has proper destruction and move semantics.
263
 */
264
template <class T, class M>
265
class Persistent : public PersistentBase<T> {
266
 public:
267
  /**
268
   * A Persistent with no storage cell.
269
   */
270
  V8_INLINE Persistent() = default;
271
272
  /**
273
   * Construct a Persistent from a Local.
274
   * When the Local is non-empty, a new storage cell is created
275
   * pointing to the same object, and no flags are set.
276
   */
277
  template <class S>
278
  V8_INLINE Persistent(Isolate* isolate, Local<S> that)
279
      : PersistentBase<T>(
280
            PersistentBase<T>::New(isolate, that.template value<S>())) {
281
    static_assert(std::is_base_of<T, S>::value, "type check");
282
  }
283
284
  /**
285
   * Construct a Persistent from a Persistent.
286
   * When the Persistent is non-empty, a new storage cell is created
287
   * pointing to the same object, and no flags are set.
288
   */
289
  template <class S, class M2>
290
  V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that)
291
      : PersistentBase<T>(
292
            PersistentBase<T>::New(isolate, that.template value<S>())) {
293
    static_assert(std::is_base_of<T, S>::value, "type check");
294
  }
295
296
  /**
297
   * The copy constructors and assignment operator create a Persistent
298
   * exactly as the Persistent constructor, but the Copy function from the
299
   * traits class is called, allowing the setting of flags based on the
300
   * copied Persistent.
301
   */
302
  V8_INLINE Persistent(const Persistent& that) : PersistentBase<T>() {
303
    Copy(that);
304
  }
305
  template <class S, class M2>
306
  V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>() {
307
    Copy(that);
308
  }
309
  V8_INLINE Persistent& operator=(const Persistent& that) {
310
    Copy(that);
311
    return *this;
312
  }
313
  template <class S, class M2>
314
  V8_INLINE Persistent& operator=(const Persistent<S, M2>& that) {
315
    Copy(that);
316
    return *this;
317
  }
318
319
  /**
320
   * The destructor will dispose the Persistent based on the
321
   * kResetInDestructor flags in the traits class.  Since not calling dispose
322
   * can result in a memory leak, it is recommended to always set this flag.
323
   */
324
  V8_INLINE ~Persistent() {
325
    if (M::kResetInDestructor) this->Reset();
326
  }
327
328
  // TODO(dcarney): this is pretty useless, fix or remove
329
  template <class S, class M2>
330
  V8_INLINE static Persistent<T, M>& Cast(const Persistent<S, M2>& that) {
331
#ifdef V8_ENABLE_CHECKS
332
    // If we're going to perform the type check then we have to check
333
    // that the handle isn't empty before doing the checked cast.
334
    if (!that.IsEmpty()) T::Cast(that.template value<S>());
335
#endif
336
    return reinterpret_cast<Persistent<T, M>&>(
337
        const_cast<Persistent<S, M2>&>(that));
338
  }
339
340
  // TODO(dcarney): this is pretty useless, fix or remove
341
  template <class S, class M2>
342
  V8_INLINE Persistent<S, M2>& As() const {
343
    return Persistent<S, M2>::Cast(*this);
344
  }
345
346
 private:
347
  friend class Isolate;
348
  friend class Utils;
349
  template <class F>
350
  friend class Local;
351
  template <class F1, class F2>
352
  friend class Persistent;
353
  template <class F>
354
  friend class ReturnValue;
355
356
  template <class S, class M2>
357
  V8_INLINE void Copy(const Persistent<S, M2>& that);
358
};
359
360
/**
361
 * A PersistentBase which has move semantics.
362
 *
363
 * Note: Persistent class hierarchy is subject to future changes.
364
 */
365
template <class T>
366
class Global : public PersistentBase<T> {
367
 public:
368
  /**
369
   * A Global with no storage cell.
370
   */
371
11.8M
  V8_INLINE Global() = default;
v8::Global<v8::Object>::Global()
Line
Count
Source
371
1.21M
  V8_INLINE Global() = default;
v8::Global<v8::Array>::Global()
Line
Count
Source
371
134k
  V8_INLINE Global() = default;
v8::Global<v8::Function>::Global()
Line
Count
Source
371
7.53M
  V8_INLINE Global() = default;
v8::Global<v8::Context>::Global()
Line
Count
Source
371
271k
  V8_INLINE Global() = default;
v8::Global<v8::Int32Array>::Global()
Line
Count
Source
371
403k
  V8_INLINE Global() = default;
v8::Global<v8::Uint32Array>::Global()
Line
Count
Source
371
942k
  V8_INLINE Global() = default;
v8::Global<v8::Uint8Array>::Global()
Line
Count
Source
371
403k
  V8_INLINE Global() = default;
v8::Global<v8::Float64Array>::Global()
Line
Count
Source
371
672k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::Promise>::Global()
v8::Global<v8::Value>::Global()
Line
Count
Source
371
8.51k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>::Global()
v8::Global<v8::UnboundScript>::Global()
Line
Count
Source
371
1.13k
  V8_INLINE Global() = default;
v8::Global<v8::BigInt64Array>::Global()
Line
Count
Source
371
269k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::WasmMemoryObject>::Global()
v8::Global<v8::ArrayBufferView>::Global()
Line
Count
Source
371
847
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::FunctionTemplate>::Global()
372
373
  /**
374
   * Construct a Global from a Local.
375
   * When the Local is non-empty, a new storage cell is created
376
   * pointing to the same object, and no flags are set.
377
   */
378
  template <class S>
379
  V8_INLINE Global(Isolate* isolate, Local<S> that)
380
3.89M
      : PersistentBase<T>(
381
3.89M
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
3.89M
    static_assert(std::is_base_of<T, S>::value, "type check");
383
3.89M
  }
v8::Global<v8::Object>::Global<v8::Object>(v8::Isolate*, v8::Local<v8::Object>)
Line
Count
Source
380
1.19M
      : PersistentBase<T>(
381
1.19M
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
1.19M
    static_assert(std::is_base_of<T, S>::value, "type check");
383
1.19M
  }
v8::Global<v8::Int32Array>::Global<v8::Int32Array>(v8::Isolate*, v8::Local<v8::Int32Array>)
Line
Count
Source
380
403k
      : PersistentBase<T>(
381
403k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
403k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
403k
  }
v8::Global<v8::Uint32Array>::Global<v8::Uint32Array>(v8::Isolate*, v8::Local<v8::Uint32Array>)
Line
Count
Source
380
942k
      : PersistentBase<T>(
381
942k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
942k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
942k
  }
v8::Global<v8::Uint8Array>::Global<v8::Uint8Array>(v8::Isolate*, v8::Local<v8::Uint8Array>)
Line
Count
Source
380
403k
      : PersistentBase<T>(
381
403k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
403k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
403k
  }
v8::Global<v8::Float64Array>::Global<v8::Float64Array>(v8::Isolate*, v8::Local<v8::Float64Array>)
Line
Count
Source
380
672k
      : PersistentBase<T>(
381
672k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
672k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
672k
  }
v8::Global<v8::Value>::Global<v8::Value>(v8::Isolate*, v8::Local<v8::Value>)
Line
Count
Source
380
4
      : PersistentBase<T>(
381
4
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
4
    static_assert(std::is_base_of<T, S>::value, "type check");
383
4
  }
Unexecuted instantiation: v8::Global<v8::Module>::Global<v8::Module>(v8::Isolate*, v8::Local<v8::Module>)
v8::Global<v8::Context>::Global<v8::Context>(v8::Isolate*, v8::Local<v8::Context>)
Line
Count
Source
380
8.51k
      : PersistentBase<T>(
381
8.51k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
8.51k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
8.51k
  }
v8::Global<v8::BigInt64Array>::Global<v8::BigInt64Array>(v8::Isolate*, v8::Local<v8::BigInt64Array>)
Line
Count
Source
380
269k
      : PersistentBase<T>(
381
269k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
269k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
269k
  }
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>::Global<v8::ArrayBuffer>(v8::Isolate*, v8::Local<v8::ArrayBuffer>)
Unexecuted instantiation: v8::Global<v8::SharedArrayBuffer>::Global<v8::SharedArrayBuffer>(v8::Isolate*, v8::Local<v8::SharedArrayBuffer>)
Unexecuted instantiation: v8::Global<v8::Function>::Global<v8::Function>(v8::Isolate*, v8::Local<v8::Function>)
384
385
  /**
386
   * Construct a Global from a PersistentBase.
387
   * When the Persistent is non-empty, a new storage cell is created
388
   * pointing to the same object, and no flags are set.
389
   */
390
  template <class S>
391
  V8_INLINE Global(Isolate* isolate, const PersistentBase<S>& that)
392
      : PersistentBase<T>(
393
            PersistentBase<T>::New(isolate, that.template value<S>())) {
394
    static_assert(std::is_base_of<T, S>::value, "type check");
395
  }
396
397
  /**
398
   * Move constructor.
399
   */
400
  V8_INLINE Global(Global&& other);
401
402
15.7M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Object>::~Global()
Line
Count
Source
402
2.40M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Int32Array>::~Global()
Line
Count
Source
402
807k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint32Array>::~Global()
Line
Count
Source
402
1.88M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint8Array>::~Global()
Line
Count
Source
402
807k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Function>::~Global()
Line
Count
Source
402
7.53M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Array>::~Global()
Line
Count
Source
402
134k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Float64Array>::~Global()
Line
Count
Source
402
1.34M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Context>::~Global()
Line
Count
Source
402
281k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Value>::~Global()
Line
Count
Source
402
8.52k
  V8_INLINE ~Global() { this->Reset(); }
Unexecuted instantiation: v8::Global<v8::Module>::~Global()
Unexecuted instantiation: v8::Global<v8::Promise>::~Global()
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>::~Global()
v8::Global<v8::UnboundScript>::~Global()
Line
Count
Source
402
1.13k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::BigInt64Array>::~Global()
Line
Count
Source
402
538k
  V8_INLINE ~Global() { this->Reset(); }
Unexecuted instantiation: v8::Global<v8::SharedArrayBuffer>::~Global()
Unexecuted instantiation: v8::Global<v8::WasmMemoryObject>::~Global()
v8::Global<v8::ArrayBufferView>::~Global()
Line
Count
Source
402
847
  V8_INLINE ~Global() { this->Reset(); }
Unexecuted instantiation: v8::Global<v8::FunctionTemplate>::~Global()
403
404
  /**
405
   * Move via assignment.
406
   */
407
  template <class S>
408
  V8_INLINE Global& operator=(Global<S>&& rhs);
409
410
  /**
411
   * Pass allows returning uniques from functions, etc.
412
   */
413
  Global Pass() { return static_cast<Global&&>(*this); }
414
415
  /*
416
   * For compatibility with Chromium's base::Bind (base::Passed).
417
   */
418
  using MoveOnlyTypeForCPP03 = void;
419
420
  Global(const Global&) = delete;
421
  void operator=(const Global&) = delete;
422
423
 private:
424
  template <class F>
425
  friend class ReturnValue;
426
};
427
428
// UniquePersistent is an alias for Global for historical reason.
429
template <class T>
430
using UniquePersistent = Global<T>;
431
432
/**
433
 * Interface for iterating through all the persistent handles in the heap.
434
 */
435
class V8_EXPORT PersistentHandleVisitor {
436
 public:
437
  virtual ~PersistentHandleVisitor() = default;
438
  virtual void VisitPersistentHandle(Persistent<Value>* value,
439
0
                                     uint16_t class_id) {}
440
};
441
442
template <class T>
443
8.73M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
8.73M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
8.73M
  return api_internal::GlobalizeReference(
446
8.73M
      reinterpret_cast<internal::Isolate*>(isolate),
447
8.73M
      internal::ValueHelper::ValueAsAddress(that));
448
8.73M
}
v8::PersistentBase<v8::Value>::New(v8::Isolate*, v8::Value*)
Line
Count
Source
443
6.90k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
6.90k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
6.90k
  return api_internal::GlobalizeReference(
446
6.90k
      reinterpret_cast<internal::Isolate*>(isolate),
447
6.90k
      internal::ValueHelper::ValueAsAddress(that));
448
6.90k
}
v8::PersistentBase<v8::Array>::New(v8::Isolate*, v8::Array*)
Line
Count
Source
443
134k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
134k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
134k
  return api_internal::GlobalizeReference(
446
134k
      reinterpret_cast<internal::Isolate*>(isolate),
447
134k
      internal::ValueHelper::ValueAsAddress(that));
448
134k
}
v8::PersistentBase<v8::Object>::New(v8::Isolate*, v8::Object*)
Line
Count
Source
443
2.26M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
2.26M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
2.26M
  return api_internal::GlobalizeReference(
446
2.26M
      reinterpret_cast<internal::Isolate*>(isolate),
447
2.26M
      internal::ValueHelper::ValueAsAddress(that));
448
2.26M
}
v8::PersistentBase<v8::Function>::New(v8::Isolate*, v8::Function*)
Line
Count
Source
443
3.35M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
3.35M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
3.35M
  return api_internal::GlobalizeReference(
446
3.35M
      reinterpret_cast<internal::Isolate*>(isolate),
447
3.35M
      internal::ValueHelper::ValueAsAddress(that));
448
3.35M
}
v8::PersistentBase<v8::Context>::New(v8::Isolate*, v8::Context*)
Line
Count
Source
443
279k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
279k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
279k
  return api_internal::GlobalizeReference(
446
279k
      reinterpret_cast<internal::Isolate*>(isolate),
447
279k
      internal::ValueHelper::ValueAsAddress(that));
448
279k
}
v8::PersistentBase<v8::Int32Array>::New(v8::Isolate*, v8::Int32Array*)
Line
Count
Source
443
403k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
403k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
403k
  return api_internal::GlobalizeReference(
446
403k
      reinterpret_cast<internal::Isolate*>(isolate),
447
403k
      internal::ValueHelper::ValueAsAddress(that));
448
403k
}
v8::PersistentBase<v8::Uint32Array>::New(v8::Isolate*, v8::Uint32Array*)
Line
Count
Source
443
942k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
942k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
942k
  return api_internal::GlobalizeReference(
446
942k
      reinterpret_cast<internal::Isolate*>(isolate),
447
942k
      internal::ValueHelper::ValueAsAddress(that));
448
942k
}
v8::PersistentBase<v8::Uint8Array>::New(v8::Isolate*, v8::Uint8Array*)
Line
Count
Source
443
403k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
403k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
403k
  return api_internal::GlobalizeReference(
446
403k
      reinterpret_cast<internal::Isolate*>(isolate),
447
403k
      internal::ValueHelper::ValueAsAddress(that));
448
403k
}
v8::PersistentBase<v8::Float64Array>::New(v8::Isolate*, v8::Float64Array*)
Line
Count
Source
443
672k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
672k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
672k
  return api_internal::GlobalizeReference(
446
672k
      reinterpret_cast<internal::Isolate*>(isolate),
447
672k
      internal::ValueHelper::ValueAsAddress(that));
448
672k
}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::New(v8::Isolate*, v8::Module*)
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::New(v8::Isolate*, v8::Promise*)
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::New(v8::Isolate*, v8::ArrayBuffer*)
v8::PersistentBase<v8::UnboundScript>::New(v8::Isolate*, v8::UnboundScript*)
Line
Count
Source
443
1.13k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
1.13k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
1.13k
  return api_internal::GlobalizeReference(
446
1.13k
      reinterpret_cast<internal::Isolate*>(isolate),
447
1.13k
      internal::ValueHelper::ValueAsAddress(that));
448
1.13k
}
v8::PersistentBase<v8::BigInt64Array>::New(v8::Isolate*, v8::BigInt64Array*)
Line
Count
Source
443
269k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
269k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
269k
  return api_internal::GlobalizeReference(
446
269k
      reinterpret_cast<internal::Isolate*>(isolate),
447
269k
      internal::ValueHelper::ValueAsAddress(that));
448
269k
}
Unexecuted instantiation: v8::PersistentBase<v8::SharedArrayBuffer>::New(v8::Isolate*, v8::SharedArrayBuffer*)
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::New(v8::Isolate*, v8::WasmMemoryObject*)
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBufferView>::New(v8::Isolate*, v8::ArrayBufferView*)
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::New(v8::Isolate*, v8::FunctionTemplate*)
449
450
template <class T, class M>
451
template <class S, class M2>
452
void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
453
  static_assert(std::is_base_of<T, S>::value, "type check");
454
  this->Reset();
455
  if (that.IsEmpty()) return;
456
  this->slot() = api_internal::CopyGlobalReference(that.slot());
457
  M::Copy(that, this);
458
}
459
460
template <class T>
461
2.61M
bool PersistentBase<T>::IsWeak() const {
462
2.61M
  using I = internal::Internals;
463
2.61M
  if (this->IsEmpty()) return false;
464
2.61M
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
2.61M
}
Unexecuted instantiation: v8::PersistentBase<v8::Int8Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Uint8Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Int16Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Uint16Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Int32Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Uint32Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Float32Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Float64Array>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::BigInt64Array>::IsWeak() const
v8::PersistentBase<v8::Object>::IsWeak() const
Line
Count
Source
461
2.60M
bool PersistentBase<T>::IsWeak() const {
462
2.60M
  using I = internal::Internals;
463
2.60M
  if (this->IsEmpty()) return false;
464
2.60M
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
2.60M
}
Unexecuted instantiation: v8::PersistentBase<v8::Function>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::IsWeak() const
v8::PersistentBase<v8::Context>::IsWeak() const
Line
Count
Source
461
14.7k
bool PersistentBase<T>::IsWeak() const {
462
14.7k
  using I = internal::Internals;
463
14.7k
  if (this->IsEmpty()) return false;
464
14.7k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
14.7k
}
v8::PersistentBase<v8::UnboundScript>::IsWeak() const
Line
Count
Source
461
1.13k
bool PersistentBase<T>::IsWeak() const {
462
1.13k
  using I = internal::Internals;
463
1.13k
  if (this->IsEmpty()) return false;
464
1.13k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
1.13k
}
Unexecuted instantiation: v8::PersistentBase<v8::Value>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBufferView>::IsWeak() const
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::IsWeak() const
466
467
template <class T>
468
24.2M
void PersistentBase<T>::Reset() {
469
24.2M
  if (this->IsEmpty()) return;
470
8.73M
  api_internal::DisposeGlobal(this->slot());
471
8.73M
  this->Clear();
472
8.73M
}
v8::PersistentBase<v8::Value>::Reset()
Line
Count
Source
468
15.4k
void PersistentBase<T>::Reset() {
469
15.4k
  if (this->IsEmpty()) return;
470
6.90k
  api_internal::DisposeGlobal(this->slot());
471
6.90k
  this->Clear();
472
6.90k
}
v8::PersistentBase<v8::Array>::Reset()
Line
Count
Source
468
269k
void PersistentBase<T>::Reset() {
469
269k
  if (this->IsEmpty()) return;
470
134k
  api_internal::DisposeGlobal(this->slot());
471
134k
  this->Clear();
472
134k
}
v8::PersistentBase<v8::Object>::Reset()
Line
Count
Source
468
3.48M
void PersistentBase<T>::Reset() {
469
3.48M
  if (this->IsEmpty()) return;
470
2.26M
  api_internal::DisposeGlobal(this->slot());
471
2.26M
  this->Clear();
472
2.26M
}
v8::PersistentBase<v8::Int32Array>::Reset()
Line
Count
Source
468
1.21M
void PersistentBase<T>::Reset() {
469
1.21M
  if (this->IsEmpty()) return;
470
403k
  api_internal::DisposeGlobal(this->slot());
471
403k
  this->Clear();
472
403k
}
v8::PersistentBase<v8::Uint32Array>::Reset()
Line
Count
Source
468
2.82M
void PersistentBase<T>::Reset() {
469
2.82M
  if (this->IsEmpty()) return;
470
942k
  api_internal::DisposeGlobal(this->slot());
471
942k
  this->Clear();
472
942k
}
v8::PersistentBase<v8::Uint8Array>::Reset()
Line
Count
Source
468
1.21M
void PersistentBase<T>::Reset() {
469
1.21M
  if (this->IsEmpty()) return;
470
403k
  api_internal::DisposeGlobal(this->slot());
471
403k
  this->Clear();
472
403k
}
v8::PersistentBase<v8::Function>::Reset()
Line
Count
Source
468
11.6M
void PersistentBase<T>::Reset() {
469
11.6M
  if (this->IsEmpty()) return;
470
3.35M
  api_internal::DisposeGlobal(this->slot());
471
3.35M
  this->Clear();
472
3.35M
}
v8::PersistentBase<v8::Float64Array>::Reset()
Line
Count
Source
468
2.01M
void PersistentBase<T>::Reset() {
469
2.01M
  if (this->IsEmpty()) return;
470
672k
  api_internal::DisposeGlobal(this->slot());
471
672k
  this->Clear();
472
672k
}
v8::PersistentBase<v8::Context>::Reset()
Line
Count
Source
468
689k
void PersistentBase<T>::Reset() {
469
689k
  if (this->IsEmpty()) return;
470
279k
  api_internal::DisposeGlobal(this->slot());
471
279k
  this->Clear();
472
279k
}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::Reset()
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::Reset()
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::Reset()
v8::PersistentBase<v8::UnboundScript>::Reset()
Line
Count
Source
468
2.27k
void PersistentBase<T>::Reset() {
469
2.27k
  if (this->IsEmpty()) return;
470
1.13k
  api_internal::DisposeGlobal(this->slot());
471
1.13k
  this->Clear();
472
1.13k
}
v8::PersistentBase<v8::BigInt64Array>::Reset()
Line
Count
Source
468
807k
void PersistentBase<T>::Reset() {
469
807k
  if (this->IsEmpty()) return;
470
269k
  api_internal::DisposeGlobal(this->slot());
471
269k
  this->Clear();
472
269k
}
Unexecuted instantiation: v8::PersistentBase<v8::SharedArrayBuffer>::Reset()
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::Reset()
v8::PersistentBase<v8::ArrayBufferView>::Reset()
Line
Count
Source
468
847
void PersistentBase<T>::Reset() {
469
847
  if (this->IsEmpty()) return;
470
0
  api_internal::DisposeGlobal(this->slot());
471
0
  this->Clear();
472
0
}
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::Reset()
473
474
/**
475
 * If non-empty, destroy the underlying storage cell
476
 * and create a new one with the contents of other if other is non empty
477
 */
478
template <class T>
479
template <class S>
480
5.64M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
5.64M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
5.64M
  Reset();
483
5.64M
  if (other.IsEmpty()) return;
484
4.84M
  this->slot() = New(isolate, *other);
485
4.84M
}
void v8::PersistentBase<v8::Array>::Reset<v8::Array>(v8::Isolate*, v8::Local<v8::Array> const&)
Line
Count
Source
480
134k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
134k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
134k
  Reset();
483
134k
  if (other.IsEmpty()) return;
484
134k
  this->slot() = New(isolate, *other);
485
134k
}
void v8::PersistentBase<v8::Object>::Reset<v8::Object>(v8::Isolate*, v8::Local<v8::Object> const&)
Line
Count
Source
480
1.07M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
1.07M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
1.07M
  Reset();
483
1.07M
  if (other.IsEmpty()) return;
484
1.07M
  this->slot() = New(isolate, *other);
485
1.07M
}
void v8::PersistentBase<v8::Function>::Reset<v8::Function>(v8::Isolate*, v8::Local<v8::Function> const&)
Line
Count
Source
480
4.15M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
4.15M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
4.15M
  Reset();
483
4.15M
  if (other.IsEmpty()) return;
484
3.35M
  this->slot() = New(isolate, *other);
485
3.35M
}
void v8::PersistentBase<v8::Context>::Reset<v8::Context>(v8::Isolate*, v8::Local<v8::Context> const&)
Line
Count
Source
480
271k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
271k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
271k
  Reset();
483
271k
  if (other.IsEmpty()) return;
484
271k
  this->slot() = New(isolate, *other);
485
271k
}
Unexecuted instantiation: void v8::PersistentBase<v8::Uint32Array>::Reset<v8::Uint32Array>(v8::Isolate*, v8::Local<v8::Uint32Array> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Uint8Array>::Reset<v8::Uint8Array>(v8::Isolate*, v8::Local<v8::Uint8Array> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Float64Array>::Reset<v8::Float64Array>(v8::Isolate*, v8::Local<v8::Float64Array> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Int32Array>::Reset<v8::Int32Array>(v8::Isolate*, v8::Local<v8::Int32Array> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Promise>::Reset<v8::Promise>(v8::Isolate*, v8::Local<v8::Promise> const&)
void v8::PersistentBase<v8::Value>::Reset<v8::Value>(v8::Isolate*, v8::Local<v8::Value> const&)
Line
Count
Source
480
6.90k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
6.90k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
6.90k
  Reset();
483
6.90k
  if (other.IsEmpty()) return;
484
6.90k
  this->slot() = New(isolate, *other);
485
6.90k
}
Unexecuted instantiation: void v8::PersistentBase<v8::ArrayBuffer>::Reset<v8::ArrayBuffer>(v8::Isolate*, v8::Local<v8::ArrayBuffer> const&)
void v8::PersistentBase<v8::UnboundScript>::Reset<v8::UnboundScript>(v8::Isolate*, v8::Local<v8::UnboundScript> const&)
Line
Count
Source
480
1.13k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
1.13k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
1.13k
  Reset();
483
1.13k
  if (other.IsEmpty()) return;
484
1.13k
  this->slot() = New(isolate, *other);
485
1.13k
}
Unexecuted instantiation: void v8::PersistentBase<v8::BigInt64Array>::Reset<v8::BigInt64Array>(v8::Isolate*, v8::Local<v8::BigInt64Array> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::WasmMemoryObject>::Reset<v8::WasmMemoryObject>(v8::Isolate*, v8::Local<v8::WasmMemoryObject> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::ArrayBufferView>::Reset<v8::ArrayBufferView>(v8::Isolate*, v8::Local<v8::ArrayBufferView> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Value>::Reset<v8::External>(v8::Isolate*, v8::Local<v8::External> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::Value>::Reset<v8::Promise::Resolver>(v8::Isolate*, v8::Local<v8::Promise::Resolver> const&)
Unexecuted instantiation: void v8::PersistentBase<v8::FunctionTemplate>::Reset<v8::FunctionTemplate>(v8::Isolate*, v8::Local<v8::FunctionTemplate> const&)
486
487
/**
488
 * If non-empty, destroy the underlying storage cell
489
 * and create a new one with the contents of other if other is non empty
490
 */
491
template <class T>
492
template <class S>
493
void PersistentBase<T>::Reset(Isolate* isolate,
494
                              const PersistentBase<S>& other) {
495
  static_assert(std::is_base_of<T, S>::value, "type check");
496
  Reset();
497
  if (other.IsEmpty()) return;
498
  this->slot() = New(isolate, other.template value<S>());
499
}
500
501
template <class T>
502
template <typename P>
503
V8_INLINE void PersistentBase<T>::SetWeak(
504
    P* parameter, typename WeakCallbackInfo<P>::Callback callback,
505
1.24M
    WeakCallbackType type) {
506
1.24M
  using Callback = WeakCallbackInfo<void>::Callback;
507
#if (__GNUC__ >= 8) && !defined(__clang__)
508
#pragma GCC diagnostic push
509
#pragma GCC diagnostic ignored "-Wcast-function-type"
510
#endif
511
1.24M
  api_internal::MakeWeak(this->slot(), parameter,
512
1.24M
                         reinterpret_cast<Callback>(callback), type);
513
#if (__GNUC__ >= 8) && !defined(__clang__)
514
#pragma GCC diagnostic pop
515
#endif
516
1.24M
}
Unexecuted instantiation: void v8::PersistentBase<v8::Object>::SetWeak<node::DestroyParam>(node::DestroyParam*, v8::WeakCallbackInfo<node::DestroyParam>::Callback, v8::WeakCallbackType)
void v8::PersistentBase<v8::Object>::SetWeak<node::BaseObject>(node::BaseObject*, v8::WeakCallbackInfo<node::BaseObject>::Callback, v8::WeakCallbackType)
Line
Count
Source
505
1.24M
    WeakCallbackType type) {
506
1.24M
  using Callback = WeakCallbackInfo<void>::Callback;
507
#if (__GNUC__ >= 8) && !defined(__clang__)
508
#pragma GCC diagnostic push
509
#pragma GCC diagnostic ignored "-Wcast-function-type"
510
#endif
511
1.24M
  api_internal::MakeWeak(this->slot(), parameter,
512
1.24M
                         reinterpret_cast<Callback>(callback), type);
513
#if (__GNUC__ >= 8) && !defined(__clang__)
514
#pragma GCC diagnostic pop
515
#endif
516
1.24M
}
Unexecuted instantiation: node_api.cc:void v8::PersistentBase<v8::Object>::SetWeak<v8impl::(anonymous namespace)::AsyncContext>(v8impl::(anonymous namespace)::AsyncContext*, v8::WeakCallbackInfo<v8impl::(anonymous namespace)::AsyncContext>::Callback, v8::WeakCallbackType)
Unexecuted instantiation: void v8::PersistentBase<v8::Context>::SetWeak<node::shadow_realm::ShadowRealm>(node::shadow_realm::ShadowRealm*, v8::WeakCallbackInfo<node::shadow_realm::ShadowRealm>::Callback, v8::WeakCallbackType)
Unexecuted instantiation: void v8::PersistentBase<v8::Value>::SetWeak<v8impl::ExternalWrapper>(v8impl::ExternalWrapper*, v8::WeakCallbackInfo<v8impl::ExternalWrapper>::Callback, v8::WeakCallbackType)
Unexecuted instantiation: void v8::PersistentBase<v8::Value>::SetWeak<v8impl::Reference>(v8impl::Reference*, v8::WeakCallbackInfo<v8impl::Reference>::Callback, v8::WeakCallbackType)
517
518
template <class T>
519
1.21M
void PersistentBase<T>::SetWeak() {
520
1.21M
  api_internal::MakeWeak(&this->slot());
521
1.21M
}
v8::PersistentBase<v8::Context>::SetWeak()
Line
Count
Source
519
136k
void PersistentBase<T>::SetWeak() {
520
136k
  api_internal::MakeWeak(&this->slot());
521
136k
}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::SetWeak()
v8::PersistentBase<v8::UnboundScript>::SetWeak()
Line
Count
Source
519
1.13k
void PersistentBase<T>::SetWeak() {
520
1.13k
  api_internal::MakeWeak(&this->slot());
521
1.13k
}
v8::PersistentBase<v8::Float64Array>::SetWeak()
Line
Count
Source
519
269k
void PersistentBase<T>::SetWeak() {
520
269k
  api_internal::MakeWeak(&this->slot());
521
269k
}
v8::PersistentBase<v8::BigInt64Array>::SetWeak()
Line
Count
Source
519
269k
void PersistentBase<T>::SetWeak() {
520
269k
  api_internal::MakeWeak(&this->slot());
521
269k
}
v8::PersistentBase<v8::Uint32Array>::SetWeak()
Line
Count
Source
519
403k
void PersistentBase<T>::SetWeak() {
520
403k
  api_internal::MakeWeak(&this->slot());
521
403k
}
Unexecuted instantiation: v8::PersistentBase<v8::Function>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::Object>::SetWeak()
v8::PersistentBase<v8::Uint8Array>::SetWeak()
Line
Count
Source
519
134k
void PersistentBase<T>::SetWeak() {
520
134k
  api_internal::MakeWeak(&this->slot());
521
134k
}
522
523
template <class T>
524
template <typename P>
525
116k
P* PersistentBase<T>::ClearWeak() {
526
116k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
116k
}
void* v8::PersistentBase<v8::Object>::ClearWeak<void>()
Line
Count
Source
525
116k
P* PersistentBase<T>::ClearWeak() {
526
116k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
116k
}
Unexecuted instantiation: void* v8::PersistentBase<v8::Value>::ClearWeak<void>()
528
529
template <class T>
530
void PersistentBase<T>::AnnotateStrongRetainer(const char* label) {
531
  api_internal::AnnotateStrongRetainer(this->slot(), label);
532
}
533
534
template <class T>
535
void PersistentBase<T>::SetWrapperClassId(uint16_t class_id) {
536
  using I = internal::Internals;
537
  if (this->IsEmpty()) return;
538
  uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
539
  *reinterpret_cast<uint16_t*>(addr) = class_id;
540
}
541
542
template <class T>
543
uint16_t PersistentBase<T>::WrapperClassId() const {
544
  using I = internal::Internals;
545
  if (this->IsEmpty()) return 0;
546
  uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
547
  return *reinterpret_cast<uint16_t*>(addr);
548
}
549
550
template <class T>
551
1.14k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.14k
  if (!other.IsEmpty()) {
553
1.14k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.14k
    other.Clear();
555
1.14k
  }
556
1.14k
}
Unexecuted instantiation: v8::Global<v8::Object>::Global(v8::Global<v8::Object>&&)
v8::Global<v8::Context>::Global(v8::Global<v8::Context>&&)
Line
Count
Source
551
1.13k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.13k
  if (!other.IsEmpty()) {
553
1.13k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.13k
    other.Clear();
555
1.13k
  }
556
1.13k
}
v8::Global<v8::Value>::Global(v8::Global<v8::Value>&&)
Line
Count
Source
551
4
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
4
  if (!other.IsEmpty()) {
553
4
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
4
    other.Clear();
555
4
  }
556
4
}
Unexecuted instantiation: v8::Global<v8::SharedArrayBuffer>::Global(v8::Global<v8::SharedArrayBuffer>&&)
557
558
template <class T>
559
template <class S>
560
2.69M
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
2.69M
  static_assert(std::is_base_of<T, S>::value, "type check");
562
2.69M
  if (this != &rhs) {
563
2.69M
    this->Reset();
564
2.69M
    if (!rhs.IsEmpty()) {
565
2.69M
      this->slot() = rhs.slot();
566
2.69M
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
2.69M
      rhs.Clear();
568
2.69M
    }
569
2.69M
  }
570
2.69M
  return *this;
571
2.69M
}
Unexecuted instantiation: v8::Global<v8::Context>& v8::Global<v8::Context>::operator=<v8::Context>(v8::Global<v8::Context>&&)
v8::Global<v8::Int32Array>& v8::Global<v8::Int32Array>::operator=<v8::Int32Array>(v8::Global<v8::Int32Array>&&)
Line
Count
Source
560
403k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
403k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
403k
  if (this != &rhs) {
563
403k
    this->Reset();
564
403k
    if (!rhs.IsEmpty()) {
565
403k
      this->slot() = rhs.slot();
566
403k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
403k
      rhs.Clear();
568
403k
    }
569
403k
  }
570
403k
  return *this;
571
403k
}
v8::Global<v8::Uint32Array>& v8::Global<v8::Uint32Array>::operator=<v8::Uint32Array>(v8::Global<v8::Uint32Array>&&)
Line
Count
Source
560
942k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
942k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
942k
  if (this != &rhs) {
563
942k
    this->Reset();
564
942k
    if (!rhs.IsEmpty()) {
565
942k
      this->slot() = rhs.slot();
566
942k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
942k
      rhs.Clear();
568
942k
    }
569
942k
  }
570
942k
  return *this;
571
942k
}
v8::Global<v8::Uint8Array>& v8::Global<v8::Uint8Array>::operator=<v8::Uint8Array>(v8::Global<v8::Uint8Array>&&)
Line
Count
Source
560
403k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
403k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
403k
  if (this != &rhs) {
563
403k
    this->Reset();
564
403k
    if (!rhs.IsEmpty()) {
565
403k
      this->slot() = rhs.slot();
566
403k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
403k
      rhs.Clear();
568
403k
    }
569
403k
  }
570
403k
  return *this;
571
403k
}
v8::Global<v8::Float64Array>& v8::Global<v8::Float64Array>::operator=<v8::Float64Array>(v8::Global<v8::Float64Array>&&)
Line
Count
Source
560
672k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
672k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
672k
  if (this != &rhs) {
563
672k
    this->Reset();
564
672k
    if (!rhs.IsEmpty()) {
565
672k
      this->slot() = rhs.slot();
566
672k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
672k
      rhs.Clear();
568
672k
    }
569
672k
  }
570
672k
  return *this;
571
672k
}
v8::Global<v8::BigInt64Array>& v8::Global<v8::BigInt64Array>::operator=<v8::BigInt64Array>(v8::Global<v8::BigInt64Array>&&)
Line
Count
Source
560
269k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
269k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
269k
  if (this != &rhs) {
563
269k
    this->Reset();
564
269k
    if (!rhs.IsEmpty()) {
565
269k
      this->slot() = rhs.slot();
566
269k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
269k
      rhs.Clear();
568
269k
    }
569
269k
  }
570
269k
  return *this;
571
269k
}
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>& v8::Global<v8::ArrayBuffer>::operator=<v8::ArrayBuffer>(v8::Global<v8::ArrayBuffer>&&)
572
573
}  // namespace v8
574
575
#endif  // INCLUDE_V8_PERSISTENT_HANDLE_H_