diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-06 14:07:07 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-12-06 14:07:07 +0000 |
commit | cf76c84a878ebeb2f469f1555b09f30046c5a352 (patch) | |
tree | 4267b6f9d37a71e0cf64c8d35ef6e062c75df259 /gin/wrappable.h | |
parent | 1b15e9baa48d9fa55865d4178e002e3e8c639270 (diff) | |
download | chromium_src-cf76c84a878ebeb2f469f1555b09f30046c5a352.zip chromium_src-cf76c84a878ebeb2f469f1555b09f30046c5a352.tar.gz chromium_src-cf76c84a878ebeb2f469f1555b09f30046c5a352.tar.bz2 |
Gin: Consolidate all the Converter<Wrappable> subclasses.
Review URL: https://codereview.chromium.org/107113005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@239204 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gin/wrappable.h')
-rw-r--r-- | gin/wrappable.h | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/gin/wrappable.h b/gin/wrappable.h index 0fa3697..741bf8f 100644 --- a/gin/wrappable.h +++ b/gin/wrappable.h @@ -5,6 +5,7 @@ #ifndef GIN_WRAPPABLE_H_ #define GIN_WRAPPABLE_H_ +#include "base/template_util.h" #include "gin/converter.h" #include "gin/public/wrapper_info.h" @@ -53,8 +54,6 @@ class Wrappable { virtual ~Wrappable(); private: - friend struct Converter<Wrappable*>; - static void WeakCallback( const v8::WeakCallbackData<v8::Object, Wrappable>& data); v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); @@ -64,28 +63,38 @@ class Wrappable { DISALLOW_COPY_AND_ASSIGN(Wrappable); }; -template<> -struct Converter<Wrappable*> { - static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, - Wrappable* val); - static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, - Wrappable** out); -}; - +// This converter handles any subclass of Wrappable. template<typename T> -struct WrappableConverter { +struct Converter<T*, typename base::enable_if< + base::is_convertible<T*, Wrappable*>::value>::type> { static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) { - return Converter<Wrappable*>::ToV8(isolate, val); + return val->GetWrapper(isolate); } + static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val, T** out) { - Wrappable* wrappable = NULL; - if (!Converter<Wrappable*>::FromV8(isolate, val, &wrappable) - || wrappable->GetWrapperInfo() != &T::kWrapperInfo) + if (!val->IsObject()) + return false; + v8::Handle<v8::Object> obj = v8::Handle<v8::Object>::Cast(val); + WrapperInfo* info = WrapperInfo::From(obj); + + // If this fails, the object is not managed by Gin. It is either a normal JS + // object that's not wrapping any external C++ object, or it is wrapping + // some C++ object, but that object isn't managed by Gin (maybe Blink). + if (!info) + return false; + + // If this fails, the object is managed by Gin, but it's not wrapping an + // instance of T. + if (info != &T::kWrapperInfo) return false; - // Currently we require that you unwrap to the exact runtime type of the - // wrapped object. - // TODO(abarth): Support unwrapping to a base class. - *out = static_cast<T*>(wrappable); + + void* pointer = obj->GetAlignedPointerFromInternalField(kEncodedValueIndex); + T* result = static_cast<T*>(pointer); + + // If this fails, something fishy is going on. |info| should have come from + // T::GetWrapperInfo(), but somehow is now different than it. So panic. + CHECK(result->GetWrapperInfo() == info); + *out = result; return true; } }; |