Coverage Report

Created: 2025-08-03 10:06

/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.2M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Private>::Eternal()
Line
Count
Source
49
9.51M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::Symbol>::Eternal()
Line
Count
Source
49
2.28M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::String>::Eternal()
Line
Count
Source
49
44.4M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::FunctionTemplate>::Eternal()
Line
Count
Source
49
3.29M
  V8_INLINE Eternal() = default;
v8::Eternal<v8::ObjectTemplate>::Eternal()
Line
Count
Source
49
4.69M
  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
114M
  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
114M
    return Local<T>::FromSlot(slot());
61
114M
  }
v8::Eternal<v8::Private>::Get(v8::Isolate*) const
Line
Count
Source
57
3.15M
  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.15M
    return Local<T>::FromSlot(slot());
61
3.15M
  }
v8::Eternal<v8::Symbol>::Get(v8::Isolate*) const
Line
Count
Source
57
4.99M
  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.99M
    return Local<T>::FromSlot(slot());
61
4.99M
  }
v8::Eternal<v8::FunctionTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
2.75M
  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.75M
    return Local<T>::FromSlot(slot());
61
2.75M
  }
v8::Eternal<v8::ObjectTemplate>::Get(v8::Isolate*) const
Line
Count
Source
57
4.68M
  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.68M
    return Local<T>::FromSlot(slot());
61
4.68M
  }
62
63
  template <class S>
64
61.2M
  void Set(Isolate* isolate, Local<S> handle) {
65
61.2M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
61.2M
    slot() =
67
61.2M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
61.2M
  }
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.85M
  void Set(Isolate* isolate, Local<S> handle) {
65
3.85M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
3.85M
    slot() =
67
3.85M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
3.85M
  }
void v8::Eternal<v8::Private>::Set<v8::Private>(v8::Isolate*, v8::Local<v8::Private>)
Line
Count
Source
64
9.51M
  void Set(Isolate* isolate, Local<S> handle) {
65
9.51M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
9.51M
    slot() =
67
9.51M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
9.51M
  }
void v8::Eternal<v8::Symbol>::Set<v8::Symbol>(v8::Isolate*, v8::Local<v8::Symbol>)
Line
Count
Source
64
2.28M
  void Set(Isolate* isolate, Local<S> handle) {
65
2.28M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
2.28M
    slot() =
67
2.28M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
2.28M
  }
void v8::Eternal<v8::String>::Set<v8::String>(v8::Isolate*, v8::Local<v8::String>)
Line
Count
Source
64
44.4M
  void Set(Isolate* isolate, Local<S> handle) {
65
44.4M
    static_assert(std::is_base_of<T, S>::value, "type check");
66
44.4M
    slot() =
67
44.4M
        api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
68
44.4M
  }
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.62M
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
2.62M
    return Local<T>::New(isolate, *this);
115
2.62M
  }
Unexecuted instantiation: v8::PersistentBase<v8::Int8Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Uint8Array>::Get(v8::Isolate*) const
Line
Count
Source
113
507k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
507k
    return Local<T>::New(isolate, *this);
115
507k
  }
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
339k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
339k
    return Local<T>::New(isolate, *this);
115
339k
  }
v8::PersistentBase<v8::Uint32Array>::Get(v8::Isolate*) const
Line
Count
Source
113
888k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
888k
    return Local<T>::New(isolate, *this);
115
888k
  }
Unexecuted instantiation: v8::PersistentBase<v8::Float32Array>::Get(v8::Isolate*) const
v8::PersistentBase<v8::Float64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
634k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
634k
    return Local<T>::New(isolate, *this);
115
634k
  }
v8::PersistentBase<v8::BigInt64Array>::Get(v8::Isolate*) const
Line
Count
Source
113
253k
  V8_INLINE Local<T> Get(Isolate* isolate) const {
114
253k
    return Local<T>::New(isolate, *this);
115
253k
  }
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
108k
  V8_INLINE void ClearWeak() { ClearWeak<void>(); }
v8::PersistentBase<v8::Object>::ClearWeak()
Line
Count
Source
165
108k
  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.1M
  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
