Coverage Report

Created: 2025-09-05 10:05

/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
64.4M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Private>::Eternal()
Line
Count
Source
49
9.54M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Symbol>::Eternal()
Line
Count
Source
49
2.29M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::String>::Eternal()
Line
Count
Source
49
44.5M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::FunctionTemplate>::Eternal()
Line
Count
Source
49
3.31M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::ObjectTemplate>::Eternal()
Line
Count
Source
49
4.71M
  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
130M
  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
130M
    return Local<T>::FromSlot(slot());
61
130M
  }
v8::Eternal<v8::String>::Get(v8::Isolate*) const
Line
Count
Source
57
115M
  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
115M
    return Local<T>::FromSlot(slot());
61
115M
  }
v8::Eternal<v8::Private>::Get(v8::Isolate*) const
Line
Count
Source
57
3.17M
  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.17M
    return Local<T>::FromSlot(slot());
61
3.17M
  }
v8::Eternal<v8::Symbol>::Get(v8::Isolate*) const
Line
Count
Source
57
5.01M
  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.01M
    return Local<T>::FromSlot(slot());
61
5.01M
  }
v8::Eternal<v8::FunctionTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
2.74M
  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.74M
    return Local<T>::FromSlot(slot());
61
2.74M
  }
v8::Eternal<v8::ObjectTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
4.69M
  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.69M
    return Local<T>::FromSlot(slot());
61
4.69M
  }
62
63
  template <class S>
64
61.4M
  void Set(Isolate* isolate, Local<S> handle) {
65
61.4M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
61.4M
    slot() =
67
61.4M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
61.4M
  }
void v8::Eternal<v8::FunctionTemplate>::Set<v8::FunctionTemplate>(v8::Isolate*, v8::Local<v8::FunctionTemplate>)
Line
Count
Source
64
1.16M
  void Set(Isolate* isolate, Local<S> handle) {
65
1.16M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
1.16M
    slot() =
67
1.16M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
1.16M
  }
void v8::Eternal<v8::ObjectTemplate>::Set<v8::ObjectTemplate>(v8::Isolate*, v8::Local<v8::ObjectTemplate>)
Line
Count
Source
64
3.86M
  void Set(Isolate* isolate, Local<S> handle) {
65
3.86M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
3.86M
    slot() =
67
3.86M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
3.86M
  }
void v8::Eternal<v8::Private>::Set<v8::Private>(v8::Isolate*, v8::Local<v8::Private>)
Line
Count
Source
64
9.54M
  void Set(Isolate* isolate, Local<S> handle) {
65
9.54M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
9.54M
    slot() =
67
9.54M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
9.54M
  }
void v8::Eternal<v8::Symbol>::Set<v8::Symbol>(v8::Isolate*, v8::Local<v8::Symbol>)
Line
Count
Source
64
2.29M
  void Set(Isolate* isolate, Local<S> handle) {
65
2.29M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
2.29M
    slot() =
67
2.29M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
2.29M
  }
void v8::Eternal<v8::String>::Set<v8::String>(v8::Isolate*, v8::Local<v8::String>)
Line
Count
Source
64
44.5M
  void Set(Isolate* isolate, Local<S> handle) {
65
44.5M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
44.5M
    slot() =
67
44.5M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
44.5M
  }
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.63M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
2.63M
    return Local<T>::New(isolate, *this);
115
2.63M
  }
Unexecuted instantiation: v8::PersistentBase<v8::Int8Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Uint8Array>::Get(v8::Isolate*) const
Line
Count
Source
113
509k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
509k
    return Local<T>::New(isolate, *this);
115
509k
  }
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
340k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
340k
    return Local<T>::New(isolate, *this);
115
340k
  }
v8::PersistentBase<v8::Uint32Array>::Get(v8::Isolate*) const
Line
Count
Source
113
891k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
891k
    return Local<T>::New(isolate, *this);
115
891k
  }
Unexecuted instantiation: v8::PersistentBase<v8::Float32Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Float64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
636k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
636k
    return Local<T>::New(isolate, *this);
115
636k
  }
v8::PersistentBase<v8::BigInt64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
254k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
254k
    return Local<T>::New(isolate, *this);
115
254k
  }
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
110k
  V8_INLINE void ClearWeak() { ClearWeak<void>(); }
v8::PersistentBase<v8::Object>::ClearWeak()
Line
Count
Source
165
110k
  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.2M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Object>::PersistentBase()
