Commit f8072dbd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[handles] Use is_convertible instead of is_base_of

std::is_base_of<A, B> has undefined behaviour if B is not a complete
type. Hence, avoid it and use is_convertible<B*, A*> instead.
This captures exactly the requirement that
  Handle<A> foo() { return produce<Handle<B>>(); }
is valid exactly if
  A* foo() { return produce<B>(); }
is valid.
Also, change some static asserts to enable_ifs in order to allow
overloading a function by different Handle types, which would cause
disambiguity otherwise.

R=tebbi@chromium.org

Change-Id: I60fbdfcfd96c7b216e42819a5b5de3423a2c38d0
Reviewed-on: https://chromium-review.googlesource.com/774841Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49440}
parent 3e0bf580
...@@ -23,7 +23,6 @@ class HandleScopeImplementer; ...@@ -23,7 +23,6 @@ class HandleScopeImplementer;
class Isolate; class Isolate;
class Object; class Object;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Base class for Handle instantiations. Don't use directly. // Base class for Handle instantiations. Don't use directly.
class HandleBase { class HandleBase {
...@@ -94,7 +93,8 @@ class Handle final : public HandleBase { ...@@ -94,7 +93,8 @@ class Handle final : public HandleBase {
V8_INLINE explicit Handle(T** location = nullptr) V8_INLINE explicit Handle(T** location = nullptr)
: HandleBase(reinterpret_cast<Object**>(location)) { : HandleBase(reinterpret_cast<Object**>(location)) {
// Type check: // Type check:
static_assert(std::is_base_of<Object, T>::value, "static type violation"); static_assert(std::is_convertible<T*, Object*>::value,
"static type violation");
} }
V8_INLINE explicit Handle(T* object); V8_INLINE explicit Handle(T* object);
...@@ -105,11 +105,9 @@ class Handle final : public HandleBase { ...@@ -105,11 +105,9 @@ class Handle final : public HandleBase {
// Constructor for handling automatic up casting. // Constructor for handling automatic up casting.
// Ex. Handle<JSFunction> can be passed when Handle<Object> is expected. // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected.
template <typename S> template <typename S, typename = typename std::enable_if<
V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) { std::is_convertible<S*, T*>::value>::type>
// Type check: V8_INLINE Handle(Handle<S> handle) : HandleBase(handle) {}
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
V8_INLINE T* operator->() const { return operator*(); } V8_INLINE T* operator->() const { return operator*(); }
...@@ -187,24 +185,19 @@ class MaybeHandle final { ...@@ -187,24 +185,19 @@ class MaybeHandle final {
// Constructor for handling automatic up casting from Handle. // Constructor for handling automatic up casting from Handle.
// Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected.
template <typename S> template <typename S, typename = typename std::enable_if<
std::is_convertible<S*, T*>::value>::type>
V8_INLINE MaybeHandle(Handle<S> handle) V8_INLINE MaybeHandle(Handle<S> handle)
: location_(reinterpret_cast<T**>(handle.location_)) { : location_(reinterpret_cast<T**>(handle.location_)) {}
// Type check:
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
// Constructor for handling automatic up casting. // Constructor for handling automatic up casting.
// Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected. // Ex. MaybeHandle<JSArray> can be passed when Handle<Object> is expected.
template <typename S> template <typename S, typename = typename std::enable_if<
std::is_convertible<S*, T*>::value>::type>
V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle) V8_INLINE MaybeHandle(MaybeHandle<S> maybe_handle)
: location_(reinterpret_cast<T**>(maybe_handle.location_)) { : location_(reinterpret_cast<T**>(maybe_handle.location_)) {}
// Type check:
static_assert(std::is_base_of<T, S>::value, "static type violation");
}
template <typename S> V8_INLINE MaybeHandle(T* object, Isolate* isolate)
V8_INLINE MaybeHandle(S* object, Isolate* isolate)
: MaybeHandle(handle(object, isolate)) {} : MaybeHandle(handle(object, isolate)) {}
V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); } V8_INLINE void Assert() const { DCHECK_NOT_NULL(location_); }
......
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