Coverage Report

Created: 2025-08-28 09:57

/src/node/deps/v8/include/v8-handle-base.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2023 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_HANDLE_BASE_H_
6
#define INCLUDE_V8_HANDLE_BASE_H_
7
8
#include "v8-internal.h"  // NOLINT(build/include_directory)
9
10
namespace v8::api_internal {
11
12
template <bool check_statically_enabled>
13
class StackAllocated {
14
 public:
15
  V8_INLINE StackAllocated() = default;
16
17
 protected:
18
  struct no_checking_tag {};
19
  static constexpr no_checking_tag do_not_check{};
20
21
  V8_INLINE explicit StackAllocated(no_checking_tag) {}
22
  V8_INLINE explicit StackAllocated(const StackAllocated& other,
23
                                    no_checking_tag) {}
24
25
  V8_INLINE void VerifyOnStack() const {}
26
};
27
28
template <>
29
class V8_TRIVIAL_ABI StackAllocated<true> : public StackAllocated<false> {
30
 public:
31
0
  V8_INLINE StackAllocated() { VerifyOnStack(); }
32
33
#if V8_HAS_ATTRIBUTE_TRIVIAL_ABI
34
  // In this case, StackAllocated becomes not trivially copyable.
35
0
  V8_INLINE StackAllocated(const StackAllocated& other) { VerifyOnStack(); }
36
  StackAllocated& operator=(const StackAllocated&) = default;
37
#endif
38
39
 protected:
40
  V8_INLINE explicit StackAllocated(no_checking_tag tag)
41
0
      : StackAllocated<false>(tag) {}
42
  V8_INLINE explicit StackAllocated(const StackAllocated& other,
43
                                    no_checking_tag tag)
44
0
      : StackAllocated<false>(other, tag) {}
45
46
  V8_EXPORT void VerifyOnStack() const;
47
};
48
49
/**
50
 * A base class for abstract handles containing indirect pointers.
51
 * These are useful regardless of whether direct local support is enabled.
52
 */
53
class IndirectHandleBase {
54
 public:
55
  // Returns true if the handle is empty.
56
742M
  V8_INLINE bool IsEmpty() const { return location_ == nullptr; }
57
58
  // Sets the handle to be empty. IsEmpty() will then return true.
59
10.3M
  V8_INLINE void Clear() { location_ = nullptr; }
60
61
 protected:
62
  friend class internal::ValueHelper;
63
  friend class internal::HandleHelper;
64
65
1.04G
  V8_INLINE IndirectHandleBase() = default;
66
  V8_INLINE IndirectHandleBase(const IndirectHandleBase& other) = default;
67
  V8_INLINE IndirectHandleBase& operator=(const IndirectHandleBase& that) =
68
      default;
69
70
  V8_INLINE explicit IndirectHandleBase(internal::Address* location)
71
240M
      : location_(location) {}
72
73
  // Returns the address of the actual heap object (tagged).
74
  // This method must be called only if the handle is not empty, otherwise it
75
  // will crash.
76
16.0M
  V8_INLINE internal::Address ptr() const { return *location_; }
77
78
  // Returns a reference to the slot (indirect pointer).
79
893M
  V8_INLINE internal::Address* const& slot() const { return location_; }
80
105M
  V8_INLINE internal::Address*& slot() { return location_; }
81
82
  // Returns the handler's "value" (direct or indirect pointer, depending on
83
  // whether direct local support is enabled).
84
  template <typename T, bool check_null = false>
85
765M
  V8_INLINE T* value() const {
86
765M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
765M
  }
Unexecuted instantiation: v8::Data* v8::api_internal::IndirectHandleBase::value<v8::Data, false>() const
v8::Value* v8::api_internal::IndirectHandleBase::value<v8::Value, false>() const
Line
Count
Source
85
129M
  V8_INLINE T* value() const {
86
129M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
129M
  }
v8::Object* v8::api_internal::IndirectHandleBase::value<v8::Object, false>() const
Line
Count
Source
85
279M
  V8_INLINE T* value() const {
86
279M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
279M
  }
v8::Context* v8::api_internal::IndirectHandleBase::value<v8::Context, false>() const
Line
Count
Source
85
167M
  V8_INLINE T* value() const {
86
167M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
167M
  }
Unexecuted instantiation: v8::Date* v8::api_internal::IndirectHandleBase::value<v8::Date, false>() const
v8::FunctionTemplate* v8::api_internal::IndirectHandleBase::value<v8::FunctionTemplate, false>() const
Line
Count
Source
85
50.3M
  V8_INLINE T* value() const {
86
50.3M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
50.3M
  }
v8::Template* v8::api_internal::IndirectHandleBase::value<v8::Template, false>() const
Line
Count
Source
85
20.6M
  V8_INLINE T* value() const {
86
20.6M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
20.6M
  }
v8::Function* v8::api_internal::IndirectHandleBase::value<v8::Function, false>() const
Line
Count
Source
85
19.9M
  V8_INLINE T* value() const {
86
19.9M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
19.9M
  }
v8::ObjectTemplate* v8::api_internal::IndirectHandleBase::value<v8::ObjectTemplate, false>() const
Line
Count
Source
85
25.8M
  V8_INLINE T* value() const {
86
25.8M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
25.8M
  }
v8::Array* v8::api_internal::IndirectHandleBase::value<v8::Array, false>() const
Line
Count
Source
85
1.71M
  V8_INLINE T* value() const {
86
1.71M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.71M
  }
v8::Number* v8::api_internal::IndirectHandleBase::value<v8::Number, false>() const
Line
Count
Source
85
9
  V8_INLINE T* value() const {
86
9
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
9
  }
Unexecuted instantiation: v8::Int8Array* v8::api_internal::IndirectHandleBase::value<v8::Int8Array, true>() const
v8::Uint8Array* v8::api_internal::IndirectHandleBase::value<v8::Uint8Array, true>() const
Line
Count
Source
85
488k
  V8_INLINE T* value() const {
86
488k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
488k
  }
Unexecuted instantiation: v8::Int16Array* v8::api_internal::IndirectHandleBase::value<v8::Int16Array, true>() const
Unexecuted instantiation: v8::Uint16Array* v8::api_internal::IndirectHandleBase::value<v8::Uint16Array, true>() const
v8::Int32Array* v8::api_internal::IndirectHandleBase::value<v8::Int32Array, true>() const
Line
Count
Source
85
327k
  V8_INLINE T* value() const {
86
327k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
327k
  }
v8::Uint32Array* v8::api_internal::IndirectHandleBase::value<v8::Uint32Array, true>() const
Line
Count
Source
85
854k
  V8_INLINE T* value() const {
86
854k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
854k
  }
Unexecuted instantiation: v8::Float32Array* v8::api_internal::IndirectHandleBase::value<v8::Float32Array, true>() const
v8::Float64Array* v8::api_internal::IndirectHandleBase::value<v8::Float64Array, true>() const
Line
Count
Source
85
610k
  V8_INLINE T* value() const {
86
610k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
610k
  }
v8::BigInt64Array* v8::api_internal::IndirectHandleBase::value<v8::BigInt64Array, true>() const
Line
Count
Source
85
244k
  V8_INLINE T* value() const {
86
244k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
244k
  }
v8::Object* v8::api_internal::IndirectHandleBase::value<v8::Object, true>() const
Line
Count
Source
85
1.00M
  V8_INLINE T* value() const {
86
1.00M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.00M
  }
v8::Int32* v8::api_internal::IndirectHandleBase::value<v8::Int32, false>() const
Line
Count
Source
85
115k
  V8_INLINE T* value() const {
86
115k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
115k
  }
v8::Context* v8::api_internal::IndirectHandleBase::value<v8::Context, true>() const
Line
Count
Source
85
137k
  V8_INLINE T* value() const {
86
137k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
137k
  }
Unexecuted instantiation: v8::Private* v8::api_internal::IndirectHandleBase::value<v8::Private, false>() const
v8::Symbol* v8::api_internal::IndirectHandleBase::value<v8::Symbol, false>() const
Line
Count
Source
85
2.19M
  V8_INLINE T* value() const {
86
2.19M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
2.19M
  }
v8::String* v8::api_internal::IndirectHandleBase::value<v8::String, false>() const
Line
Count
Source
85
31.0M
  V8_INLINE T* value() const {
86
31.0M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
31.0M
  }
v8::ArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::ArrayBuffer, false>() const
Line
Count
Source
85
2.85M
  V8_INLINE T* value() const {
86
2.85M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
2.85M
  }
v8::Int32Array* v8::api_internal::IndirectHandleBase::value<v8::Int32Array, false>() const
Line
Count
Source
85
366k
  V8_INLINE T* value() const {
86
366k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
366k
  }
v8::Uint32Array* v8::api_internal::IndirectHandleBase::value<v8::Uint32Array, false>() const
Line
Count
Source
85
860k
  V8_INLINE T* value() const {
86
860k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
860k
  }
v8::Script* v8::api_internal::IndirectHandleBase::value<v8::Script, false>() const
Line
Count
Source
85
3.98k
  V8_INLINE T* value() const {
86
3.98k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
3.98k
  }
Unexecuted instantiation: v8::Promise* v8::api_internal::IndirectHandleBase::value<v8::Promise, false>() const
v8::Uint8Array* v8::api_internal::IndirectHandleBase::value<v8::Uint8Array, false>() const
Line
Count
Source
85
614k
  V8_INLINE T* value() const {
86
614k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
614k
  }
v8::Float64Array* v8::api_internal::IndirectHandleBase::value<v8::Float64Array, false>() const
Line
Count
Source
85
610k
  V8_INLINE T* value() const {
86
610k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
610k
  }
Unexecuted instantiation: v8::Array* v8::api_internal::IndirectHandleBase::value<v8::Array, true>() const
v8::Function* v8::api_internal::IndirectHandleBase::value<v8::Function, true>() const
Line
Count
Source
85
2
  V8_INLINE T* value() const {
86
2
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
2
  }
v8::Uint32* v8::api_internal::IndirectHandleBase::value<v8::Uint32, false>() const
Line
Count
Source
85
1.30k
  V8_INLINE T* value() const {
86
1.30k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.30k
  }
Unexecuted instantiation: v8::Promise* v8::api_internal::IndirectHandleBase::value<v8::Promise, true>() const
v8::Name* v8::api_internal::IndirectHandleBase::value<v8::Name, false>() const
Line
Count
Source
85
1.14M
  V8_INLINE T* value() const {
86
1.14M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.14M
  }
Unexecuted instantiation: v8::Module* v8::api_internal::IndirectHandleBase::value<v8::Module, false>() const
Unexecuted instantiation: v8::Module* v8::api_internal::IndirectHandleBase::value<v8::Module, true>() const
v8::PrimitiveArray* v8::api_internal::IndirectHandleBase::value<v8::PrimitiveArray, false>() const
Line
Count
Source
85
264k
  V8_INLINE T* value() const {
86
264k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
264k
  }
v8::ArrayBufferView* v8::api_internal::IndirectHandleBase::value<v8::ArrayBufferView, false>() const
Line
Count
Source
85
508k
  V8_INLINE T* value() const {
86
508k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
508k
  }
Unexecuted instantiation: v8::UnboundModuleScript* v8::api_internal::IndirectHandleBase::value<v8::UnboundModuleScript, false>() const
Unexecuted instantiation: v8::FixedArray* v8::api_internal::IndirectHandleBase::value<v8::FixedArray, false>() const
Unexecuted instantiation: v8::ModuleRequest* v8::api_internal::IndirectHandleBase::value<v8::ModuleRequest, false>() const
v8::Boolean* v8::api_internal::IndirectHandleBase::value<v8::Boolean, false>() const
Line
Count
Source
85
122k
  V8_INLINE T* value() const {
86
122k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
122k
  }
Unexecuted instantiation: v8::Promise::Resolver* v8::api_internal::IndirectHandleBase::value<v8::Promise::Resolver, false>() const
Unexecuted instantiation: v8::SharedArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::SharedArrayBuffer, false>() const
v8::Value* v8::api_internal::IndirectHandleBase::value<v8::Value, true>() const
Line
Count
Source
85
2
  V8_INLINE T* value() const {
86
2
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
2
  }
Unexecuted instantiation: v8::ArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::ArrayBuffer, true>() const
v8::Integer* v8::api_internal::IndirectHandleBase::value<v8::Integer, false>() const
Line
Count
Source
85
1.00k
  V8_INLINE T* value() const {
86
1.00k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.00k
  }
Unexecuted instantiation: v8::Set* v8::api_internal::IndirectHandleBase::value<v8::Set, false>() const
v8::UnboundScript* v8::api_internal::IndirectHandleBase::value<v8::UnboundScript, false>() const
Line
Count
Source
85
2.85k
  V8_INLINE T* value() const {
86
2.85k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
2.85k
  }
v8::UnboundScript* v8::api_internal::IndirectHandleBase::value<v8::UnboundScript, true>() const
Line
Count
Source
85
953
  V8_INLINE T* value() const {
86
953
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
953
  }
v8::Message* v8::api_internal::IndirectHandleBase::value<v8::Message, false>() const
Line
Count
Source
85
1.44M
  V8_INLINE T* value() const {
86
1.44M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
1.44M
  }
v8::BigInt64Array* v8::api_internal::IndirectHandleBase::value<v8::BigInt64Array, false>() const
Line
Count
Source
85
244k
  V8_INLINE T* value() const {
86
244k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
244k
  }
Unexecuted instantiation: v8::StackFrame* v8::api_internal::IndirectHandleBase::value<v8::StackFrame, false>() const
Unexecuted instantiation: v8::StackTrace* v8::api_internal::IndirectHandleBase::value<v8::StackTrace, false>() const
Unexecuted instantiation: v8::BigInt* v8::api_internal::IndirectHandleBase::value<v8::BigInt, false>() const
Unexecuted instantiation: v8::WasmModuleObject* v8::api_internal::IndirectHandleBase::value<v8::WasmModuleObject, false>() const
v8::Map* v8::api_internal::IndirectHandleBase::value<v8::Map, false>() const
Line
Count
Source
85
24.0M
  V8_INLINE T* value() const {
86
24.0M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
87
24.0M
  }
Unexecuted instantiation: v8::Proxy* v8::api_internal::IndirectHandleBase::value<v8::Proxy, false>() const
Unexecuted instantiation: v8::External* v8::api_internal::IndirectHandleBase::value<v8::External, false>() const
Unexecuted instantiation: v8::WasmMemoryObject* v8::api_internal::IndirectHandleBase::value<v8::WasmMemoryObject, false>() const
Unexecuted instantiation: v8::WasmMemoryObject* v8::api_internal::IndirectHandleBase::value<v8::WasmMemoryObject, true>() const
Unexecuted instantiation: v8::ArrayBufferView* v8::api_internal::IndirectHandleBase::value<v8::ArrayBufferView, true>() const
Unexecuted instantiation: v8::TypedArray* v8::api_internal::IndirectHandleBase::value<v8::TypedArray, false>() const
Unexecuted instantiation: v8::DataView* v8::api_internal::IndirectHandleBase::value<v8::DataView, false>() const
Unexecuted instantiation: v8::FunctionTemplate* v8::api_internal::IndirectHandleBase::value<v8::FunctionTemplate, true>() const
88
89
 private:
90
  internal::Address* location_ = nullptr;
91
};
92
93
#ifdef V8_ENABLE_DIRECT_LOCAL
94
95
/**
96
 * A base class for abstract handles containing direct pointers.
97
 * These are only possible when conservative stack scanning is enabled.
98
 */
99
class DirectHandleBase {
100
 public:
101
  // Returns true if the handle is empty.
102
  V8_INLINE bool IsEmpty() const {
103
    return ptr_ == internal::ValueHelper::kEmpty;
104
  }
105
106
  // Sets the handle to be empty. IsEmpty() will then return true.
107
  V8_INLINE void Clear() { ptr_ = internal::ValueHelper::kEmpty; }
108
109
 protected:
110
  friend class internal::ValueHelper;
111
  friend class internal::HandleHelper;
112
113
  V8_INLINE DirectHandleBase() = default;
114
  V8_INLINE DirectHandleBase(const DirectHandleBase& other) = default;
115
  V8_INLINE DirectHandleBase& operator=(const DirectHandleBase& that) = default;
116
117
  V8_INLINE explicit DirectHandleBase(internal::Address ptr) : ptr_(ptr) {}
118
119
  // Returns the address of the referenced object.
120
  V8_INLINE internal::Address ptr() const { return ptr_; }
121
122
  // Returns the handler's "value" (direct pointer, as direct local support
123
  // is guaranteed to be enabled here).
124
  template <typename T, bool check_null = false>
125
  V8_INLINE T* value() const {
126
    return reinterpret_cast<T*>(ptr_);
127
  }
128
129
 private:
130
  internal::Address ptr_ = internal::ValueHelper::kEmpty;
131
};
132
133
#endif  // V8_ENABLE_DIRECT_LOCAL
134
135
}  // namespace v8::api_internal
136
137
#endif  // INCLUDE_V8_HANDLE_BASE_H_