Line
Count
Source
212
1.14M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Array>::PersistentBase()
Line
Count
Source
212
127k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Function>::PersistentBase()
Line
Count
Source
212
7.12M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Context>::PersistentBase()
Line
Count
Source
212
257k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Int32Array>::PersistentBase()
Line
Count
Source
212
381k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint32Array>::PersistentBase()
Line
Count
Source
212
891k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint8Array>::PersistentBase()
Line
Count
Source
212
381k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Float64Array>::PersistentBase()
Line
Count
Source
212
636k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::PersistentBase()
v8::PersistentBase<v8::Value>::PersistentBase()
Line
Count
Source
212
7.71k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::PersistentBase()
v8::PersistentBase<v8::UnboundScript>::PersistentBase()
Line
Count
Source
212
1.27k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::BigInt64Array>::PersistentBase()
Line
Count
Source
212
254k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::PersistentBase()
v8::PersistentBase<v8::ArrayBufferView>::PersistentBase()
Line
Count
Source
212
810
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::PersistentBase()
213
214
  V8_INLINE explicit PersistentBase(internal::Address* location)
215
3.68M
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Object>::PersistentBase(unsigned long*)
Line
Count
Source
215
1.12M
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Context>::PersistentBase(unsigned long*)
Line
Count
Source
215
8.98k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Int32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
381k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
891k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint8Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
381k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Float64Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
636k
      : 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
254k
      : 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.2M
  V8_INLINE Global() = default;
v8::Global<v8::Object>::Global()
Line
Count
Source
371
1.14M
  V8_INLINE Global() = default;
v8::Global<v8::Array>::Global()
Line
Count
Source
371
127k
  V8_INLINE Global() = default;
v8::Global<v8::Function>::Global()
Line
Count
Source
371
7.12M
  V8_INLINE Global() = default;
v8::Global<v8::Context>::Global()
Line
Count
Source
371
257k
  V8_INLINE Global() = default;
v8::Global<v8::Int32Array>::Global()
Line
Count
Source
371
381k
  V8_INLINE Global() = default;
v8::Global<v8::Uint32Array>::Global()
Line
Count
Source
371
891k
  V8_INLINE Global() = default;
v8::Global<v8::Uint8Array>::Global()
Line
Count
Source
371
381k
  V8_INLINE Global() = default;
v8::Global<v8::Float64Array>::Global()
Line
Count
Source
371
636k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::Promise>::Global()
v8::Global<v8::Value>::Global()
Line
Count
Source
371
7.71k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>::Global()
v8::Global<v8::UnboundScript>::Global()
Line
Count
Source
371
1.27k
  V8_INLINE Global() = default;
v8::Global<v8::BigInt64Array>::Global()
Line
Count
Source
371
254k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::WasmMemoryObject>::Global()
v8::Global<v8::ArrayBufferView>::Global()
Line
Count
Source
371
810
  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.68M
      : PersistentBase<T>(
381
3.68M
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
3.68M
    static_assert(std::is_base_of<T, S>::value, "type check");
383
3.68M
  }
v8::Global<v8::Object>::Global<v8::Object>(v8::Isolate*, v8::Local<v8::Object>)
Line
Count
Source
380
1.12M
      : PersistentBase<T>(
381
1.12M
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
1.12M
    static_assert(std::is_base_of<T, S>::value, "type check");
383
1.12M
  }
v8::Global<v8::Int32Array>::Global<v8::Int32Array>(v8::Isolate*, v8::Local<v8::Int32Array>)
Line
Count
Source
380
381k
      : PersistentBase<T>(
381
381k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
381k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
381k
  }
v8::Global<v8::Uint32Array>::Global<v8::Uint32Array>(v8::Isolate*, v8::Local<v8::Uint32Array>)
Line
Count
Source
380
891k
      : PersistentBase<T>(
381
891k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
891k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
891k
  }
v8::Global<v8::Uint8Array>::Global<v8::Uint8Array>(v8::Isolate*, v8::Local<v8::Uint8Array>)
Line
Count
Source
380
381k
      : PersistentBase<T>(
381
381k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
381k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
381k
  }
v8::Global<v8::Float64Array>::Global<v8::Float64Array>(v8::Isolate*, v8::Local<v8::Float64Array>)
Line
Count
Source
380
636k
      : PersistentBase<T>(
381
636k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
636k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
636k
  }
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
7.71k
      : PersistentBase<T>(
381
7.71k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
7.71k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
7.71k
  }
