OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... | |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #ifndef ScriptWrappable_h | 31 #ifndef ScriptWrappable_h |
32 #define ScriptWrappable_h | 32 #define ScriptWrappable_h |
33 | 33 |
34 #include "bindings/core/v8/WrapperTypeInfo.h" | 34 #include "bindings/core/v8/WrapperTypeInfo.h" |
35 #include "platform/heap/Handle.h" | 35 #include "platform/heap/Handle.h" |
36 #include "wtf/Noncopyable.h" | |
36 #include <v8.h> | 37 #include <v8.h> |
37 | 38 |
38 namespace blink { | 39 namespace blink { |
39 | 40 |
40 /** | 41 /** |
41 * The base class of all wrappable objects. | 42 * The base class of all wrappable objects. |
42 * | 43 * |
43 * This class provides the internal pointer to be stored in the wrapper objects, | 44 * This class provides the internal pointer to be stored in the wrapper objects, |
44 * and its conversions from / to the DOM instances. | 45 * and its conversions from / to the DOM instances. |
45 * | 46 * |
46 * Note that this class must not have vtbl (any virtual function) or any member | 47 * Note that this class must not have vtbl (any virtual function) or any member |
47 * variable which increase the size of instances. Some of the classes sensitive | 48 * variable which increase the size of instances. Some of the classes sensitive |
48 * to the size inherit from this class. So this class must be zero size. | 49 * to the size inherit from this class. So this class must be zero size. |
49 */ | 50 */ |
50 #if COMPILER(MSVC) | 51 #if COMPILER(MSVC) |
haraken
2014/11/14 08:21:20
Can we remove this comment now, since ScriptWrappa
Yuki
2014/11/14 11:25:09
ScriptWrappableBase is still used as the internal
| |
51 // VC++ 2013 doesn't support EBCO (Empty Base Class Optimization). It causes | 52 // VC++ 2013 doesn't support EBCO (Empty Base Class Optimization). It causes |
52 // that not always pointers to an empty base class are aligned to 4 byte | 53 // that not always pointers to an empty base class are aligned to 4 byte |
53 // alignment. For example, | 54 // alignment. For example, |
54 // | 55 // |
55 // class EmptyBase1 {}; | 56 // class EmptyBase1 {}; |
56 // class EmptyBase2 {}; | 57 // class EmptyBase2 {}; |
57 // class Derived : public EmptyBase1, public EmptyBase2 {}; | 58 // class Derived : public EmptyBase1, public EmptyBase2 {}; |
58 // Derived d; | 59 // Derived d; |
59 // // &d == 0x1000 | 60 // // &d == 0x1000 |
60 // // static_cast<EmptyBase1*>(&d) == 0x1000 | 61 // // static_cast<EmptyBase1*>(&d) == 0x1000 |
61 // // static_cast<EmptyBase2*>(&d) == 0x1001 // Not 4 byte alignment! | 62 // // static_cast<EmptyBase2*>(&d) == 0x1001 // Not 4 byte alignment! |
62 // | 63 // |
63 // This doesn't happen with other compilers which support EBCO. All the | 64 // This doesn't happen with other compilers which support EBCO. All the |
64 // addresses in the above example will be 0x1000 with EBCO supported. | 65 // addresses in the above example will be 0x1000 with EBCO supported. |
65 // | 66 // |
66 // Since v8::Object::SetAlignedPointerInInternalField requires the pointers to | 67 // Since v8::Object::SetAlignedPointerInInternalField requires the pointers to |
67 // be aligned, we need a hack to specify at least 4 byte alignment to MSVC. | 68 // be aligned, we need a hack to specify at least 4 byte alignment to MSVC. |
68 __declspec(align(4)) | 69 __declspec(align(4)) |
69 #endif | 70 #endif |
70 class ScriptWrappableBase { | 71 class ScriptWrappableBase { |
72 WTF_MAKE_NONCOPYABLE(ScriptWrappableBase); | |
73 friend class ScriptWrappable; | |
71 public: | 74 public: |
72 template<typename T> | 75 template<typename T> |
73 T* toImpl() | 76 T* toImpl() |
74 { | 77 { |
75 // Check if T* is castable to ScriptWrappableBase*, which means T | 78 // Check if T* is castable to ScriptWrappableBase*, which means T |
76 // doesn't have two or more ScriptWrappableBase as superclasses. | 79 // doesn't have two or more ScriptWrappableBase as superclasses. |
77 // If T has two ScriptWrappableBase as superclasses, conversions | 80 // If T has two ScriptWrappableBase as superclasses, conversions |
78 // from T* to ScriptWrappableBase* are ambiguous. | 81 // from T* to ScriptWrappableBase* are ambiguous. |
79 ASSERT(static_cast<ScriptWrappableBase*>(static_cast<T*>(this))); | 82 ASSERT(static_cast<ScriptWrappableBase*>(static_cast<T*>(this))); |
80 // The internal pointers must be aligned to at least 4 byte alignment. | 83 // The internal pointers must be aligned to at least 4 byte alignment. |
81 ASSERT((reinterpret_cast<intptr_t>(this) & 0x3) == 0); | 84 ASSERT((reinterpret_cast<intptr_t>(this) & 0x3) == 0); |
82 return static_cast<T*>(this); | 85 return static_cast<T*>(this); |
83 } | 86 } |
84 ScriptWrappableBase* toScriptWrappableBase() | 87 ScriptWrappableBase* toScriptWrappableBase() |
85 { | 88 { |
86 ASSERT(this); | 89 ASSERT(this); |
87 // The internal pointers must be aligned to at least 4 byte alignment. | 90 // The internal pointers must be aligned to at least 4 byte alignment. |
88 ASSERT((reinterpret_cast<intptr_t>(this) & 0x3) == 0); | 91 ASSERT((reinterpret_cast<intptr_t>(this) & 0x3) == 0); |
89 return this; | 92 return this; |
90 } | 93 } |
91 | 94 |
92 // Creates and returns a new wrapper object. | |
93 // Do not call this method for a ScriptWrappable or its subclasses. This | |
94 // non-virtual version of "wrap" is meant only for non-ScriptWrappable | |
95 // objects. This wrap takes an extra third argument of type WrapperTypeInfo | |
96 // because ScriptWrappableBase doesn't have wrapperTypeInfo() method unlike | |
97 // ScriptWrappable. | |
98 v8::Handle<v8::Object> wrap(v8::Handle<v8::Object> creationContext, v8::Isol ate*, const WrapperTypeInfo*); | |
99 | |
100 void assertWrapperSanity(v8::Local<v8::Object> object) | 95 void assertWrapperSanity(v8::Local<v8::Object> object) |
101 { | 96 { |
102 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty() | 97 RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(object.IsEmpty() |
103 || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectInde x) == toScriptWrappableBase()); | 98 || object->GetAlignedPointerFromInternalField(v8DOMWrapperObjectInde x) == toScriptWrappableBase()); |
104 } | 99 } |
100 | |
101 private: | |
102 // Do not allow DOM classes to inherit directly from ScriptWrappableBase. | |
103 // DOM classes must inherit from ScriptWrappable instead. | |
104 ScriptWrappableBase() { } | |
105 }; | 105 }; |
106 | 106 |
107 /** | 107 /** |
108 * ScriptWrappable wraps a V8 object and its WrapperTypeInfo. | 108 * ScriptWrappable wraps a V8 object and its WrapperTypeInfo. |
109 * | 109 * |
110 * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a | 110 * ScriptWrappable acts much like a v8::Persistent<> in that it keeps a |
111 * V8 object alive. | 111 * V8 object alive. |
112 * | 112 * |
113 * The state transitions are: | 113 * The state transitions are: |
114 * - new: an empty ScriptWrappable. | 114 * - new: an empty ScriptWrappable. |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 releaseObject(data.GetValue()); | 229 releaseObject(data.GetValue()); |
230 } | 230 } |
231 | 231 |
232 v8::Persistent<v8::Object> m_wrapper; | 232 v8::Persistent<v8::Object> m_wrapper; |
233 }; | 233 }; |
234 | 234 |
235 // Defines 'wrapperTypeInfo' virtual method which returns the WrapperTypeInfo of | 235 // Defines 'wrapperTypeInfo' virtual method which returns the WrapperTypeInfo of |
236 // the instance. Also declares a static member of type WrapperTypeInfo, of which | 236 // the instance. Also declares a static member of type WrapperTypeInfo, of which |
237 // the definition is given by the IDL code generator. | 237 // the definition is given by the IDL code generator. |
238 // | 238 // |
239 // Every DOM Class T must meet either of the following conditions: | |
240 // - T.idl inherits from [NotScriptWrappable]. | |
241 // - T inherits from ScriptWrappable and has DEFINE_WRAPPERTYPEINFO(). | |
242 // | |
243 // If a DOM class T does not inherit from ScriptWrappable, you have to write | |
244 // [NotScriptWrappable] in the IDL file as an extended attribute in order to let | |
245 // IDL code generator know that T does not inherit from ScriptWrappable. Note | |
246 // that [NotScriptWrappable] is inheritable. | |
247 // | |
248 // All the derived classes of ScriptWrappable, regardless of directly or | 239 // All the derived classes of ScriptWrappable, regardless of directly or |
249 // indirectly, must write this macro in the class definition. | 240 // indirectly, must write this macro in the class definition as long as the |
241 // class has a corresponding .idl file. | |
250 #define DEFINE_WRAPPERTYPEINFO() \ | 242 #define DEFINE_WRAPPERTYPEINFO() \ |
251 public: \ | 243 public: \ |
252 virtual const WrapperTypeInfo* wrapperTypeInfo() const override \ | 244 virtual const WrapperTypeInfo* wrapperTypeInfo() const override \ |
253 { \ | 245 { \ |
254 return &s_wrapperTypeInfo; \ | 246 return &s_wrapperTypeInfo; \ |
255 } \ | 247 } \ |
256 private: \ | 248 private: \ |
257 static const WrapperTypeInfo& s_wrapperTypeInfo | 249 static const WrapperTypeInfo& s_wrapperTypeInfo |
258 | 250 |
259 // Defines 'wrapperTypeInfo' virtual method, which should never be called. | 251 // Defines 'wrapperTypeInfo' virtual method, which should never be called. |
(...skipping 11 matching lines...) Expand all Loading... | |
271 { \ | 263 { \ |
272 ASSERT_NOT_REACHED(); \ | 264 ASSERT_NOT_REACHED(); \ |
273 return 0; \ | 265 return 0; \ |
274 } \ | 266 } \ |
275 private: \ | 267 private: \ |
276 typedef void end_of_define_wrappertypeinfo_not_reached_t | 268 typedef void end_of_define_wrappertypeinfo_not_reached_t |
277 | 269 |
278 } // namespace blink | 270 } // namespace blink |
279 | 271 |
280 #endif // ScriptWrappable_h | 272 #endif // ScriptWrappable_h |
OLD | NEW |