Commit 1413e4f5 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

Avoid Object::operator-> from Handle

Add an {ObjectRef} class to Handle which is returned by {operator->}.
Before, it returned {T} directly, and then used {T::operator->} for
the chained {operator->}.
As a drive-by, this CL also removes {HandleBase::operator*} and
implements this in {Handle<T>} directly.

R=jkummerow@chromium.org

Bug: v8:9183, v8:3770
Change-Id: I0a79fbbc393539543a62773c98a39c7bc2a84b77
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1624206Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61734}
parent 1d1567a3
......@@ -58,12 +58,6 @@ class HandleBase {
V8_INLINE Address address() const { return bit_cast<Address>(location_); }
protected:
// Provides the C++ dereference operator.
V8_INLINE Address operator*() const {
SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return *location_;
}
// Returns the address to where the raw pointer is stored.
V8_INLINE Address* location() const {
SLOW_DCHECK(location_ == nullptr ||
......@@ -101,6 +95,22 @@ class HandleBase {
template <typename T>
class Handle final : public HandleBase {
public:
// {ObjectRef} is returned by {Handle::operator->}. It should never be stored
// anywhere or used in any other code; no one should ever have to spell out
// {ObjectRef} in code. Its only purpose is to be dereferenced immediately by
// "operator-> chaining". Returning the address of the field is valid because
// this objects lifetime only ends at the end of the full statement.
class ObjectRef {
public:
T* operator->() { return &object_; }
private:
friend class Handle;
explicit ObjectRef(T object) : object_(object) {}
T object_;
};
V8_INLINE explicit Handle(Address* location = nullptr)
: HandleBase(location) {
// Type check:
......@@ -120,13 +130,13 @@ class Handle final : public HandleBase {
std::is_convertible<S*, T*>::value>::type>
V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) {}
V8_INLINE T operator->() const { return operator*(); }
V8_INLINE ObjectRef operator->() const { return ObjectRef{**this}; }
// Provides the C++ dereference operator.
V8_INLINE T operator*() const {
// unchecked_cast because we rather trust Handle<T> to contain a T than
// include all the respective -inl.h headers for SLOW_DCHECKs.
return T::unchecked_cast(Object(HandleBase::operator*()));
SLOW_DCHECK(IsDereferenceAllowed(INCLUDE_DEFERRED_CHECK));
return T::unchecked_cast(Object(*location()));
}
// Returns the address to where the raw pointer is stored.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment