Chromium Code Reviews| Index: src/handles.h |
| diff --git a/src/handles.h b/src/handles.h |
| index bcd7eb23744fa2c631ffa1c43a58342f93604dc4..66bac001e585e8c3ddc9f27b3a603c0bc04e4121 100644 |
| --- a/src/handles.h |
| +++ b/src/handles.h |
| @@ -34,6 +34,50 @@ |
| namespace v8 { |
| namespace internal { |
| +template<typename T> |
| +class MaybeHandle { |
|
Michael Starzinger
2014/04/02 14:24:46
Can we get a few comments above this class about w
|
| + public: |
| + MaybeHandle() : location_(NULL) { } |
| + |
| + // Constructor for handling automatic up casting. |
| + // Ex. Handle<JSArray> can be passed when MaybeHandle<Object> is expected. |
| + template <class S> MaybeHandle(Handle<S> handle) { |
| +#ifdef DEBUG |
| + T* a = NULL; |
| + S* b = NULL; |
| + a = b; // Fake assignment to enforce type checks. |
| + USE(a); |
| +#endif |
| + this->location_ = reinterpret_cast<T**>(handle.location_); |
| + } |
| + |
| + static MaybeHandle<T> Exception() { |
| + return Handle<T>::null(); |
| + } |
| + |
| + INLINE(Handle<T> ToHandleChecked()) { |
| + CHECK(!is_null()); |
| + return Handle<T>(location_); |
| + } |
| + |
| + INLINE(bool ToHandle(Handle<T>* out)) { |
| + if (is_null()) { |
| + *out = Handle<T>::null(); |
| + return false; |
| + } else { |
| + *out = Handle<T>(location_); |
| + return true; |
| + } |
| + } |
| + |
| + INLINE(bool is_null()) const { return this->location_ == NULL; } |
| + |
| + protected: |
| + // To access location_ from derived Handle<T> classes, we need to explicitly |
| + // use this->location_, since the compiler does not resolve it correctly. |
| + T** location_; |
| +}; |
| + |
| // ---------------------------------------------------------------------------- |
| // A Handle provides a reference to an object that survives relocation by |
| // the garbage collector. |
| @@ -41,13 +85,13 @@ namespace internal { |
| // When a handle is created for an object a cell is allocated in the heap. |
| template<typename T> |
| -class Handle { |
| +class Handle : public MaybeHandle<T> { |
|
Toon Verwaest
2014/04/02 14:40:24
I find it pretty confusing that a "checked handle"
|
| public: |
| - INLINE(explicit Handle(T** location)) { location_ = location; } |
| + INLINE(explicit Handle(T** location)) { this->location_ = location; } |
| INLINE(explicit Handle(T* obj)); |
| INLINE(Handle(T* obj, Isolate* isolate)); |
| - INLINE(Handle()) : location_(NULL) {} |
| + INLINE(Handle()) {} |
|
Michael Starzinger
2014/04/02 14:24:46
As discussed offline: The ultimate goal of this en
|
| // Constructor for handling automatic up casting. |
| // Ex. Handle<JSFunction> can be passed when Handle<Object> is expected. |
| @@ -58,7 +102,7 @@ class Handle { |
| a = b; // Fake assignment to enforce type checks. |
| USE(a); |
| #endif |
| - location_ = reinterpret_cast<T**>(handle.location_); |
| + this->location_ = reinterpret_cast<T**>(handle.location_); |
| } |
| INLINE(T* operator->() const) { return operator*(); } |
| @@ -78,7 +122,6 @@ class Handle { |
| } |
| static Handle<T> null() { return Handle<T>(); } |
|
Michael Starzinger
2014/04/02 14:24:46
Likewise.
|
| - bool is_null() const { return location_ == NULL; } |
| // Closes the given scope, but lets this handle escape. See |
| // implementation in api.h. |
| @@ -91,10 +134,9 @@ class Handle { |
| #endif // DEBUG |
| private: |
| - T** location_; |
| - |
| // Handles of different classes are allowed to access each other's location_. |
| template<class S> friend class Handle; |
| + template<class S> friend class MaybeHandle; |
| }; |