| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef GIN_WRAPPABLE_H_ | 5 #ifndef GIN_WRAPPABLE_H_ |
| 6 #define GIN_WRAPPABLE_H_ | 6 #define GIN_WRAPPABLE_H_ |
| 7 | 7 |
| 8 #include "base/memory/ref_counted.h" | |
| 9 #include "gin/converter.h" | 8 #include "gin/converter.h" |
| 10 #include "gin/public/wrapper_info.h" | 9 #include "gin/public/wrapper_info.h" |
| 11 | 10 |
| 12 namespace gin { | 11 namespace gin { |
| 13 | 12 |
| 14 // Wrappable is an abstract base class for C++ objects that have cooresponding | 13 // Wrappable is an abstract base class for C++ objects that have cooresponding |
| 15 // v8 wrapper objects. Wrappable are RefCounted, which means they can be | 14 // v8 wrapper objects. To retain a Wrappable object on the stack, use a |
| 16 // retained either by V8's garbage collector or by a scoped_refptr. | 15 // gin::Handle. |
| 17 // | 16 class Wrappable { |
| 18 // WARNING: If you retain a Wrappable object with a scoped_refptr, it's possible | |
| 19 // that the v8 wrapper can "fall off" if the wrapper object is not | |
| 20 // referenced elsewhere in the V8 heap. Although Wrappable opens a | |
| 21 // handle to the wrapper object, we make that handle as weak, which | |
| 22 // means V8 is free to reclaim the wrapper. (We can't make the handle | |
| 23 // strong without risking introducing a memory leak if an object that | |
| 24 // holds a scoped_refptr is reachable from the wrapper.) | |
| 25 // | |
| 26 class Wrappable : public base::RefCounted<Wrappable> { | |
| 27 public: | 17 public: |
| 28 // Subclasses must return the WrapperInfo object associated with the | 18 // Subclasses must return the WrapperInfo object associated with the |
| 29 // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for | 19 // v8::ObjectTemplate for their subclass. When creating a v8 wrapper for |
| 30 // this object, we'll look up the appropriate v8::ObjectTemplate in the | 20 // this object, we'll look up the appropriate v8::ObjectTemplate in the |
| 31 // PerIsolateData using this WrapperInfo pointer. | 21 // PerIsolateData using this WrapperInfo pointer. |
| 32 virtual WrapperInfo* GetWrapperInfo() = 0; | 22 virtual WrapperInfo* GetWrapperInfo() = 0; |
| 33 | 23 |
| 34 // Subclasses much also contain a static member variable named |kWrapperInfo| | 24 // Subclasses much also contain a static member variable named |kWrapperInfo| |
| 35 // of type WrapperInfo: | 25 // of type WrapperInfo: |
| 36 // | 26 // |
| 37 // static WrapperInfo kWrapperInfo; | 27 // static WrapperInfo kWrapperInfo; |
| 38 // | 28 // |
| 39 // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo() | 29 // If |obj| is a concrete instance of the subclass, then obj->GetWrapperInfo() |
| 40 // must return &kWrapperInfo. | 30 // must return &kWrapperInfo. |
| 41 // | 31 // |
| 42 // We use both the dynamic |GetWrapperInfo| function and the static | 32 // We use both the dynamic |GetWrapperInfo| function and the static |
| 43 // |kWrapperInfo| member variable during wrapping and the unwrapping. During | 33 // |kWrapperInfo| member variable during wrapping and the unwrapping. During |
| 44 // wrapping, we use GetWrapperInfo() to make sure we use the correct | 34 // wrapping, we use GetWrapperInfo() to make sure we use the correct |
| 45 // v8::ObjectTemplate for the object regardless of the declared C++ type. | 35 // v8::ObjectTemplate for the object regardless of the declared C++ type. |
| 46 // During unwrapping, we use the static member variable to prevent type errors | 36 // During unwrapping, we use the static member variable to prevent type errors |
| 47 // during the downcast from Wrappable to the subclass. | 37 // during the downcast from Wrappable to the subclass. |
| 48 | 38 |
| 49 // Retrieve (or create) the v8 wrapper object cooresponding to this object. | 39 // Retrieve (or create) the v8 wrapper object cooresponding to this object. |
| 50 // To customize the wrapper created for a subclass, override GetWrapperInfo() | 40 // To customize the wrapper created for a subclass, override GetWrapperInfo() |
| 51 // instead of overriding this function. | 41 // instead of overriding this function. |
| 52 v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate); | 42 v8::Handle<v8::Object> GetWrapper(v8::Isolate* isolate); |
| 53 | 43 |
| 44 // Subclasses should have private constructors and expose a static Create |
| 45 // function that returns a gin::Handle. Forcing creators through this static |
| 46 // Create function will enforce that clients actually create a wrapper for |
| 47 // the object. If clients fail to create a wrapper for a wrappable object, |
| 48 // the object will leak because we use the weak callback from the wrapper |
| 49 // as the signal to delete the wrapped object. |
| 50 |
| 54 protected: | 51 protected: |
| 55 Wrappable(); | 52 Wrappable(); |
| 56 virtual ~Wrappable(); | 53 virtual ~Wrappable(); |
| 57 | 54 |
| 58 private: | 55 private: |
| 59 friend class base::RefCounted<Wrappable>; | |
| 60 friend struct Converter<Wrappable*>; | 56 friend struct Converter<Wrappable*>; |
| 61 | 57 |
| 62 static void WeakCallback( | 58 static void WeakCallback( |
| 63 const v8::WeakCallbackData<v8::Object, Wrappable>& data); | 59 const v8::WeakCallbackData<v8::Object, Wrappable>& data); |
| 64 v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); | 60 v8::Handle<v8::Object> CreateWrapper(v8::Isolate* isolate); |
| 65 | 61 |
| 66 v8::Persistent<v8::Object> wrapper_; // Weak | 62 v8::Persistent<v8::Object> wrapper_; // Weak |
| 67 | 63 |
| 68 DISALLOW_COPY_AND_ASSIGN(Wrappable); | 64 DISALLOW_COPY_AND_ASSIGN(Wrappable); |
| 69 }; | 65 }; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 90 // wrapped object. | 86 // wrapped object. |
| 91 // TODO(abarth): Support unwrapping to a base class. | 87 // TODO(abarth): Support unwrapping to a base class. |
| 92 *out = static_cast<T*>(wrappable); | 88 *out = static_cast<T*>(wrappable); |
| 93 return true; | 89 return true; |
| 94 } | 90 } |
| 95 }; | 91 }; |
| 96 | 92 |
| 97 } // namespace gin | 93 } // namespace gin |
| 98 | 94 |
| 99 #endif // GIN_WRAPPABLE_H_ | 95 #endif // GIN_WRAPPABLE_H_ |
| OLD | NEW |