v8::Global<v8::BigInt64Array>::Global<v8::BigInt64Array>(v8::Isolate*, v8::Local<v8::BigInt64Array>)
Line
Count
Source
380
254k
      : PersistentBase<T>(
381
254k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
254k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
254k
  }
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
14.8M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Object>::~Global()
Line
Count
Source
402
2.27M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Int32Array>::~Global()
Line
Count
Source
402
763k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint32Array>::~Global()
Line
Count
Source
402
1.78M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint8Array>::~Global()
Line
Count
Source
402
763k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Function>::~Global()
Line
Count
Source
402
7.12M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Array>::~Global()
Line
Count
Source
402
127k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Float64Array>::~Global()
Line
Count
Source
402
1.27M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Context>::~Global()
Line
Count
Source
402
266k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Value>::~Global()
Line
Count
Source
402
7.72k
  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.27k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::BigInt64Array>::~Global()
Line
Count
Source
402
509k
  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
810
  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.26M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
8.26M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
8.26M
  return api_internal::GlobalizeReference(
446
8.26M
      reinterpret_cast<internal::Isolate*>(isolate),
447
8.26M
      internal::ValueHelper::ValueAsAddress(that));
448
8.26M
}
v8::PersistentBase<v8::Value>::New(v8::Isolate*, v8::Value*)
Line
Count
Source
443
6.06k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
6.06k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
6.06k
  return api_internal::GlobalizeReference(
446
6.06k
      reinterpret_cast<internal::Isolate*>(isolate),
447
6.06k
      internal::ValueHelper::ValueAsAddress(that));
448
6.06k
}
v8::PersistentBase<v8::Array>::New(v8::Isolate*, v8::Array*)
Line
Count
Source
443
127k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
127k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
127k
  return api_internal::GlobalizeReference(
446
127k
      reinterpret_cast<internal::Isolate*>(isolate),
447
127k
      internal::ValueHelper::ValueAsAddress(that));
448
127k
}
v8::PersistentBase<v8::Object>::New(v8::Isolate*, v8::Object*)
Line
Count
Source
443
2.14M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
2.14M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
2.14M
  return api_internal::GlobalizeReference(
446
2.14M
      reinterpret_cast<internal::Isolate*>(isolate),
447
2.14M
      internal::ValueHelper::ValueAsAddress(that));
448
2.14M
}
v8::PersistentBase<v8::Function>::New(v8::Isolate*, v8::Function*)
Line
Count
Source
443
3.16M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
3.16M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
3.16M
  return api_internal::GlobalizeReference(
446
3.16M
      reinterpret_cast<internal::Isolate*>(isolate),
447
3.16M
      internal::ValueHelper::ValueAsAddress(that));
448
3.16M
}
v8::PersistentBase<v8::Context>::New(v8::Isolate*, v8::Context*)
Line
Count
Source
443
264k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
264k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
264k
  return api_internal::GlobalizeReference(
446
264k
      reinterpret_cast<internal::Isolate*>(isolate),
447
264k
      internal::ValueHelper::ValueAsAddress(that));
448
264k
}
v8::PersistentBase<v8::Int32Array>::New(v8::Isolate*, v8::Int32Array*)
Line
Count
Source
443
381k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
381k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
381k
  return api_internal::GlobalizeReference(
446
381k
      reinterpret_cast<internal::Isolate*>(isolate),
447
381k
      internal::ValueHelper::ValueAsAddress(that));
448
381k
}
v8::PersistentBase<v8::Uint32Array>::New(v8::Isolate*, v8::Uint32Array*)
Line
Count
Source
443
891k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
891k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
891k
  return api_internal::GlobalizeReference(
446
891k
      reinterpret_cast<internal::Isolate*>(isolate),
447
891k
      internal::ValueHelper::ValueAsAddress(that));
448
891k
}
v8::PersistentBase<v8::Uint8Array>::New(v8::Isolate*, v8::Uint8Array*)
Line
Count
Source
443
381k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
381k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
381k
  return api_internal::GlobalizeReference(
446
381k
      reinterpret_cast<internal::Isolate*>(isolate),
447
381k
      internal::ValueHelper::ValueAsAddress(that));
448
381k
}
v8::PersistentBase<v8::Float64Array>::New(v8::Isolate*, v8::Float64Array*)
Line
Count
Source
443
636k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
636k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
636k
  return api_internal::GlobalizeReference(
446
636k
      reinterpret_cast<internal::Isolate*>(isolate),
447
636k
      internal::ValueHelper::ValueAsAddress(that));