126k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Function>::PersistentBase()
Line
Count
Source
212
7.10M
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Context>::PersistentBase()
Line
Count
Source
212
255k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Int32Array>::PersistentBase()
Line
Count
Source
212
380k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint32Array>::PersistentBase()
Line
Count
Source
212
888k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Uint8Array>::PersistentBase()
Line
Count
Source
212
380k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::Float64Array>::PersistentBase()
Line
Count
Source
212
634k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::Promise>::PersistentBase()
v8::PersistentBase<v8::Value>::PersistentBase()
Line
Count
Source
212
7.52k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::PersistentBase()
v8::PersistentBase<v8::UnboundScript>::PersistentBase()
Line
Count
Source
212
1.03k
  V8_INLINE PersistentBase() = default;
v8::PersistentBase<v8::BigInt64Array>::PersistentBase()
Line
Count
Source
212
253k
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::PersistentBase()
v8::PersistentBase<v8::ArrayBufferView>::PersistentBase()
Line
Count
Source
212
898
  V8_INLINE PersistentBase() = default;
Unexecuted instantiation: v8::PersistentBase<v8::FunctionTemplate>::PersistentBase()
213
214
  V8_INLINE explicit PersistentBase(internal::Address* location)
215
3.67M
      : 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.56k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Int32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
380k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint32Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
888k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Uint8Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
380k
      : IndirectHandleBase(location) {}
v8::PersistentBase<v8::Float64Array>::PersistentBase(unsigned long*)
Line
Count
Source
215
634k
      : 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
253k
      : 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.1M
  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
126k
  V8_INLINE Global() = default;
v8::Global<v8::Function>::Global()
Line
Count
Source
371
7.10M
  V8_INLINE Global() = default;
v8::Global<v8::Context>::Global()
Line
Count
Source
371
255k
  V8_INLINE Global() = default;
v8::Global<v8::Int32Array>::Global()
Line
Count
Source
371
380k
  V8_INLINE Global() = default;
v8::Global<v8::Uint32Array>::Global()
Line
Count
Source
371
888k
  V8_INLINE Global() = default;
v8::Global<v8::Uint8Array>::Global()
Line
Count
Source
371
380k
  V8_INLINE Global() = default;
v8::Global<v8::Float64Array>::Global()
Line
Count
Source
371
634k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::Promise>::Global()
v8::Global<v8::Value>::Global()
Line
Count
Source
371
7.52k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::ArrayBuffer>::Global()
v8::Global<v8::UnboundScript>::Global()
Line
Count
Source
371
1.03k
  V8_INLINE Global() = default;
v8::Global<v8::BigInt64Array>::Global()
Line
Count
Source
371
253k
  V8_INLINE Global() = default;
Unexecuted instantiation: v8::Global<v8::WasmMemoryObject>::Global()
v8::Global<v8::ArrayBufferView>::Global()
Line
Count
Source
371
898
  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.66M
      : PersistentBase<T>(
381
3.66M
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
3.66M
    static_assert(std::is_base_of<T, S>::value, "type check");
383
3.66M
  }
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
380k
      : PersistentBase<T>(
381
380k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
380k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
380k
  }
v8::Global<v8::Uint32Array>::Global<v8::Uint32Array>(v8::Isolate*, v8::Local<v8::Uint32Array>)
Line
Count
Source
380
888k
      : PersistentBase<T>(
381
888k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
888k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
888k
  }
v8::Global<v8::Uint8Array>::Global<v8::Uint8Array>(v8::Isolate*, v8::Local<v8::Uint8Array>)
Line
Count
Source
380
380k
      : PersistentBase<T>(
381
380k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
380k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
380k
  }
v8::Global<v8::Float64Array>::Global<v8::Float64Array>(v8::Isolate*, v8::Local<v8::Float64Array>)
Line
Count
Source
380
634k
      : PersistentBase<T>(
381
634k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
634k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
634k
  }
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.52k
      : PersistentBase<T>(
381
7.52k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
7.52k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
7.52k
  }
