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

Side by Side Diff: gin/wrappable.h

Issue 1161923004: Reland: Plugin Placeholders: Refactor for platforms that don't support plugins (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Merge to solve patch conflicts again... Created 5 years, 6 months 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 unified diff | Download patch
OLDNEW
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/logging.h"
8 #include "base/template_util.h" 9 #include "base/template_util.h"
9 #include "gin/converter.h" 10 #include "gin/converter.h"
10 #include "gin/gin_export.h" 11 #include "gin/gin_export.h"
11 #include "gin/public/wrapper_info.h" 12 #include "gin/public/wrapper_info.h"
12 13
13 namespace gin { 14 namespace gin {
14 15
15 namespace internal {
16
17 GIN_EXPORT void* FromV8Impl(v8::Isolate* isolate,
18 v8::Local<v8::Value> val,
19 WrapperInfo* info);
20
21 } // namespace internal
22
23
24 // Wrappable is a base class for C++ objects that have corresponding v8 wrapper 16 // Wrappable is a base class for C++ objects that have corresponding v8 wrapper
25 // objects. To retain a Wrappable object on the stack, use a gin::Handle. 17 // objects. To retain a Wrappable object on the stack, use a gin::Handle.
26 // 18 //
27 // USAGE: 19 // USAGE:
28 // // my_class.h 20 // // my_class.h
29 // class MyClass : Wrappable<MyClass> { 21 // class MyClass : Wrappable<MyClass> {
30 // public: 22 // public:
31 // static WrapperInfo kWrapperInfo; 23 // static WrapperInfo kWrapperInfo;
32 // 24 //
33 // // Optional, only required if non-empty template should be used. 25 // // Optional, only required if non-empty template should be used.
(...skipping 10 matching lines...) Expand all
44 // return Wrappable<MyClass>::GetObjectTemplateBuilder(isolate) 36 // return Wrappable<MyClass>::GetObjectTemplateBuilder(isolate)
45 // .SetValue("foobar", 42); 37 // .SetValue("foobar", 42);
46 // } 38 // }
47 // 39 //
48 // Subclasses should also typically have private constructors and expose a 40 // Subclasses should also typically have private constructors and expose a
49 // static Create function that returns a gin::Handle. Forcing creators through 41 // static Create function that returns a gin::Handle. Forcing creators through
50 // this static Create function will enforce that clients actually create a 42 // this static Create function will enforce that clients actually create a
51 // wrapper for the object. If clients fail to create a wrapper for a wrappable 43 // wrapper for the object. If clients fail to create a wrapper for a wrappable
52 // object, the object will leak because we use the weak callback from the 44 // object, the object will leak because we use the weak callback from the
53 // wrapper as the signal to delete the wrapped object. 45 // wrapper as the signal to delete the wrapped object.
54 template<typename T>
55 class Wrappable;
56 46
57 class ObjectTemplateBuilder; 47 class ObjectTemplateBuilder;
58 48
59 // Non-template base class to share code between templates instances. 49 // Non-template base class to share code between templates instances.
60 class GIN_EXPORT WrappableBase { 50 class GIN_EXPORT WrappableBase {
61 protected: 51 protected:
62 WrappableBase(); 52 WrappableBase();
63 virtual ~WrappableBase(); 53 virtual ~WrappableBase();
64 54
65 virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate); 55 virtual ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate* isolate);
66 56
67 v8::Local<v8::Object> GetWrapperImpl(v8::Isolate* isolate, 57 v8::Local<v8::Object> GetWrapperImpl(v8::Isolate* isolate,
68 WrapperInfo* wrapper_info); 58 WrapperInfo* wrapper_info);
69 59
70 private: 60 private:
71 static void FirstWeakCallback( 61 static void FirstWeakCallback(
72 const v8::WeakCallbackInfo<WrappableBase>& data); 62 const v8::WeakCallbackInfo<WrappableBase>& data);
73 static void SecondWeakCallback( 63 static void SecondWeakCallback(
74 const v8::WeakCallbackInfo<WrappableBase>& data); 64 const v8::WeakCallbackInfo<WrappableBase>& data);
75 65
76 v8::Global<v8::Object> wrapper_; // Weak 66 v8::Global<v8::Object> wrapper_; // Weak
77 67
78 DISALLOW_COPY_AND_ASSIGN(WrappableBase); 68 DISALLOW_COPY_AND_ASSIGN(WrappableBase);
79 }; 69 };
80 70
81 71
82 template<typename T> 72 template<typename T>
83 class Wrappable : public WrappableBase { 73 class Wrappable : public WrappableBase {
84 public: 74 public:
75 // Subclasses derived from T that override GetObjectTemplateBuilder must
76 // also override this method. Otherwise, they will have the same WrapperInfo
77 // as T, and share a cached v8::ObjectTemplate. That will lead to crashes.
78 virtual WrapperInfo* GetWrapperInfo() { return &T::kWrapperInfo; }
79
85 // Retrieve (or create) the v8 wrapper object cooresponding to this object. 80 // Retrieve (or create) the v8 wrapper object cooresponding to this object.
86 // To customize the wrapper created for a subclass, override GetWrapperInfo() 81 // To customize the wrapper created for a subclass, override GetWrapperInfo()
87 // instead of overriding this function. 82 // instead of overriding this function.
88 v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate) { 83 v8::Local<v8::Object> GetWrapper(v8::Isolate* isolate) {
89 return GetWrapperImpl(isolate, &T::kWrapperInfo); 84 return GetWrapperImpl(isolate, GetWrapperInfo());
90 } 85 }
91 86
92 protected: 87 protected:
93 Wrappable() {} 88 Wrappable() {}
94 virtual ~Wrappable() {} 89 virtual ~Wrappable() {}
95 90
96 private: 91 private:
97 DISALLOW_COPY_AND_ASSIGN(Wrappable); 92 DISALLOW_COPY_AND_ASSIGN(Wrappable);
98 }; 93 };
99 94
100
101 // This converter handles any subclass of Wrappable. 95 // This converter handles any subclass of Wrappable.
102 template<typename T> 96 template<typename T>
103 struct Converter<T*, typename base::enable_if< 97 struct Converter<T*, typename base::enable_if<
104 base::is_convertible<T*, WrappableBase*>::value>::type> { 98 base::is_convertible<T*, WrappableBase*>::value>::type> {
105 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) { 99 static v8::Local<v8::Value> ToV8(v8::Isolate* isolate, T* val) {
106 return val->GetWrapper(isolate); 100 return val->GetWrapper(isolate);
107 } 101 }
108 102
109 static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) { 103 static bool FromV8(v8::Isolate* isolate, v8::Local<v8::Value> val, T** out) {
tommycli 2015/06/02 22:01:23 These changes are inspired by reverting some chang
110 *out = static_cast<T*>(static_cast<WrappableBase*>( 104 if (!val->IsObject())
111 internal::FromV8Impl(isolate, val, &T::kWrapperInfo))); 105 return false;
112 return *out != NULL; 106 v8::Local<v8::Object> obj = v8::Local<v8::Object>::Cast(val);
107 WrapperInfo* info = WrapperInfo::From(obj);
108
109 // If this fails, the object is not managed by Gin. It is either a normal JS
110 // object that's not wrapping any external C++ object, or it is wrapping
111 // some C++ object, but that object isn't managed by Gin (maybe Blink).
112 if (!info)
113 return false;
114
115 // The stored pointer points to the WrappableBase portion of the object,
116 // so we must convert to WrappableBase first, then downcast, to correctly
117 // adjust the pointer to point to the the T object.
118 WrappableBase* pointer = static_cast<WrappableBase*>(
119 obj->GetAlignedPointerFromInternalField(kEncodedValueIndex));
120
121 // There is no way to detect if pointer is really of type T without RTTI.
122 // We cannot compare to &T::kWrapperInfo, as subclasses of T can override
123 // GetWrapperInfo(). This is unfortunate, but needed to support subclasses.
tommycli 2015/06/02 22:01:23 I tried various methods for hours, but my conclusi
124 *out = static_cast<T*>(pointer);
125 return true;
113 } 126 }
114 }; 127 };
115 128
116 } // namespace gin 129 } // namespace gin
117 130
118 #endif // GIN_WRAPPABLE_H_ 131 #endif // GIN_WRAPPABLE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698