v8 11.3.244 (node 20.3.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-local-handle.h
Go to the documentation of this file.
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_LOCAL_HANDLE_H_
6#define INCLUDE_V8_LOCAL_HANDLE_H_
7
8#include <stddef.h>
9
10#include <type_traits>
11
12#include "v8-internal.h" // NOLINT(build/include_directory)
13
14namespace v8 {
15
16class Boolean;
17template <class T>
18class BasicTracedReference;
19class Context;
20class EscapableHandleScope;
21template <class F>
22class Eternal;
23template <class F>
24class FunctionCallbackInfo;
25class Isolate;
26template <class F>
27class MaybeLocal;
28template <class T>
29class NonCopyablePersistentTraits;
30class Object;
31template <class T, class M = NonCopyablePersistentTraits<T>>
32class Persistent;
33template <class T>
34class PersistentBase;
35template <class F1, class F2, class F3>
36class PersistentValueMapBase;
37template <class F1, class F2>
39class Primitive;
40class Private;
41template <class F>
43template <class F>
44class ReturnValue;
45class String;
46template <class F>
47class Traced;
48template <class F>
49class TracedReference;
51class Utils;
52
53namespace debug {
54class ConsoleCallArguments;
55}
56
57namespace internal {
58template <typename T>
60class SamplingHeapProfiler;
61} // namespace internal
62
63namespace api_internal {
64// Called when ToLocalChecked is called on an empty Local.
66} // namespace api_internal
67
83 public:
84 explicit HandleScope(Isolate* isolate);
85
87
91 static int NumberOfHandles(Isolate* isolate);
92
94 return reinterpret_cast<Isolate*>(i_isolate_);
95 }
96
97 HandleScope(const HandleScope&) = delete;
98 void operator=(const HandleScope&) = delete;
99
101 internal::Address value);
102
103 protected:
105
106 void Initialize(Isolate* isolate);
107
108 static internal::Address* CreateHandle(internal::Isolate* i_isolate,
109 internal::Address value);
110
111 private:
112 // Declaring operator new and delete as deleted is not spec compliant.
113 // Therefore declare them private instead to disable dynamic alloc
114 void* operator new(size_t size);
115 void* operator new[](size_t size);
116 void operator delete(void*, size_t);
117 void operator delete[](void*, size_t);
118
119 internal::Isolate* i_isolate_;
120 internal::Address* prev_next_;
121 internal::Address* prev_limit_;
122
123 // Local::New uses CreateHandle with an Isolate* parameter.
124 template <class F>
125 friend class Local;
126
127 // Object::GetInternalField and Context::GetEmbedderData use CreateHandle with
128 // a HeapObject in their shortcuts.
129 friend class Object;
130 friend class Context;
131};
132
133namespace internal {
134
138class HandleHelper final {
139 public:
150 template <typename T1, typename T2>
151 V8_INLINE static bool EqualHandles(const T1& lhs, const T2& rhs) {
152 if (lhs.IsEmpty()) return rhs.IsEmpty();
153 if (rhs.IsEmpty()) return false;
154 return lhs.address() == rhs.address();
155 }
156};
157
158} // namespace internal
159
189template <class T>
190class Local {
191 public:
192 V8_INLINE Local() : val_(internal::ValueHelper::EmptyValue<T>()) {}
193
194 template <class S>
195 V8_INLINE Local(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
201 static_assert(std::is_base_of<T, S>::value, "type check");
202 }
203
207 V8_INLINE bool IsEmpty() const {
208 return val_ == internal::ValueHelper::EmptyValue<T>();
209 }
210
214 V8_INLINE void Clear() { val_ = internal::ValueHelper::EmptyValue<T>(); }
215
216 V8_INLINE T* operator->() const { return val_; }
217
218 V8_INLINE T* operator*() const { return val_; }
219
231 template <class S>
232 V8_INLINE bool operator==(const Local<S>& that) const {
233 return internal::HandleHelper::EqualHandles(*this, that);
234 }
235
236 template <class S>
237 V8_INLINE bool operator==(const PersistentBase<S>& that) const {
238 return internal::HandleHelper::EqualHandles(*this, that);
239 }
240
241 template <class S>
242 V8_INLINE bool operator!=(const Local<S>& that) const {
243 return !operator==(that);
244 }
245
246 template <class S>
247 V8_INLINE bool operator!=(const Persistent<S>& that) const {
248 return !operator==(that);
249 }
250
256 template <class S>
258#ifdef V8_ENABLE_CHECKS
259 // If we're going to perform the type check then we have to check
260 // that the handle isn't empty before doing the checked cast.
261 if (that.IsEmpty()) return Local<T>();
262#endif
263 return Local<T>(T::Cast(*that));
264 }
265
271 template <class S>
273 return Local<S>::Cast(*this);
274 }
275
281 V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that) {
282 return New(isolate, that.val_);
283 }
284
285 V8_INLINE static Local<T> New(Isolate* isolate,
286 const PersistentBase<T>& that) {
287 return New(isolate, internal::ValueHelper::SlotAsValue<T>(that.val_));
288 }
289
290 V8_INLINE static Local<T> New(Isolate* isolate,
291 const BasicTracedReference<T>& that) {
292 return New(isolate, internal::ValueHelper::SlotAsValue<T>(*that));
293 }
294
295 private:
297 friend class Utils;
298 template <class F>
299 friend class Eternal;
300 template <class F>
301 friend class MaybeLocal;
302 template <class F>
304 template <class F>
306 friend class String;
307 friend class Object;
308 friend class Context;
309 friend class Isolate;
310 friend class Private;
311 template <class F>
313 friend Local<Primitive> Undefined(Isolate* isolate);
314 friend Local<Primitive> Null(Isolate* isolate);
315 friend Local<Boolean> True(Isolate* isolate);
316 friend Local<Boolean> False(Isolate* isolate);
317 friend class HandleScope;
319 template <class F1, class F2, class F3>
321 template <class F1, class F2>
323 template <class F>
324 friend class ReturnValue;
325 template <class F>
326 friend class Traced;
330
331 explicit V8_INLINE Local(T* that) : val_(that) {}
332
333 V8_INLINE internal::Address address() const {
335 }
336
337 V8_INLINE static Local<T> FromSlot(internal::Address* slot) {
338 return Local<T>(internal::ValueHelper::SlotAsValue<T>(slot));
339 }
340
341 V8_INLINE static Local<T> New(Isolate* isolate, T* that) {
342#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
343 return Local<T>(that);
344#else
345 if (that == nullptr) return Local<T>();
346 internal::Address* p = reinterpret_cast<internal::Address*>(that);
347 return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle(
348 reinterpret_cast<internal::Isolate*>(isolate), *p)));
349#endif
350 }
351
352 T* val_;
353};
354
355#if !defined(V8_IMMINENT_DEPRECATION_WARNINGS)
356// Handle is an alias for Local for historical reasons.
357template <class T>
359#endif
360
371template <class T>
373 public:
374 V8_INLINE MaybeLocal() : val_(internal::ValueHelper::EmptyValue<T>()) {}
375 template <class S>
376 V8_INLINE MaybeLocal(Local<S> that) : val_(reinterpret_cast<T*>(*that)) {
377 static_assert(std::is_base_of<T, S>::value, "type check");
378 }
379
380 V8_INLINE bool IsEmpty() const {
381 return val_ == internal::ValueHelper::EmptyValue<T>();
382 }
383
388 template <class S>
390 out->val_ = IsEmpty() ? internal::ValueHelper::EmptyValue<T>() : this->val_;
391 return !IsEmpty();
392 }
393
400 return Local<T>(val_);
401 }
402
407 template <class S>
408 V8_INLINE Local<S> FromMaybe(Local<S> default_value) const {
409 return IsEmpty() ? default_value : Local<S>(val_);
410 }
411
412 private:
413 T* val_;
414};
415
421 public:
422 explicit EscapableHandleScope(Isolate* isolate);
424
429 template <class T>
431#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
432 return value;
433#else
434 internal::Address* slot =
435 Escape(reinterpret_cast<internal::Address*>(*value));
436 return Local<T>(reinterpret_cast<T*>(slot));
437#endif
438 }
439
440 template <class T>
442 return Escape(value.FromMaybe(Local<T>()));
443 }
444
446 void operator=(const EscapableHandleScope&) = delete;
447
448 private:
449 // Declaring operator new and delete as deleted is not spec compliant.
450 // Therefore declare them private instead to disable dynamic alloc
451 void* operator new(size_t size);
452 void* operator new[](size_t size);
453 void operator delete(void*, size_t);
454 void operator delete[](void*, size_t);
455
456 internal::Address* Escape(internal::Address* escape_value);
457 internal::Address* escape_slot_;
458};
459
466 public:
467 explicit SealHandleScope(Isolate* isolate);
469
471 void operator=(const SealHandleScope&) = delete;
472
473 private:
474 // Declaring operator new and delete as deleted is not spec compliant.
475 // Therefore declare them private instead to disable dynamic alloc
476 void* operator new(size_t size);
477 void* operator new[](size_t size);
478 void operator delete(void*, size_t);
479 void operator delete[](void*, size_t);
480
481 internal::Isolate* const i_isolate_;
482 internal::Address* prev_limit_;
483 int prev_sealed_level_;
484};
485
486} // namespace v8
487
488#endif // INCLUDE_V8_LOCAL_HANDLE_H_
EscapableHandleScope(const EscapableHandleScope &)=delete
void operator=(const EscapableHandleScope &)=delete
V8_INLINE Local< T > Escape(Local< T > value)
EscapableHandleScope(Isolate *isolate)
V8_INLINE MaybeLocal< T > EscapeMaybe(MaybeLocal< T > value)
V8_INLINE ~EscapableHandleScope()=default
void Initialize(Isolate *isolate)
V8_INLINE HandleScope()=default
static int NumberOfHandles(Isolate *isolate)
V8_INLINE Isolate * GetIsolate() const
HandleScope(const HandleScope &)=delete
static internal::Address * CreateHandleForCurrentIsolate(internal::Address value)
HandleScope(Isolate *isolate)
void operator=(const HandleScope &)=delete
static internal::Address * CreateHandle(internal::Isolate *i_isolate, internal::Address value)
friend Local< Primitive > Null(Isolate *isolate)
V8_INLINE T * operator->() const
V8_INLINE Local(Local< S > that)
V8_INLINE bool operator!=(const Local< S > &that) const
static V8_INLINE Local< T > New(Isolate *isolate, const PersistentBase< T > &that)
static V8_INLINE Local< T > Cast(Local< S > that)
V8_INLINE bool IsEmpty() const
V8_INLINE bool operator==(const Local< S > &that) const
friend Local< Boolean > False(Isolate *isolate)
friend Local< Primitive > Undefined(Isolate *isolate)
static V8_INLINE Local< T > New(Isolate *isolate, const BasicTracedReference< T > &that)
V8_INLINE Local< S > As() const
V8_INLINE bool operator==(const PersistentBase< S > &that) const
friend Local< Boolean > True(Isolate *isolate)
V8_INLINE Local()
V8_INLINE void Clear()
friend class debug::ConsoleCallArguments
friend class Isolate
friend class Utils
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
friend class internal::SamplingHeapProfiler
V8_INLINE T * operator*() const
V8_INLINE bool operator!=(const Persistent< S > &that) const
V8_INLINE Local< T > ToLocalChecked()
V8_INLINE bool IsEmpty() const
V8_INLINE MaybeLocal(Local< S > that)
V8_INLINE MaybeLocal()
V8_INLINE Local< S > FromMaybe(Local< S > default_value) const
V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local< S > *out) const
void operator=(const SealHandleScope &)=delete
SealHandleScope(Isolate *isolate)
SealHandleScope(const SealHandleScope &)=delete
static V8_INLINE bool EqualHandles(const T1 &lhs, const T2 &rhs)
static V8_INLINE Address ValueAsAddress(const T *value)
internal::BasicPersistent< T, internal::StrongPersistentPolicy > Persistent
Definition persistent.h:359
V8_EXPORT void ToLocalEmpty()
uintptr_t Address
Definition v8-internal.h:29
#define V8_EXPORT
Definition v8config.h:719
#define V8_INLINE
Definition v8config.h:460
#define V8_WARN_UNUSED_RESULT
Definition v8config.h:609
#define V8_UNLIKELY(condition)
Definition v8config.h:598
#define V8_NODISCARD
Definition v8config.h:623