v8::Global<v8::BigInt64Array>::Global<v8::BigInt64Array>(v8::Isolate*, v8::Local<v8::BigInt64Array>)
Line
Count
Source
380
253k
      : PersistentBase<T>(
381
253k
            PersistentBase<T>::New(isolate, that.template value<S>())) {
382
253k
    static_assert(std::is_base_of<T, S>::value, "type check");
383
253k
  }
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.26M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Int32Array>::~Global()
Line
Count
Source
402
761k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint32Array>::~Global()
Line
Count
Source
402
1.77M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Uint8Array>::~Global()
Line
Count
Source
402
761k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Function>::~Global()
Line
Count
Source
402
7.10M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Array>::~Global()
Line
Count
Source
402
126k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Float64Array>::~Global()
Line
Count
Source
402
1.26M
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Context>::~Global()
Line
Count
Source
402
264k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::Value>::~Global()
Line
Count
Source
402
7.53k
  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.03k
  V8_INLINE ~Global() { this->Reset(); }
v8::Global<v8::BigInt64Array>::~Global()
Line
Count
Source
402
507k
  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
898
  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.23M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
8.23M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
8.23M
  return api_internal::GlobalizeReference(
446
8.23M
      reinterpret_cast<internal::Isolate*>(isolate),
447
8.23M
      internal::ValueHelper::ValueAsAddress(that));
448
8.23M
}
v8::PersistentBase<v8::Value>::New(v8::Isolate*, v8::Value*)
Line
Count
Source
443
5.91k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
5.91k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
5.91k
  return api_internal::GlobalizeReference(
446
5.91k
      reinterpret_cast<internal::Isolate*>(isolate),
447
5.91k
      internal::ValueHelper::ValueAsAddress(that));
448
5.91k
}
v8::PersistentBase<v8::Array>::New(v8::Isolate*, v8::Array*)
Line
Count
Source
443
126k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
126k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
126k
  return api_internal::GlobalizeReference(
446
126k
      reinterpret_cast<internal::Isolate*>(isolate),
447
126k
      internal::ValueHelper::ValueAsAddress(that));
448
126k
}
v8::PersistentBase<v8::Object>::New(v8::Isolate*, v8::Object*)
Line
Count
Source
443
2.13M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
2.13M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
2.13M
  return api_internal::GlobalizeReference(
446
2.13M
      reinterpret_cast<internal::Isolate*>(isolate),
447
2.13M
      internal::ValueHelper::ValueAsAddress(that));
448
2.13M
}
v8::PersistentBase<v8::Function>::New(v8::Isolate*, v8::Function*)
Line
Count
Source
443
3.15M
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
3.15M
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
3.15M
  return api_internal::GlobalizeReference(
446
3.15M
      reinterpret_cast<internal::Isolate*>(isolate),
447
3.15M
      internal::ValueHelper::ValueAsAddress(that));
448
3.15M
}
v8::PersistentBase<v8::Context>::New(v8::Isolate*, v8::Context*)
Line
Count
Source
443
263k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
263k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
263k
  return api_internal::GlobalizeReference(
446
263k
      reinterpret_cast<internal::Isolate*>(isolate),
447
263k
      internal::ValueHelper::ValueAsAddress(that));
448
263k
}
v8::PersistentBase<v8::Int32Array>::New(v8::Isolate*, v8::Int32Array*)
Line
Count
Source
443
380k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
380k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
380k
  return api_internal::GlobalizeReference(
446
380k
      reinterpret_cast<internal::Isolate*>(isolate),
447
380k
      internal::ValueHelper::ValueAsAddress(that));
448
380k
}
v8::PersistentBase<v8::Uint32Array>::New(v8::Isolate*, v8::Uint32Array*)
Line
Count
Source
443
888k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
888k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
888k
  return api_internal::GlobalizeReference(
446
888k
      reinterpret_cast<internal::Isolate*>(isolate),
447
888k
      internal::ValueHelper::ValueAsAddress(that));
448
888k
}
v8::PersistentBase<v8::Uint8Array>::New(v8::Isolate*, v8::Uint8Array*)
Line
Count
Source
443
380k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
380k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
380k
  return api_internal::GlobalizeReference(
446
380k
      reinterpret_cast<internal::Isolate*>(isolate),
447
380k
      internal::ValueHelper::ValueAsAddress(that));
448
380k
}
v8::PersistentBase<v8::Float64Array>::New(v8::Isolate*, v8::Float64Array*)
Line
Count
Source
443
634k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
634k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
634k
  return api_internal::GlobalizeReference(
446
634k
      reinterpret_cast<internal::Isolate*>(isolate),
447
634k
      internal::ValueHelper::ValueAsAddress(that));