448
636k
}
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.27k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
1.27k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
1.27k
  return api_internal::GlobalizeReference(
446
1.27k
      reinterpret_cast<internal::Isolate*>(isolate),
447
1.27k
      internal::ValueHelper::ValueAsAddress(that));
448
1.27k
}
v8::PersistentBase<v8::BigInt64Array>::New(v8::Isolate*, v8::BigInt64Array*)
Line
Count
Source
443
254k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
254k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
254k
  return api_internal::GlobalizeReference(
446
254k
      reinterpret_cast<internal::Isolate*>(isolate),
447
254k
      internal::ValueHelper::ValueAsAddress(that));
448
254k
}
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.48M
bool PersistentBase<T>::IsWeak() const {
462
2.48M
  using I = internal::Internals;
463
2.48M
  if (this->IsEmpty()) return false;
464
2.48M
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
2.48M
}
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.46M
bool PersistentBase<T>::IsWeak() const {
462
2.46M
  using I = internal::Internals;
463
2.46M
  if (this->IsEmpty()) return false;
464
2.46M
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
2.46M
}
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
16.5k
bool PersistentBase<T>::IsWeak() const {
462
16.5k
  using I = internal::Internals;
463
16.5k
  if (this->IsEmpty()) return false;
464
16.5k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
16.5k
}
v8::PersistentBase<v8::UnboundScript>::IsWeak() const
Line
Count
Source
461
1.27k
bool PersistentBase<T>::IsWeak() const {
462
1.27k
  using I = internal::Internals;
463
1.27k
  if (this->IsEmpty()) return false;
464
1.27k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
1.27k
}
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
22.9M
void PersistentBase<T>::Reset() {
469
22.9M
  if (this->IsEmpty()) return;
470
8.26M
  api_internal::DisposeGlobal(this->slot());
471
8.26M
  this->Clear();
472
8.26M
}
v8::PersistentBase<v8::Value>::Reset()
Line
Count
Source
468
13.7k
void PersistentBase<T>::Reset() {
469
13.7k
  if (this->IsEmpty()) return;
470
6.06k
  api_internal::DisposeGlobal(this->slot());
471
6.06k
  this->Clear();
472
6.06k
}
v8::PersistentBase<v8::Array>::Reset()
Line
Count
Source
468
254k
void PersistentBase<T>::Reset() {
469
254k
  if (this->IsEmpty()) return;
470
127k
  api_internal::DisposeGlobal(this->slot());
471
127k
  this->Clear();
472
127k
}
v8::PersistentBase<v8::Object>::Reset()
Line
Count
Source
468
3.29M
void PersistentBase<T>::Reset() {
469
3.29M
  if (this->IsEmpty()) return;
470
2.14M
  api_internal::DisposeGlobal(this->slot());
471
2.14M
  this->Clear();
472
2.14M
}
v8::PersistentBase<v8::Int32Array>::Reset()
Line
Count
Source
468
1.14M
void PersistentBase<T>::Reset() {
469
1.14M
  if (this->IsEmpty()) return;
470
381k
  api_internal::DisposeGlobal(this->slot());
471
381k
  this->Clear();
472
381k
}
v8::PersistentBase<v8::Uint32Array>::Reset()
Line
Count
Source
468
2.67M
void PersistentBase<T>::Reset() {
469
2.67M
  if (this->IsEmpty()) return;
470
891k
  api_internal::DisposeGlobal(this->slot());
471
891k
  this->Clear();
472
891k
}
v8::PersistentBase<v8::Uint8Array>::Reset()
Line
Count
Source
468
1.14M
void PersistentBase<T>::Reset() {
469
1.14M
  if (this->IsEmpty()) return;
470
381k
  api_internal::DisposeGlobal(this->slot());
471
381k
  this->Clear();
472
381k
}
v8::PersistentBase<v8::Function>::Reset()
Line
Count
Source
468
11.0M
void PersistentBase<T>::Reset() {
469
11.0M
  if (this->IsEmpty()) return;
470
3.16M
  api_internal::DisposeGlobal(this->slot());
471
3.16M
  this->Clear();
472
3.16M
}
v8::PersistentBase<v8::Float64Array>::Reset()
Line
Count
Source
468
1.90M
void PersistentBase<T>::Reset() {
469
1.90M
  if (this->IsEmpty()) return;
470
636k
  api_internal::DisposeGlobal(this->slot());
471
636k
  this->Clear();
472
636k
}
v8::PersistentBase<v8::Context>::Reset()
Line
Count
Source
468
653k
void PersistentBase<T>::Reset() {
469
653k
  if (this->IsEmpty()) return;
470
264k
  api_internal::DisposeGlobal(this->slot());
471
264k
  this->Clear();
472
264k
}
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.54k
void PersistentBase<T>::Reset() {
469
2.54k
  if (this->IsEmpty()) return;
470
1.27k
  api_internal::DisposeGlobal(this->slot());
471
1.27k
  this->Clear();
472
1.27k
}
v8::PersistentBase<v8::BigInt64Array>::Reset()
Line
Count
Source
468
763k
void PersistentBase<T>::Reset() {
469
763k
  if (this->IsEmpty()) return;
470
254k
  api_internal::DisposeGlobal(this->slot());
471
254k
  this->Clear();
472
254k
}
Unexecuted instantiation: v8::PersistentBase<v8::SharedArrayBuffer>::Reset()
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::Reset()
v8::PersistentBase<v8::ArrayBufferView>::Reset()
Line
Count
Source
468
810
void PersistentBase<T>::Reset() {
469
810
  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.34M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
5.34M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
5.34M
  Reset();
483
5.34M
  if (other.IsEmpty()) return;
484
4.57M
  this->slot() = New(isolate, *other);
485
4.57M
}
void v8::PersistentBase<v8::Array>::Reset<v8::Array>(v8::Isolate*, v8::Local<v8::Array> const&)
Line
Count
Source
480
127k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
127k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
127k
  Reset();
