Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Unified Diff: gin/wrappable.h

Issue 105743007: Gin: Make it easier to implement Wrappable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: blah Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gin/object_template_builder.h ('k') | gin/wrappable.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gin/wrappable.h
diff --git a/gin/wrappable.h b/gin/wrappable.h
index 741bf8ff6d11b72ef7a3ffc4297868aa2346adf4..84187048669643e5a82eacf9186cc6249f5a2e0c 100644
--- a/gin/wrappable.h
+++ b/gin/wrappable.h
@@ -11,62 +11,76 @@
namespace gin {
-// Wrappable is an abstract base class for C++ objects that have cooresponding
-// v8 wrapper objects. To retain a Wrappable object on the stack, use a
-// gin::Handle.
-class Wrappable {
- public:
- // Subclasses must return the WrapperInfo object associated with the
- // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for
- // this object, we'll look up the appropriate v8::ObjectTemplate in the
- // PerIsolateData using this WrapperInfo pointer.
- virtual WrapperInfo* GetWrapperInfo() = 0;
+template<typename T>
+struct WrappableTraits {
+ static WrapperInfo kWrapperInfo;
+};
- // Subclasses much also contain a static member variable named |kWrapperInfo|
- // of type WrapperInfo:
- //
- // static WrapperInfo kWrapperInfo;
- //
- // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo()
- // must return &kWrapperInfo.
- //
- // We use both the dynamic |GetWrapperInfo| function and the static
- // |kWrapperInfo| member variable during wrapping and the unwrapping. During
- // wrapping, we use GetWrapperInfo() to make sure we use the correct
- // v8::ObjectTemplate for the object regardless of the declared C++ type.
- // During unwrapping, we use the static member variable to prevent type errors
- // during the downcast from Wrappable to the subclass.
+template<typename T>
+WrapperInfo WrappableTraits<T>::kWrapperInfo = {
+ gin::kEmbedderNativeGin
+};
+
+struct WrappableTraitsTest {
+ static WrapperInfo* GetWrapperInfo();
+};
+
+
+// Wrappable is a base class for C++ objects that have cooresponding v8 wrapper
+// objects. To retain a Wrappable object on the stack, use a gin::Handle.
+//
+// Usage:
+// class MyClass : Wrappable<MyClass> {
+// ...
+// };
+//
+// Subclasses should have private constructors and expose a static Create
+// function that returns a gin::Handle. Forcing creators through this static
+// Create function will enforce that clients actually create a wrapper for the
+// object. If clients fail to create a wrapper for a wrappable object, the
+// object will leak because we use the weak callback from the wrapper as the
+// signal to delete the wrapped object.
+template<typename T>
+class Wrappable;
+
+class WrappableBase {
+ public:
// Retrieve (or create) the v8 wrapper object cooresponding to this object.
// To customize the wrapper created for a subclass, override GetWrapperInfo()
// instead of overriding this function.
v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate);
- // Subclasses should have private constructors and expose a static Create
- // function that returns a gin::Handle. Forcing creators through this static
- // Create function will enforce that clients actually create a wrapper for
- // the object. If clients fail to create a wrapper for a wrappable object,
- // the object will leak because we use the weak callback from the wrapper
- // as the signal to delete the wrapped object.
+ virtual WrapperInfo* GetWrapperInfo() = 0;
protected:
- Wrappable();
- virtual ~Wrappable();
+ WrappableBase();
+ virtual ~WrappableBase();
private:
static void WeakCallback(
- const v8::WeakCallbackData<v8::Object, Wrappable>& data);
+ const v8::WeakCallbackData<v8::Object, WrappableBase>& data);
v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate);
v8::Persistent<v8::Object> wrapper_; // Weak
- DISALLOW_COPY_AND_ASSIGN(Wrappable);
+ DISALLOW_COPY_AND_ASSIGN(WrappableBase);
+};
+
+
+template<typename T>
+class Wrappable : public WrappableBase {
+ public:
+ virtual WrapperInfo* GetWrapperInfo() {
Aaron Boodman 2013/12/06 22:40:55 I am kind of grumpy about the extra inheritance an
abarth-chromium 2013/12/06 23:03:10 It's a security check to catch a class of use-afte
+ return &WrappableTraits<T>::kWrapperInfo;
+ }
};
+
// This converter handles any subclass of Wrappable.
template<typename T>
struct Converter<T*, typename base::enable_if<
- base::is_convertible<T*, Wrappable*>::value>::type> {
+ base::is_convertible<T*, Wrappable<T>*>::value>::type> {
static v8::Handle<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
return val->GetWrapper(isolate);
}
@@ -85,7 +99,7 @@ struct Converter<T*, typename base::enable_if<
// If this fails, the object is managed by Gin, but it's not wrapping an
// instance of T.
- if (info != &T::kWrapperInfo)
+ if (info != &WrappableTraits<T>::kWrapperInfo)
return false;
void* pointer = obj->GetAlignedPointerFromInternalField(kEncodedValueIndex);
« no previous file with comments | « gin/object_template_builder.h ('k') | gin/wrappable.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698