448
634k
}
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.03k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
1.03k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
1.03k
  return api_internal::GlobalizeReference(
446
1.03k
      reinterpret_cast<internal::Isolate*>(isolate),
447
1.03k
      internal::ValueHelper::ValueAsAddress(that));
448
1.03k
}
v8::PersistentBase<v8::BigInt64Array>::New(v8::Isolate*, v8::BigInt64Array*)
Line
Count
Source
443
253k
internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
444
253k
  if (internal::ValueHelper::IsEmpty(that)) return nullptr;
445
253k
  return api_internal::GlobalizeReference(
446
253k
      reinterpret_cast<internal::Isolate*>(isolate),
447
253k
      internal::ValueHelper::ValueAsAddress(that));
448
253k
}
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.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::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.45M
bool PersistentBase<T>::IsWeak() const {
462
2.45M
  using I = internal::Internals;
463
2.45M
  if (this->IsEmpty()) return false;
464
2.45M
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
2.45M
}
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
13.4k
bool PersistentBase<T>::IsWeak() const {
462
13.4k
  using I = internal::Internals;
463
13.4k
  if (this->IsEmpty()) return false;
464
13.4k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
13.4k
}
v8::PersistentBase<v8::UnboundScript>::IsWeak() const
Line
Count
Source
461
1.03k
bool PersistentBase<T>::IsWeak() const {
462
1.03k
  using I = internal::Internals;
463
1.03k
  if (this->IsEmpty()) return false;
464
1.03k
  return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
465
1.03k
}
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.8M
void PersistentBase<T>::Reset() {
469
22.8M
  if (this->IsEmpty()) return;
470
8.23M
  api_internal::DisposeGlobal(this->slot());
471
8.23M
  this->Clear();
472
8.23M
}
v8::PersistentBase<v8::Value>::Reset()
Line
Count
Source
468
13.4k
void PersistentBase<T>::Reset() {
469
13.4k
  if (this->IsEmpty()) return;
470
5.91k
  api_internal::DisposeGlobal(this->slot());
471
5.91k
  this->Clear();
472
5.91k
}
v8::PersistentBase<v8::Array>::Reset()
Line
Count
Source
468
253k
void PersistentBase<T>::Reset() {
469
253k
  if (this->IsEmpty()) return;
470
126k
  api_internal::DisposeGlobal(this->slot());
471
126k
  this->Clear();
472
126k
}
v8::PersistentBase<v8::Object>::Reset()
Line
Count
Source
468
3.28M
void PersistentBase<T>::Reset() {
469
3.28M
  if (this->IsEmpty()) return;
470
2.13M
  api_internal::DisposeGlobal(this->slot());
471
2.13M
  this->Clear();
472
2.13M
}
v8::PersistentBase<v8::Int32Array>::Reset()
Line
Count
Source
468
1.14M
void PersistentBase<T>::Reset() {
469
1.14M
  if (this->IsEmpty()) return;
470
380k
  api_internal::DisposeGlobal(this->slot());
471
380k
  this->Clear();
472
380k
}
v8::PersistentBase<v8::Uint32Array>::Reset()
Line
Count
Source
468
2.66M
void PersistentBase<T>::Reset() {
469
2.66M
  if (this->IsEmpty()) return;
470
888k
  api_internal::DisposeGlobal(this->slot());
471
888k
  this->Clear();
472
888k
}
v8::PersistentBase<v8::Uint8Array>::Reset()
Line
Count
Source
468
1.14M
void PersistentBase<T>::Reset() {
469
1.14M
  if (this->IsEmpty()) return;
470
380k
  api_internal::DisposeGlobal(this->slot());
471
380k
  this->Clear();
472
380k
}
v8::PersistentBase<v8::Function>::Reset()
Line
Count
Source
468
11.0M
void PersistentBase<T>::Reset() {
469
11.0M
  if (this->IsEmpty()) return;
470
3.15M
  api_internal::DisposeGlobal(this->slot());
471
3.15M
  this->Clear();
472
3.15M
}
v8::PersistentBase<v8::Float64Array>::Reset()
Line
Count
Source
468
1.90M
void PersistentBase<T>::Reset() {
469
1.90M
  if (this->IsEmpty()) return;
470
634k
  api_internal::DisposeGlobal(this->slot());
471
634k
  this->Clear();
472
634k
}
v8::PersistentBase<v8::Context>::Reset()
Line
Count
Source
468
649k
void PersistentBase<T>::Reset() {
469
649k
  if (this->IsEmpty()) return;
470
263k
  api_internal::DisposeGlobal(this->slot());
471
263k
  this->Clear();
472
263k
}
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.06k
void PersistentBase<T>::Reset() {
469
2.06k
  if (this->IsEmpty()) return;
470
1.03k
  api_internal::DisposeGlobal(this->slot());
471
1.03k
  this->Clear();
472
1.03k
}
v8::PersistentBase<v8::BigInt64Array>::Reset()
Line
Count
Source
468
761k
void PersistentBase<T>::Reset() {
469
761k
  if (this->IsEmpty()) return;
470
253k
  api_internal::DisposeGlobal(this->slot());
471
253k
  this->Clear();
472
253k
}
Unexecuted instantiation: v8::PersistentBase<v8::SharedArrayBuffer>::Reset()
Unexecuted instantiation: v8::PersistentBase<v8::WasmMemoryObject>::Reset()
v8::PersistentBase<v8::ArrayBufferView>::Reset()
Line
Count
Source
468
898
void PersistentBase<T>::Reset() {
469
898
  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.32M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
5.32M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
5.32M
  Reset();
483
5.32M
  if (other.IsEmpty()) return;
484
4.56M
  this->slot() = New(isolate, *other);
485
4.56M
}
void v8::PersistentBase<v8::Array>::Reset<v8::Array>(v8::Isolate*, v8::Local<v8::Array> const&)
Line
Count
Source
480
126k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
126k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
126k
  Reset();
