Coverage Report

Created: 2025-10-31 09:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/node/deps/v8/include/v8-handle-base.h
Line
Count
Source
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
38.0k
  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
#ifdef ENABLE_SLOW_DCHECKS
47
  V8_EXPORT void VerifyOnStack() const;
48
#else
49
0
  V8_INLINE V8_EXPORT void VerifyOnStack() const {}
50
#endif
51
};
52
53
/**
54
 * A base class for abstract handles containing indirect pointers.
55
 * These are useful regardless of whether direct local support is enabled.
56
 */
57
class IndirectHandleBase {
58
 public:
59
  // Returns true if the handle is empty.
60
10.0M
  V8_INLINE bool IsEmpty() const { return location_ == nullptr; }
61
62
  // Sets the handle to be empty. IsEmpty() will then return true.
63
774k
  V8_INLINE void Clear() { location_ = nullptr; }
64
65
 protected:
66
  friend class internal::ValueHelper;
67
  friend class internal::HandleHelper;
68
69
3.63M
  V8_INLINE IndirectHandleBase() = default;
70
  V8_INLINE IndirectHandleBase(const IndirectHandleBase& other) = default;
71
  V8_INLINE IndirectHandleBase& operator=(const IndirectHandleBase& that) =
72
      default;
73
74
  V8_INLINE explicit IndirectHandleBase(internal::Address* location)
75
849k
      : location_(location) {}
76
77
  // Returns the address of the actual heap object (tagged).
78
  // This method must be called only if the handle is not empty, otherwise it
79
  // will crash.
80
1.47M
  V8_INLINE internal::Address ptr() const { return *location_; }
81
82
  // Returns a reference to the slot (indirect pointer).
83
12.1M
  V8_INLINE internal::Address* const& slot() const { return location_; }
84
1.56M
  V8_INLINE internal::Address*& slot() { return location_; }
85
86
  // Returns the handler's "value" (direct or indirect pointer, depending on
87
  // whether direct local support is enabled).
88
  template <typename T, bool check_null = false>
89
12.1M
  V8_INLINE T* value() const {
90
12.1M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
12.1M
  }
v8::Value* v8::api_internal::IndirectHandleBase::value<v8::Value, false>() const
Line
Count
Source
89
1.64M
  V8_INLINE T* value() const {
90
1.64M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
1.64M
  }
Unexecuted instantiation: v8::Data* v8::api_internal::IndirectHandleBase::value<v8::Data, false>() const
v8::Object* v8::api_internal::IndirectHandleBase::value<v8::Object, false>() const
Line
Count
Source
89
319k
  V8_INLINE T* value() const {
90
319k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
319k
  }
v8::Context* v8::api_internal::IndirectHandleBase::value<v8::Context, false>() const
Line
Count
Source
89
8.43M
  V8_INLINE T* value() const {
90
8.43M
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
8.43M
  }
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
89
14.6k
  V8_INLINE T* value() const {
90
14.6k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
14.6k
  }
v8::Template* v8::api_internal::IndirectHandleBase::value<v8::Template, false>() const
Line
Count
Source
89
6.58k
  V8_INLINE T* value() const {
90
6.58k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
6.58k
  }
v8::Function* v8::api_internal::IndirectHandleBase::value<v8::Function, false>() const
Line
Count
Source
89
4.76k
  V8_INLINE T* value() const {
90
4.76k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
4.76k
  }
v8::ObjectTemplate* v8::api_internal::IndirectHandleBase::value<v8::ObjectTemplate, false>() const
Line
Count
Source
89
9.10k
  V8_INLINE T* value() const {
90
9.10k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
9.10k
  }
v8::Context* v8::api_internal::IndirectHandleBase::value<v8::Context, true>() const
Line
Count
Source
89
22.1k
  V8_INLINE T* value() const {
90
22.1k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
22.1k
  }
v8::Script* v8::api_internal::IndirectHandleBase::value<v8::Script, false>() const
Line
Count
Source
89
8.90k
  V8_INLINE T* value() const {
90
8.90k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
8.90k
  }
v8::Object* v8::api_internal::IndirectHandleBase::value<v8::Object, true>() const
Line
Count
Source
89
280
  V8_INLINE T* value() const {
90
280
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
280
  }
v8::Array* v8::api_internal::IndirectHandleBase::value<v8::Array, false>() const
Line
Count
Source
89
741k
  V8_INLINE T* value() const {
90
741k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
741k
  }
Unexecuted instantiation: v8::Number* v8::api_internal::IndirectHandleBase::value<v8::Number, false>() const
v8::DictionaryTemplate* v8::api_internal::IndirectHandleBase::value<v8::DictionaryTemplate, false>() const
Line
Count
Source
89
35
  V8_INLINE T* value() const {
90
35
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
35
  }
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
89
140
  V8_INLINE T* value() const {
90
140
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
140
  }
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
89
70
  V8_INLINE T* value() const {
90
70
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
70
  }
v8::Uint32Array* v8::api_internal::IndirectHandleBase::value<v8::Uint32Array, true>() const
Line
Count
Source
89
245
  V8_INLINE T* value() const {
90
245
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
245
  }
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
89
175
  V8_INLINE T* value() const {
90
175
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
175
  }
v8::BigInt64Array* v8::api_internal::IndirectHandleBase::value<v8::BigInt64Array, true>() const
Line
Count
Source
89
70
  V8_INLINE T* value() const {
90
70
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
70
  }
v8::Value* v8::api_internal::IndirectHandleBase::value<v8::Value, true>() const
Line
Count
Source
89
758k
  V8_INLINE T* value() const {
90
758k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
758k
  }
Unexecuted instantiation: v8::Function* v8::api_internal::IndirectHandleBase::value<v8::Function, true>() const
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
89
735
  V8_INLINE T* value() const {
90
735
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
735
  }
v8::String* v8::api_internal::IndirectHandleBase::value<v8::String, false>() const
Line
Count
Source
89
188k
  V8_INLINE T* value() const {
90
188k
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
188k
  }
v8::ArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::ArrayBuffer, false>() const
Line
Count
Source
89
770
  V8_INLINE T* value() const {
90
770
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
770
  }
v8::Int32Array* v8::api_internal::IndirectHandleBase::value<v8::Int32Array, false>() const
Line
Count
Source
89
105
  V8_INLINE T* value() const {
90
105
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
105
  }
v8::Uint32Array* v8::api_internal::IndirectHandleBase::value<v8::Uint32Array, false>() const
Line
Count
Source
89
245
  V8_INLINE T* value() const {
90
245
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
245
  }
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
89
175
  V8_INLINE T* value() const {
90
175
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
175
  }
v8::Float64Array* v8::api_internal::IndirectHandleBase::value<v8::Float64Array, false>() const
Line
Count
Source
89
175
  V8_INLINE T* value() const {
90
175
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
175
  }
Unexecuted instantiation: v8::Array* v8::api_internal::IndirectHandleBase::value<v8::Array, true>() const
Unexecuted instantiation: v8::Uint32* v8::api_internal::IndirectHandleBase::value<v8::Uint32, false>() const
Unexecuted instantiation: v8::ModuleRequest* v8::api_internal::IndirectHandleBase::value<v8::ModuleRequest, false>() const
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
89
35
  V8_INLINE T* value() const {
90
35
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
35
  }
Unexecuted instantiation: v8::Int32* v8::api_internal::IndirectHandleBase::value<v8::Int32, false>() const
v8::ArrayBufferView* v8::api_internal::IndirectHandleBase::value<v8::ArrayBufferView, false>() const
Line
Count
Source
89
105
  V8_INLINE T* value() const {
90
105
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
105
  }
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::Promise::Resolver* v8::api_internal::IndirectHandleBase::value<v8::Promise::Resolver, false>() const
Unexecuted instantiation: v8::ArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::ArrayBuffer, true>() const
Unexecuted instantiation: v8::SharedArrayBuffer* v8::api_internal::IndirectHandleBase::value<v8::SharedArrayBuffer, false>() const
Unexecuted instantiation: v8::Integer* v8::api_internal::IndirectHandleBase::value<v8::Integer, false>() const
Unexecuted instantiation: v8::Set* v8::api_internal::IndirectHandleBase::value<v8::Set, false>() const
v8::Boolean* v8::api_internal::IndirectHandleBase::value<v8::Boolean, false>() const
Line
Count
Source
89
105
  V8_INLINE T* value() const {
90
105
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
105
  }
Unexecuted instantiation: v8::Message* v8::api_internal::IndirectHandleBase::value<v8::Message, false>() const
v8::Name* v8::api_internal::IndirectHandleBase::value<v8::Name, false>() const
Line
Count
Source
89
280
  V8_INLINE T* value() const {
90
280
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
280
  }
Unexecuted instantiation: v8::UnboundScript* v8::api_internal::IndirectHandleBase::value<v8::UnboundScript, false>() const
Unexecuted instantiation: v8::UnboundScript* v8::api_internal::IndirectHandleBase::value<v8::UnboundScript, true>() const
v8::BigInt64Array* v8::api_internal::IndirectHandleBase::value<v8::BigInt64Array, false>() const
Line
Count
Source
89
70
  V8_INLINE T* value() const {
90
70
    return internal::ValueHelper::SlotAsValue<T, check_null>(slot());
91
70
  }
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::Promise* v8::api_internal::IndirectHandleBase::value<v8::Promise, true>() const
Unexecuted instantiation: v8::Promise::Resolver* v8::api_internal::IndirectHandleBase::value<v8::Promise::Resolver, true>() const
Unexecuted instantiation: v8::WasmModuleObject* v8::api_internal::IndirectHandleBase::value<v8::WasmModuleObject, false>() const
Unexecuted instantiation: v8::External* v8::api_internal::IndirectHandleBase::value<v8::External, false>() const
Unexecuted instantiation: v8::Map* v8::api_internal::IndirectHandleBase::value<v8::Map, false>() const
Unexecuted instantiation: v8::RegExp* v8::api_internal::IndirectHandleBase::value<v8::RegExp, false>() const
Unexecuted instantiation: v8::RegExp* v8::api_internal::IndirectHandleBase::value<v8::RegExp, true>() const
Unexecuted instantiation: v8::Proxy* v8::api_internal::IndirectHandleBase::value<v8::Proxy, false>() const
Unexecuted instantiation: v8::WasmMemoryObject* v8::api_internal::IndirectHandleBase::value<v8::WasmMemoryObject, true>() const
Unexecuted instantiation: v8::WasmMemoryObject* v8::api_internal::IndirectHandleBase::value<v8::WasmMemoryObject, false>() const
Unexecuted instantiation: v8::Map* v8::api_internal::IndirectHandleBase::value<v8::Map, 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
92
93
#ifdef V8_ENABLE_DIRECT_HANDLE
94
  V8_INLINE internal::ValueHelper::InternalRepresentationType repr() const {
95
    return location_ ? *location_ : internal::ValueHelper::kEmpty;
96
  }
97
#else
98
0
  V8_INLINE internal::ValueHelper::InternalRepresentationType repr() const {
99
0
    return location_;
100
0
  }
101
#endif  // V8_ENABLE_DIRECT_HANDLE
102
103
 private:
104
  internal::Address* location_ = nullptr;
105
};
106
107
#ifdef V8_ENABLE_DIRECT_HANDLE
108
109
/**
110
 * A base class for abstract handles containing direct pointers.
111
 * These are only possible when conservative stack scanning is enabled.
112
 */
