summaryrefslogtreecommitdiff
path: root/deps/v8/include/v8-local-handle.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/include/v8-local-handle.h')
-rw-r--r--deps/v8/include/v8-local-handle.h129
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>