483
127k
  if (other.IsEmpty()) return;
484
127k
  this->slot() = New(isolate, *other);
485
127k
}
void v8::PersistentBase<v8::Object>::Reset<v8::Object>(v8::Isolate*, v8::Local<v8::Object> const&)
Line
Count
Source
480
1.01M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
1.01M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
1.01M
  Reset();
483
1.01M
  if (other.IsEmpty()) return;
484
1.01M
  this->slot() = New(isolate, *other);
485
1.01M
}
void v8::PersistentBase<v8::Function>::Reset<v8::Function>(v8::Isolate*, v8::Local<v8::Function> const&)
Line
Count
Source
480
3.93M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
3.93M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
3.93M
  Reset();
483
3.93M
  if (other.IsEmpty()) return;
484
3.16M
  this->slot() = New(isolate, *other);
485
3.16M
}
void v8::PersistentBase<v8::Context>::Reset<v8::Context>(v8::Isolate*, v8::Local<v8::Context> const&)
Line
Count
Source
480
257k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
257k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
257k
  Reset();
483
257k
  if (other.IsEmpty()) return;
484
257k
  this->slot() = New(isolate, *other);
485
257k
}
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.05k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
6.05k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
6.05k
  Reset();
483
6.05k
  if (other.IsEmpty()) return;
484
6.05k
  this->slot() = New(isolate, *other);
485
6.05k
}
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.27k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
1.27k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
1.27k
  Reset();
483
1.27k
  if (other.IsEmpty()) return;
484
1.27k
  this->slot() = New(isolate, *other);
485
1.27k
}
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.17M
    WeakCallbackType type) {
506
1.17M
  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.17M
  api_internal::MakeWeak(this->slot(), parameter,
512
1.17M
                         reinterpret_cast<Callback>(callback), type);
513
#if (__GNUC__ >= 8) && !defined(__clang__)
514
#pragma GCC diagnostic pop
515
#endif
516
1.17M
}
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.17M
    WeakCallbackType type) {
506
1.17M
  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.17M
  api_internal::MakeWeak(this->slot(), parameter,
512
1.17M
                         reinterpret_cast<Callback>(callback), type);
513
#if (__GNUC__ >= 8) && !defined(__clang__)
514
#pragma GCC diagnostic pop
515
#endif
516
1.17M
}
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.14M
void PersistentBase<T>::SetWeak() {
520
1.14M
  api_internal::MakeWeak(&this->slot());
521
1.14M
}
v8::PersistentBase<v8::Context>::SetWeak()
Line
Count
Source
519
129k
void PersistentBase<T>::SetWeak() {
520
129k
  api_internal::MakeWeak(&this->slot());
521
129k
}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::SetWeak()
v8::PersistentBase<v8::UnboundScript>::SetWeak()
Line
Count
Source
519
1.27k
void PersistentBase<T>::SetWeak() {
520
1.27k
  api_internal::MakeWeak(&this->slot());
521
1.27k
}
v8::PersistentBase<v8::Float64Array>::SetWeak()
Line
Count
Source
519
254k
void PersistentBase<T>::SetWeak() {
520
254k
  api_internal::MakeWeak(&this->slot());
521
254k
}
v8::PersistentBase<v8::BigInt64Array>::SetWeak()
Line
Count
Source
519
254k
void PersistentBase<T>::SetWeak() {
520
254k
  api_internal::MakeWeak(&this->slot());
521
254k
}
v8::PersistentBase<v8::Uint32Array>::SetWeak()
Line
Count
Source
519
381k
void PersistentBase<T>::SetWeak() {
520
381k
  api_internal::MakeWeak(&this->slot());
521
381k
}
Unexecuted instantiation: v8::PersistentBase<v8::Function>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::Object>::SetWeak()
v8::PersistentBase<v8::Uint8Array>::SetWeak()
Line
Count
Source
519
127k
void PersistentBase<T>::SetWeak() {
520
127k
  api_internal::MakeWeak(&this->slot());
521
127k
}
522
523
template <class T>
524
template <typename P>
525
110k
P* PersistentBase<T>::ClearWeak() {
526
110k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
110k
}
void* v8::PersistentBase<v8::Object>::ClearWeak<void>()
Line
Count
Source
525
110k
P* PersistentBase<T>::ClearWeak() {
526
110k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
110k
}
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.27k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.27k
  if (!other.IsEmpty()) {
553
1.27k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.27k
    other.Clear();
555
1.27k
  }
