v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
maybe-handles.h
Go to the documentation of this file.
1// Copyright 2011 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 V8_HANDLES_MAYBE_HANDLES_H_
6#define V8_HANDLES_MAYBE_HANDLES_H_
7
8#include <type_traits>
9
10#include "src/handles/handles.h"
11
12namespace v8 {
13namespace internal {
14
16
18
19// ----------------------------------------------------------------------------
20// A Handle can be converted into a MaybeHandle. Converting a MaybeHandle
21// into a Handle requires checking that it does not point to nullptr. This
22// ensures nullptr checks before use.
23//
24// Also note that MaybeHandles do not provide default equality comparison or
25// hashing operators on purpose. Such operators would be misleading, because
26// intended semantics is ambiguous between handle location and object identity.
27template <typename T>
28class MaybeHandle final {
29 public:
31
33
34 // Constructor for handling automatic up casting from Handle.
35 // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
36 template <typename S>
40
41 // Constructor for handling automatic up casting.
42 // Ex. MaybeHandle<JSArray> can be passed when MaybeHandle<Object> is
43 // expected.
44 template <typename S>
46 requires(is_subtype_v<S, T>)
47 : location_(maybe_handle.location_) {}
48
49 V8_INLINE MaybeHandle(Tagged<T> object, Isolate* isolate);
50 V8_INLINE MaybeHandle(Tagged<T> object, LocalHeap* local_heap);
51
54
56 Check();
57 return Handle<T>(location_);
58 }
59
60 // Convert to a Handle with a type that can be upcasted to.
61 template <typename S>
63 if (location_ == nullptr) {
64 *out = Handle<T>::null();
65 return false;
66 } else {
67 *out = Handle<T>(location_);
68 return true;
69 }
70 }
71
72 template <typename S>
74
75 // Location equality.
76 bool equals(MaybeHandle<T> other) const {
77 return address() == other.address();
78 }
79
80 // Returns the raw address where this handle is stored. This should only be
81 // used for hashing handles; do not ever try to dereference it.
83 return reinterpret_cast<Address>(location_);
84 }
85
86 bool is_null() const { return location_ == nullptr; }
87
88 protected:
89 V8_INLINE explicit MaybeHandle(Address* location) : location_(location) {}
90
91 Address* location_ = nullptr;
92
93 // MaybeHandles of different classes are allowed to access each
94 // other's location_.
95 template <typename>
96 friend class MaybeHandle;
97#ifdef V8_ENABLE_DIRECT_HANDLE
98 template <typename>
99 friend class MaybeDirectHandle;
100#endif
101 // Casts are allowed to access location_.
102 template <typename To, typename From>
104};
105
106template <typename T>
107std::ostream& operator<<(std::ostream& os, MaybeIndirectHandle<T> handle);
108
109// A handle which contains a potentially weak pointer. Keeps it alive (strongly)
110// while the MaybeObjectHandle is alive.
112 public:
114 : reference_type_(HeapObjectReferenceType::STRONG) {}
115 inline MaybeObjectHandle(Tagged<MaybeObject> object, Isolate* isolate);
116 inline MaybeObjectHandle(Tagged<Object> object, Isolate* isolate);
117 inline MaybeObjectHandle(Tagged<Smi> object, Isolate* isolate);
118 inline MaybeObjectHandle(Tagged<MaybeObject> object, LocalHeap* local_heap);
119 inline MaybeObjectHandle(Tagged<Object> object, LocalHeap* local_heap);
120 inline MaybeObjectHandle(Tagged<Smi> object, LocalHeap* local_heap);
121 inline explicit MaybeObjectHandle(Handle<Object> object);
122
123 static inline MaybeObjectHandle Weak(Tagged<Object> object, Isolate* isolate);
124 static inline MaybeObjectHandle Weak(Handle<Object> object);
125
126 inline Tagged<MaybeObject> operator*() const;
127 inline Tagged<MaybeObject> operator->() const;
128 inline IndirectHandle<Object> object() const;
129
130 inline bool is_identical_to(const MaybeObjectHandle& other) const;
131 bool is_null() const { return handle_.is_null(); }
132
133 HeapObjectReferenceType reference_type() const { return reference_type_; }
134
135 private:
136 inline MaybeObjectHandle(Tagged<Object> object,
137 HeapObjectReferenceType reference_type,
138 Isolate* isolate);
139 inline MaybeObjectHandle(Handle<Object> object,
140 HeapObjectReferenceType reference_type);
141
143
144 HeapObjectReferenceType reference_type_;
146};
147
148#ifdef V8_ENABLE_DIRECT_HANDLE
149
150template <typename T>
151class MaybeDirectHandle final {
152 public:
153 V8_INLINE MaybeDirectHandle() = default;
154
156
157 // Constructor for handling automatic up casting from DirectHandle.
158 // Ex. DirectHandle<JSArray> can be passed when MaybeDirectHandle<Object> is
159 // expected.
160 template <typename S, typename = std::enable_if_t<is_subtype_v<S, T>>>
162 : location_(handle.address()) {}
163
164 // Constructor for handling automatic up casting from Handle.
165 // Ex. Handle<JSArray> can be passed when MaybeDirectHandle<Object> is
166 // expected.
167 template <typename S, typename = std::enable_if_t<is_subtype_v<S, T>>>
170
171 // Constructor for handling automatic up casting.
172 // Ex. MaybeDirectHandle<JSArray> can be passed when MaybeDirectHandle<Object>
173 // is expected.
174 template <typename S, typename = std::enable_if_t<is_subtype_v<S, T>>>
176 : location_(maybe_handle.location_) {}
177
178 // Constructor for handling automatic up casting from MaybeHandle.
179 // Ex. MaybeHandle<JSArray> can be passed when
180 // MaybeDirectHandle<Object> is expected.
181 template <typename S, typename = std::enable_if_t<is_subtype_v<S, T>>>
183 : location_(maybe_handle.location_ == nullptr ? kTaggedNullAddress
184 : *maybe_handle.location_) {
185 }
186
187 V8_INLINE MaybeDirectHandle(Tagged<T> object, Isolate* isolate);
188 V8_INLINE MaybeDirectHandle(Tagged<T> object, LocalHeap* local_heap);
189
192
194 Check();
196 }
197
198 // Convert to a DirectHandle with a type that can be upcasted to.
199 template <typename S>
202 *out = DirectHandle<T>::null();
203 return false;
204 } else {
206 return true;
207 }
208 }
209
210 // Address equality.
211 bool equals(MaybeHandle<T> other) const {
212 return address() == other.address();
213 }
214
215 // Returns the raw address where this direct handle is stored.
216 V8_INLINE Address address() const { return location_; }
217
218 bool is_null() const { return location_ == kTaggedNullAddress; }
219
220 protected:
221 V8_INLINE explicit MaybeDirectHandle(Address location)
222 : location_(location) {}
223
225
226 // MaybeDirectHandles of different classes are allowed to access each
227 // other's location_.
228 template <typename>
229 friend class MaybeDirectHandle;
230 template <typename>
231 friend class MaybeHandle;
232 // Casts are allowed to access location_.
233 template <typename To, typename From>
236};
237
238#else
239
240template <typename T>
242 public:
245
247 : handle_(object, isolate) {}
249 : handle_(object, isolate) {}
251 : handle_(object, local_heap) {}
252
253 template <typename S>
257 template <typename S>
261 template <typename S>
265 template <typename S>
269
270 V8_INLINE void Assert() const { handle_.Assert(); }
271 V8_INLINE void Check() const { handle_.Check(); }
272
274 return handle_.ToHandleChecked();
275 }
276 template <typename S>
278 return handle_.ToHandle(out);
279 }
280
281 V8_INLINE bool is_null() const { return handle_.is_null(); }
282
283 private:
284 // DirectHandle is allowed to access handle_.
285 template <typename>
286 friend class DirectHandle;
287 // MaybeDirectHandle of different classes are allowed to access each other's
288 // handle_.
289 template <typename>
290 friend class MaybeDirectHandle;
291 // Casts are allowed to access handle_.
292 template <typename To, typename From>
295 template <typename U>
297 Isolate*);
298 template <typename U>
300 LocalIsolate*);
301
303};
304
305#endif // V8_ENABLE_DIRECT_HANDLE
306
307template <typename T>
308std::ostream& operator<<(std::ostream& os, MaybeDirectHandle<T> handle);
309
311 public:
313 : reference_type_(HeapObjectReferenceType::STRONG) {}
314 inline MaybeObjectDirectHandle(Tagged<MaybeObject> object, Isolate* isolate);
315 inline MaybeObjectDirectHandle(Tagged<Object> object, Isolate* isolate);
316 inline MaybeObjectDirectHandle(Tagged<Smi> object, Isolate* isolate);
318 LocalHeap* local_heap);
319 inline MaybeObjectDirectHandle(Tagged<Object> object, LocalHeap* local_heap);
320 inline MaybeObjectDirectHandle(Tagged<Smi> object, LocalHeap* local_heap);
322 : reference_type_(HeapObjectReferenceType::STRONG), handle_(object) {}
323
325
326 static inline MaybeObjectDirectHandle Weak(Tagged<Object> object,
327 Isolate* isolate);
329 return MaybeObjectDirectHandle(object, HeapObjectReferenceType::WEAK);
330 }
331
332 inline Tagged<MaybeObject> operator*() const;
333 inline Tagged<MaybeObject> operator->() const;
335 return handle_.ToHandleChecked();
336 }
337
338 inline bool is_identical_to(const MaybeObjectDirectHandle& other) const;
339 inline bool is_identical_to(const MaybeObjectHandle& other) const;
340 bool is_null() const { return handle_.is_null(); }
341
342 HeapObjectReferenceType reference_type() const { return reference_type_; }
343
344 private:
346 HeapObjectReferenceType reference_type,
347 Isolate* isolate);
349 HeapObjectReferenceType reference_type)
351
352 HeapObjectReferenceType reference_type_;
354};
355
356} // namespace internal
357} // namespace v8
358
359#endif // V8_HANDLES_MAYBE_HANDLES_H_
static V8_INLINE const DirectHandle null()
Definition handles.h:661
V8_INLINE MaybeDirectHandle(IndirectHandle< S > handle)
V8_INLINE MaybeDirectHandle(Tagged< T > object, LocalIsolate *isolate)
V8_INLINE DirectHandle< T > ToHandleChecked() const
V8_INLINE void Check() const
friend MaybeIndirectHandle< U > indirect_handle(MaybeDirectHandle< U >, LocalIsolate *)
V8_INLINE MaybeDirectHandle(MaybeDirectHandle< S > handle)
friend MaybeIndirectHandle< U > indirect_handle(MaybeDirectHandle< U >, Isolate *)
friend MaybeDirectHandle< To > UncheckedCast(MaybeDirectHandle< From > value)
V8_INLINE MaybeDirectHandle(NullMaybeHandleType)
V8_INLINE MaybeDirectHandle(Tagged< T > object, LocalHeap *local_heap)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
V8_INLINE MaybeDirectHandle(DirectHandle< S > handle)
V8_INLINE MaybeDirectHandle(Tagged< T > object, Isolate *isolate)
V8_INLINE MaybeDirectHandle(MaybeIndirectHandle< S > handle)
MaybeIndirectHandle< T > handle_
V8_INLINE MaybeDirectHandle()=default
V8_INLINE void Assert() const
V8_INLINE bool is_null() const
V8_INLINE Handle< T > ToHandleChecked() const
bool equals(MaybeHandle< T > other) const
V8_INLINE MaybeHandle()=default
V8_INLINE MaybeHandle(MaybeHandle< S > maybe_handle)
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(Handle< S > *out) const
friend MaybeIndirectHandle< To > UncheckedCast(MaybeHandle< From > value)
V8_INLINE MaybeHandle(NullMaybeHandleType)
V8_INLINE MaybeHandle(Handle< S > handle)
V8_INLINE void Assert() const
V8_WARN_UNUSED_RESULT V8_INLINE bool ToHandle(DirectHandle< S > *out) const
V8_INLINE Address address() const
V8_INLINE MaybeHandle(Address *location)
V8_INLINE void Check() const
bool is_identical_to(const MaybeObjectDirectHandle &other) const
MaybeDirectHandle< Object > handle_
Tagged< MaybeObject > operator*() const
static MaybeObjectDirectHandle Weak(DirectHandle< Object > object)
HeapObjectReferenceType reference_type_
MaybeObjectDirectHandle(DirectHandle< Object > object)
MaybeObjectDirectHandle(DirectHandle< Object > object, HeapObjectReferenceType reference_type)
HeapObjectReferenceType reference_type() const
DirectHandle< Object > object() const
Tagged< MaybeObject > operator->() const
static MaybeObjectDirectHandle Weak(Tagged< Object > object, Isolate *isolate)
HeapObjectReferenceType reference_type_
bool is_identical_to(const MaybeObjectHandle &other) const
static MaybeObjectHandle Weak(Tagged< Object > object, Isolate *isolate)
Tagged< MaybeObject > operator->() const
HeapObjectReferenceType reference_type() const
IndirectHandle< Object > object() const
Tagged< MaybeObject > operator*() const
MaybeHandle< Object > handle_
STRONG
Definition globals.h:1033
LinkageLocation location_
V8_INLINE IndirectHandle< T > handle(Tagged< T > object, Isolate *isolate)
Definition handles-inl.h:72
constexpr NullMaybeHandleType kNullMaybeHandle
constexpr Address kTaggedNullAddress
Definition handles.h:53
MaybeHandle< T > MaybeIndirectHandle
Definition globals.h:1109
static constexpr bool is_subtype_v
Definition tagged.h:121
std::ostream & operator<<(std::ostream &os, AtomicMemoryOrder order)
constexpr int S
Local< T > Handle
uint32_t equals
#define DCHECK_NOT_NULL(val)
Definition logging.h:492
#define CHECK_NOT_NULL(val)
#define DCHECK_NE(v1, v2)
Definition logging.h:486
#define CHECK_NE(lhs, rhs)
#define V8_INLINE
Definition v8config.h:500
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:671