113
class DirectHandleBase {
114
 public:
115
  // Returns true if the handle is empty.
116
  V8_INLINE bool IsEmpty() const {
117
    return ptr_ == internal::ValueHelper::kEmpty;
118
  }
119
120
  // Sets the handle to be empty. IsEmpty() will then return true.
121
  V8_INLINE void Clear() { ptr_ = internal::ValueHelper::kEmpty; }
122
123
 protected:
124
  friend class internal::ValueHelper;
125
  friend class internal::HandleHelper;
126
127
  V8_INLINE DirectHandleBase() = default;
128
  V8_INLINE DirectHandleBase(const DirectHandleBase& other) = default;
129
  V8_INLINE DirectHandleBase& operator=(const DirectHandleBase& that) = default;
130
131
  V8_INLINE explicit DirectHandleBase(internal::Address ptr) : ptr_(ptr) {}
132
133
  // Returns the address of the referenced object.
134
  V8_INLINE internal::Address ptr() const { return ptr_; }
135
136
  // Returns the handler's "value" (direct pointer, as direct local support
137
  // is guaranteed to be enabled here).
138
  template <typename T, bool check_null = false>
139
  V8_INLINE T* value() const {
140
    return reinterpret_cast<T*>(ptr_);
141
  }
142
143
  V8_INLINE internal::ValueHelper::InternalRepresentationType repr() const {
144
    return ptr_;
145
  }
146
147
 private:
148
  internal::Address ptr_ = internal::ValueHelper::kEmpty;
149
};
150
151
#endif  // V8_ENABLE_DIRECT_HANDLE
152
153
}  // namespace v8::api_internal
154
155
#endif  // INCLUDE_V8_HANDLE_BASE_H_