483
126k
  if (other.IsEmpty()) return;
484
126k
  this->slot() = New(isolate, *other);
485
126k
}
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.92M
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
3.92M
  static_assert(std::is_base_of<T, S>::value, "type check");
482
3.92M
  Reset();
483
3.92M
  if (other.IsEmpty()) return;
484
3.15M
  this->slot() = New(isolate, *other);
485
3.15M
}
void v8::PersistentBase<v8::Context>::Reset<v8::Context>(v8::Isolate*, v8::Local<v8::Context> const&)
Line
Count
Source
480
255k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
255k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
255k
  Reset();
483
255k
  if (other.IsEmpty()) return;
484
255k
  this->slot() = New(isolate, *other);
485
255k
}
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
5.91k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
5.91k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
5.91k
  Reset();
483
5.91k
  if (other.IsEmpty()) return;
484
5.91k
  this->slot() = New(isolate, *other);
485
5.91k
}
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.03k
void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
481
1.03k
  static_assert(std::is_base_of<T, S>::value, "type check");
482
1.03k
  Reset();
483
1.03k
  if (other.IsEmpty()) return;
484
1.03k
  this->slot() = New(isolate, *other);
485
1.03k
}
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
128k
void PersistentBase<T>::SetWeak() {
520
128k
  api_internal::MakeWeak(&this->slot());
521
128k
}
Unexecuted instantiation: v8::PersistentBase<v8::Module>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::ArrayBuffer>::SetWeak()
v8::PersistentBase<v8::UnboundScript>::SetWeak()
Line
Count
Source
519
1.03k
void PersistentBase<T>::SetWeak() {
520
1.03k
  api_internal::MakeWeak(&this->slot());
521
1.03k
}
v8::PersistentBase<v8::Float64Array>::SetWeak()
Line
Count
Source
519
253k
void PersistentBase<T>::SetWeak() {
520
253k
  api_internal::MakeWeak(&this->slot());
521
253k
}
v8::PersistentBase<v8::BigInt64Array>::SetWeak()
Line
Count
Source
519
253k
void PersistentBase<T>::SetWeak() {
520
253k
  api_internal::MakeWeak(&this->slot());
521
253k
}
v8::PersistentBase<v8::Uint32Array>::SetWeak()
Line
Count
Source
519
380k
void PersistentBase<T>::SetWeak() {
520
380k
  api_internal::MakeWeak(&this->slot());
521
380k
}
Unexecuted instantiation: v8::PersistentBase<v8::Function>::SetWeak()
Unexecuted instantiation: v8::PersistentBase<v8::Object>::SetWeak()
v8::PersistentBase<v8::Uint8Array>::SetWeak()
Line
Count
Source
519
126k
void PersistentBase<T>::SetWeak() {
520
126k
  api_internal::MakeWeak(&this->slot());
521
126k
}
522
523
template <class T>
524
template <typename P>
525
108k
P* PersistentBase<T>::ClearWeak() {
526
108k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
108k
}
void* v8::PersistentBase<v8::Object>::ClearWeak<void>()
Line
Count
Source
525
108k
P* PersistentBase<T>::ClearWeak() {
526
108k
  return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
527
108k
}
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.03k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.03k
  if (!other.IsEmpty()) {
553
1.03k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.03k
    other.Clear();
555
1.03k
  }
