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 |