diff options
Diffstat (limited to 'deps/v8/include/v8-local-handle.h')
-rw-r--r-- | deps/v8/include/v8-local-handle.h | 129 |
1 files changed, 81 insertions, 48 deletions
diff --git a/deps/v8/include/v8-local-handle.h b/deps/v8/include/v8-local-handle.h index cbf87f949d..0dbbfdbc9f 100644 --- a/deps/v8/include/v8-local-handle.h +++ b/deps/v8/include/v8-local-handle.h @@ -50,9 +50,14 @@ class TracedReference; class TracedReferenceBase; class Utils; +namespace debug { +class ConsoleCallArguments; +} + namespace internal { template <typename T> class CustomArguments; +class SamplingHeapProfiler; } // namespace internal namespace api_internal { @@ -92,6 +97,9 @@ class V8_EXPORT V8_NODISCARD HandleScope { HandleScope(const HandleScope&) = delete; void operator=(const HandleScope&) = delete; + static internal::Address* CreateHandleForCurrentIsolate( + internal::Address value); + protected: V8_INLINE HandleScope() = default; @@ -122,6 +130,33 @@ class V8_EXPORT V8_NODISCARD HandleScope { friend class Context; }; +namespace internal { + +/** + * Helper functions about handles. + */ +class HandleHelper final { + public: + /** + * Checks whether two handles are equal. + * They are equal iff they are both empty or they are both non-empty and the + * objects to which they refer are physically equal. + * + * If both handles refer to JS objects, this is the same as strict equality. + * For primitives, such as numbers or strings, a `false` return value does not + * indicate that the values aren't equal in the JavaScript sense. + * Use `Value::StrictEquals()` to check primitives for equality. + */ + template <typename T1, typename T2> + V8_INLINE static bool EqualHandles(const T1& lhs, const T2& rhs) { + if (lhs.IsEmpty()) return rhs.IsEmpty(); + if (rhs.IsEmpty()) return false; + return lhs.address() == rhs.address(); + } +}; + +} // namespace internal + /** * An object reference managed by the v8 garbage collector. * @@ -154,7 +189,8 @@ class V8_EXPORT V8_NODISCARD HandleScope { template <class T> class Local { public: - V8_INLINE Local() : val_(nullptr) {} + V8_INLINE Local() : val_(internal::ValueHelper::EmptyValue<T>()) {} + template <class S> V8_INLINE Local(Local<S> that) : val_(reinterpret_cast<T*>(*that)) { /** @@ -168,55 +204,40 @@ class Local { /** * Returns true if the handle is empty. */ - V8_INLINE bool IsEmpty() const { return val_ == nullptr; } + V8_INLINE bool IsEmpty() const { + return val_ == internal::ValueHelper::EmptyValue<T>(); + } /** * Sets the handle to be empty. IsEmpty() will then return true. */ - V8_INLINE void Clear() { val_ = nullptr; } + V8_INLINE void Clear() { val_ = internal::ValueHelper::EmptyValue<T>(); } V8_INLINE T* operator->() const { return val_; } V8_INLINE T* operator*() const { return val_; } /** - * Checks whether two handles are the same. - * Returns true if both are empty, or if the objects to which they refer - * are identical. + * Checks whether two handles are equal or different. + * They are equal iff they are both empty or they are both non-empty and the + * objects to which they refer are physically equal. * - * If both handles refer to JS objects, this is the same as strict equality. - * For primitives, such as numbers or strings, a `false` return value does not - * indicate that the values aren't equal in the JavaScript sense. - * Use `Value::StrictEquals()` to check primitives for equality. + * If both handles refer to JS objects, this is the same as strict + * non-equality. For primitives, such as numbers or strings, a `true` return + * value does not indicate that the values aren't equal in the JavaScript + * sense. Use `Value::StrictEquals()` to check primitives for equality. */ + template <class S> V8_INLINE bool operator==(const Local<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); - internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); - if (a == nullptr) return b == nullptr; - if (b == nullptr) return false; - return *a == *b; + return internal::HandleHelper::EqualHandles(*this, that); } template <class S> V8_INLINE bool operator==(const PersistentBase<S>& that) const { - internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); - internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); - if (a == nullptr) return b == nullptr; - if (b == nullptr) return false; - return *a == *b; + return internal::HandleHelper::EqualHandles(*this, that); } - /** - * Checks whether two handles are different. - * Returns true if only one of the handles is empty, or if - * the objects to which they refer are different. - * - * If both handles refer to JS objects, this is the same as strict - * non-equality. For primitives, such as numbers or strings, a `true` return - * value does not indicate that the values aren't equal in the JavaScript - * sense. Use `Value::StrictEquals()` to check primitives for equality. - */ template <class S> V8_INLINE bool operator!=(const Local<S>& that) const { return !operator==(that); @@ -263,12 +284,12 @@ class Local { V8_INLINE static Local<T> New(Isolate* isolate, const PersistentBase<T>& that) { - return New(isolate, that.val_); + return New(isolate, internal::ValueHelper::SlotAsValue<T>(that.val_)); } V8_INLINE static Local<T> New(Isolate* isolate, const BasicTracedReference<T>& that) { - return New(isolate, *that); + return New(isolate, internal::ValueHelper::SlotAsValue<T>(*that)); } private: @@ -277,12 +298,6 @@ class Local { template <class F> friend class Eternal; template <class F> - friend class PersistentBase; - template <class F, class M> - friend class Persistent; - template <class F> - friend class Local; - template <class F> friend class MaybeLocal; template <class F> friend class FunctionCallbackInfo; @@ -309,19 +324,31 @@ class Local { friend class ReturnValue; template <class F> friend class Traced; - template <class F> - friend class BasicTracedReference; - template <class F> - friend class TracedReference; + friend class internal::SamplingHeapProfiler; + friend class internal::HandleHelper; + friend class debug::ConsoleCallArguments; explicit V8_INLINE Local(T* that) : val_(that) {} + + V8_INLINE internal::Address address() const { + return internal::ValueHelper::ValueAsAddress(val_); + } + + V8_INLINE static Local<T> FromSlot(internal::Address* slot) { + return Local<T>(internal::ValueHelper::SlotAsValue<T>(slot)); + } + V8_INLINE static Local<T> New(Isolate* isolate, T* that) { +#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING + return Local<T>(that); +#else if (that == nullptr) return Local<T>(); - T* that_ptr = that; - internal::Address* p = reinterpret_cast<internal::Address*>(that_ptr); + internal::Address* p = reinterpret_cast<internal::Address*>(that); return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( reinterpret_cast<internal::Isolate*>(isolate), *p))); +#endif } + T* val_; }; @@ -344,13 +371,15 @@ using Handle = Local<T>; template <class T> class MaybeLocal { public: - V8_INLINE MaybeLocal() : val_(nullptr) {} + V8_INLINE MaybeLocal() : val_(internal::ValueHelper::EmptyValue<T>()) {} template <class S> V8_INLINE MaybeLocal(Local<S> that) : val_(reinterpret_cast<T*>(*that)) { static_assert(std::is_base_of<T, S>::value, "type check"); } - V8_INLINE bool IsEmpty() const { return val_ == nullptr; } + V8_INLINE bool IsEmpty() const { + return val_ == internal::ValueHelper::EmptyValue<T>(); + } /** * Converts this MaybeLocal<> to a Local<>. If this MaybeLocal<> is empty, @@ -358,7 +387,7 @@ class MaybeLocal { */ template <class S> V8_WARN_UNUSED_RESULT V8_INLINE bool ToLocal(Local<S>* out) const { - out->val_ = IsEmpty() ? nullptr : this->val_; + out->val_ = IsEmpty() ? internal::ValueHelper::EmptyValue<T>() : this->val_; return !IsEmpty(); } @@ -367,7 +396,7 @@ class MaybeLocal { * V8 will crash the process. */ V8_INLINE Local<T> ToLocalChecked() { - if (V8_UNLIKELY(val_ == nullptr)) api_internal::ToLocalEmpty(); + if (V8_UNLIKELY(IsEmpty())) api_internal::ToLocalEmpty(); return Local<T>(val_); } @@ -399,9 +428,13 @@ class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope { */ template <class T> V8_INLINE Local<T> Escape(Local<T> value) { +#ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING + return value; +#else internal::Address* slot = Escape(reinterpret_cast<internal::Address*>(*value)); return Local<T>(reinterpret_cast<T*>(slot)); +#endif } template <class T> |