556
1.03k
}
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.03k
Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
552
1.03k
  if (!other.IsEmpty()) {
553
1.03k
    api_internal::MoveGlobalReference(&other.slot(), &this->slot());
554
1.03k
    other.Clear();
555
1.03k
  }
556
1.03k
}
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.53M
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
2.53M
  static_assert(std::is_base_of<T, S>::value, "type check");
562
2.53M
  if (this != &rhs) {
563
2.53M
    this->Reset();
564
2.53M
    if (!rhs.IsEmpty()) {
565
2.53M
      this->slot() = rhs.slot();
566
2.53M
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
2.53M
      rhs.Clear();
568
2.53M
    }
569
2.53M
  }
570
2.53M
  return *this;
571
2.53M
}
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
380k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
380k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
380k
  if (this != &rhs) {
563
380k
    this->Reset();
564
380k
    if (!rhs.IsEmpty()) {
565
380k
      this->slot() = rhs.slot();
566
380k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
380k
      rhs.Clear();
568
380k
    }
569
380k
  }
570
380k
  return *this;
571
380k
}
v8::Global<v8::Uint32Array>& v8::Global<v8::Uint32Array>::operator=<v8::Uint32Array>(v8::Global<v8::Uint32Array>&&)
Line
Count
Source
560
888k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
888k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
888k
  if (this != &rhs) {
563
888k
    this->Reset();
564
888k
    if (!rhs.IsEmpty()) {
565
888k
      this->slot() = rhs.slot();
566
888k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
888k
      rhs.Clear();
568
888k
    }
569
888k
  }
570
888k
  return *this;
571
888k
}
v8::Global<v8::Uint8Array>& v8::Global<v8::Uint8Array>::operator=<v8::Uint8Array>(v8::Global<v8::Uint8Array>&&)
Line
Count
Source
560
380k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
380k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
380k
  if (this != &rhs) {
563
380k
    this->Reset();
564
380k
    if (!rhs.IsEmpty()) {
565
380k
      this->slot() = rhs.slot();
566
380k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
380k
      rhs.Clear();
568
380k
    }
569
380k
  }
570
380k
  return *this;
571
380k
}
v8::Global<v8::Float64Array>& v8::Global<v8::Float64Array>::operator=<v8::Float64Array>(v8::Global<v8::Float64Array>&&)
Line
Count
Source
560
634k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
634k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
634k
  if (this != &rhs) {
563
634k
    this->Reset();
564
634k
    if (!rhs.IsEmpty()) {
565
634k
      this->slot() = rhs.slot();
566
634k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
634k
      rhs.Clear();
568
634k
    }
569
634k
  }
570
634k
  return *this;
571
634k
}
v8::Global<v8::BigInt64Array>& v8::Global<v8::BigInt64Array>::operator=<v8::BigInt64Array>(v8::Global<v8::BigInt64Array>&&)
Line
Count
Source
560
253k
Global<T>& Global<T>::operator=(Global<S>&& rhs) {
561
253k
  static_assert(std::is_base_of<T, S>::value, "type check");
562
253k
  if (this != &rhs) {
563
253k
    this->Reset();
564
253k
    if (!rhs.IsEmpty()) {
565
253k
      this->slot() = rhs.slot();
566
253k
      api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
567
253k
      rhs.Clear();
568
253k
    }
569
253k
  }
570
253k
  return *this;
571
253k
}
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_