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; |
}; |