556
1.27k
}
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.27k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.27k
  if (!other.IsEmpty()) {
553
1.27k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.27k
    other.Clear();
555
1.27k
  }
556
1.27k
}
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.54M
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
2.54M
  static_assert(std::is_base_of<T, S>::value, "type check");
562
2.54M
  if (this != &rhs) {
563
2.54M
    this->Reset();
564
2.54M
    if (!rhs.IsEmpty()) {
565
2.54M
      this->slot() = rhs.slot();
566
2.54M
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
2.54M
      rhs.Clear();
568
2.54M
    }
569
2.54M
  }
570
2.54M
  return *this;
571
2.54M
}
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
381k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
381k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
381k
  if (this != &rhs) {
563
381k
    this->Reset();
564
381k
    if (!rhs.IsEmpty()) {
565
381k
      this->slot() = rhs.slot();
566
381k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
381k
      rhs.Clear();
568
381k
    }
569
381k
  }
570
381k
  return *this;
571
381k
}
v8::Global<v8::Uint32Array>& v8::Global<v8::Uint32Array>::operator=<v8::Uint32Array>(v8::Global<v8::Uint32Array>&&)
Line
Count
Source
560
891k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
891k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
891k
  if (this != &rhs) {
563
891k
    this->Reset();
564
891k
    if (!rhs.IsEmpty()) {
565
891k
      this->slot() = rhs.slot();
566
891k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
891k
      rhs.Clear();
568
891k
    }
569
891k
  }
570
891k
  return *this;
571
891k
}
v8::Global<v8::Uint8Array>& v8::Global<v8::Uint8Array>::operator=<v8::Uint8Array>(v8::Global<v8::Uint8Array>&&)
Line
Count
Source
560
381k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
381k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
381k
  if (this != &rhs) {
563
381k
    this->Reset();
564
381k
    if (!rhs.IsEmpty()) {
565
381k
      this->slot() = rhs.slot();
566
381k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
381k
      rhs.Clear();
568
381k
    }
569
381k
  }
570
381k
  return *this;
571
381k
}
v8::Global<v8::Float64Array>& v8::Global<v8::Float64Array>::operator=<v8::Float64Array>(v8::Global<v8::Float64Array>&&)
Line
Count
Source
560
636k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
636k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
636k
  if (this != &rhs) {
563
636k
    this->Reset();
564
636k
    if (!rhs.IsEmpty()) {
565
636k
      this->slot() = rhs.slot();
566
636k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
636k
      rhs.Clear();
568
636k
    }
569
636k
  }
570
636k
  return *this;
571
636k
}
v8::Global<v8::BigInt64Array>& v8::Global<v8::BigInt64Array>::operator=<v8::BigInt64Array>(v8::Global<v8::BigInt64Array>&&)
Line
Count
Source
560
254k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
254k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
254k
  if (this != &rhs) {
563
254k
    this->Reset();
564
254k
    if (!rhs.IsEmpty()) {
565
254k
      this->slot() = rhs.slot();
566
254k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
254k
      rhs.Clear();
568
254k
    }
569
254k
  }
570
254k
  return *this;
571
254k
}
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_