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 10 matching lines...) Expand all Loading... |
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
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 // This file has been moved to platform/bindings/ScriptWrappable.h. |
32 #define ScriptWrappable_h | 32 // TODO(adithyas): Remove this file. |
33 | 33 #include "platform/bindings/ScriptWrappable.h" |
34 #include "bindings/core/v8/ScriptWrappableVisitor.h" | |
35 #include "bindings/core/v8/WrapperTypeInfo.h" | |
36 #include "core/CoreExport.h" | |
37 #include "platform/heap/Handle.h" | |
38 #include "platform/wtf/Compiler.h" | |
39 #include "platform/wtf/Noncopyable.h" | |
40 #include "platform/wtf/TypeTraits.h" | |
41 #include "v8/include/v8.h" | |
42 | |
43 namespace blink { | |
44 | |
45 class CORE_EXPORT TraceWrapperBase { | |
46 WTF_MAKE_NONCOPYABLE(TraceWrapperBase); | |
47 | |
48 public: | |
49 TraceWrapperBase() = default; | |
50 virtual bool IsScriptWrappable() const { return false; } | |
51 | |
52 DECLARE_VIRTUAL_TRACE_WRAPPERS(){}; | |
53 }; | |
54 | |
55 // ScriptWrappable provides a way to map from/to C++ DOM implementation to/from | |
56 // JavaScript object (platform object). ToV8() converts a ScriptWrappable to | |
57 // a v8::Object and toScriptWrappable() converts a v8::Object back to | |
58 // a ScriptWrappable. v8::Object as platform object is called "wrapper object". | |
59 // The wrapepr object for the main world is stored in ScriptWrappable. Wrapper | |
60 // objects for other worlds are stored in DOMWrapperMap. | |
61 class CORE_EXPORT ScriptWrappable : public TraceWrapperBase { | |
62 WTF_MAKE_NONCOPYABLE(ScriptWrappable); | |
63 | |
64 public: | |
65 ScriptWrappable() {} | |
66 | |
67 bool IsScriptWrappable() const override { return true; } | |
68 | |
69 template <typename T> | |
70 T* ToImpl() { | |
71 // All ScriptWrappables are managed by the Blink GC heap; check that | |
72 // |T| is a garbage collected type. | |
73 static_assert( | |
74 sizeof(T) && WTF::IsGarbageCollectedType<T>::value, | |
75 "Classes implementing ScriptWrappable must be garbage collected."); | |
76 | |
77 // Check if T* is castable to ScriptWrappable*, which means T doesn't | |
78 // have two or more ScriptWrappable as superclasses. If T has two | |
79 // ScriptWrappable as superclasses, conversions from T* to | |
80 // ScriptWrappable* are ambiguous. | |
81 #if !COMPILER(MSVC) | |
82 // MSVC 2013 doesn't support static_assert + constexpr well. | |
83 static_assert(!static_cast<ScriptWrappable*>(static_cast<T*>(nullptr)), | |
84 "Class T must not have two or more ScriptWrappable as its " | |
85 "superclasses."); | |
86 #endif | |
87 return static_cast<T*>(this); | |
88 } | |
89 | |
90 // Returns the WrapperTypeInfo of the instance. | |
91 // | |
92 // This method must be overridden by DEFINE_WRAPPERTYPEINFO macro. | |
93 virtual const WrapperTypeInfo* GetWrapperTypeInfo() const = 0; | |
94 | |
95 // Creates and returns a new wrapper object. | |
96 virtual v8::Local<v8::Object> Wrap(v8::Isolate*, | |
97 v8::Local<v8::Object> creation_context); | |
98 | |
99 // Associates the instance with the given |wrapper| if this instance is not | |
100 // yet associated with any wrapper. Returns the wrapper already associated | |
101 // or |wrapper| if not yet associated. | |
102 // The caller should always use the returned value rather than |wrapper|. | |
103 WARN_UNUSED_RESULT virtual v8::Local<v8::Object> AssociateWithWrapper( | |
104 v8::Isolate*, | |
105 const WrapperTypeInfo*, | |
106 v8::Local<v8::Object> wrapper); | |
107 | |
108 // Returns true if the instance needs to be kept alive even when the | |
109 // instance is unreachable from JavaScript. | |
110 virtual bool HasPendingActivity() const { return false; } | |
111 | |
112 // Associates this instance with the given |wrapper| if this instance is not | |
113 // yet associated with any wrapper. Returns true if the given wrapper is | |
114 // associated with this instance, or false if this instance is already | |
115 // associated with a wrapper. In the latter case, |wrapper| will be updated | |
116 // to the existing wrapper. | |
117 WARN_UNUSED_RESULT bool SetWrapper(v8::Isolate* isolate, | |
118 const WrapperTypeInfo* wrapper_type_info, | |
119 v8::Local<v8::Object>& wrapper) { | |
120 DCHECK(!wrapper.IsEmpty()); | |
121 if (UNLIKELY(ContainsWrapper())) { | |
122 wrapper = MainWorldWrapper(isolate); | |
123 return false; | |
124 } | |
125 main_world_wrapper_.Reset(isolate, wrapper); | |
126 wrapper_type_info->ConfigureWrapper(&main_world_wrapper_); | |
127 main_world_wrapper_.SetWeak(); | |
128 DCHECK(ContainsWrapper()); | |
129 ScriptWrappableVisitor::WriteBarrier(isolate, &main_world_wrapper_); | |
130 return true; | |
131 } | |
132 | |
133 // Dissociates the wrapper, if any, from this instance. | |
134 void UnsetWrapperIfAny() { | |
135 if (ContainsWrapper()) { | |
136 main_world_wrapper_.Reset(); | |
137 WrapperTypeInfo::WrapperDestroyed(); | |
138 } | |
139 } | |
140 | |
141 bool IsEqualTo(const v8::Local<v8::Object>& other) const { | |
142 return main_world_wrapper_ == other; | |
143 } | |
144 | |
145 bool SetReturnValue(v8::ReturnValue<v8::Value> return_value) { | |
146 return_value.Set(main_world_wrapper_); | |
147 return ContainsWrapper(); | |
148 } | |
149 | |
150 bool ContainsWrapper() const { return !main_world_wrapper_.IsEmpty(); } | |
151 | |
152 // Mark wrapper of this ScriptWrappable as alive in V8. Only marks | |
153 // wrapper in the main world. To mark wrappers in all worlds call | |
154 // ScriptWrappableVisitor::markWrapper(ScriptWrappable*, v8::Isolate*) | |
155 void MarkWrapper(const WrapperVisitor*) const; | |
156 | |
157 private: | |
158 // These classes are exceptionally allowed to use mainWorldWrapper(). | |
159 friend class DOMDataStore; | |
160 friend class HeapSnaphotWrapperVisitor; | |
161 friend class V8HiddenValue; | |
162 friend class V8PrivateProperty; | |
163 | |
164 v8::Local<v8::Object> MainWorldWrapper(v8::Isolate* isolate) const { | |
165 return v8::Local<v8::Object>::New(isolate, main_world_wrapper_); | |
166 } | |
167 | |
168 // Only use when really necessary, i.e., when passing over this | |
169 // ScriptWrappable's reference to V8. Should only be needed by GC | |
170 // infrastructure. | |
171 const v8::Persistent<v8::Object>* RawMainWorldWrapper() const { | |
172 return &main_world_wrapper_; | |
173 } | |
174 | |
175 v8::Persistent<v8::Object> main_world_wrapper_; | |
176 }; | |
177 | |
178 // Defines 'wrapperTypeInfo' virtual method which returns the WrapperTypeInfo of | |
179 // the instance. Also declares a static member of type WrapperTypeInfo, of which | |
180 // the definition is given by the IDL code generator. | |
181 // | |
182 // All the derived classes of ScriptWrappable, regardless of directly or | |
183 // indirectly, must write this macro in the class definition as long as the | |
184 // class has a corresponding .idl file. | |
185 #define DEFINE_WRAPPERTYPEINFO() \ | |
186 public: \ | |
187 const WrapperTypeInfo* GetWrapperTypeInfo() const override { \ | |
188 return &wrapper_type_info_; \ | |
189 } \ | |
190 \ | |
191 private: \ | |
192 static const WrapperTypeInfo& wrapper_type_info_ | |
193 | |
194 // Declares 'wrapperTypeInfo' method without definition. | |
195 // | |
196 // This macro is used for template classes. e.g. DOMTypedArray<>. | |
197 // To export such a template class X, we need to instantiate X with EXPORT_API, | |
198 // i.e. "extern template class EXPORT_API X;" | |
199 // However, once we instantiate X, we cannot specialize X after | |
200 // the instantiation. i.e. we will see "error: explicit specialization of ... | |
201 // after instantiation". So we cannot define X's s_wrapperTypeInfo in generated | |
202 // code by using specialization. Instead, we need to implement wrapperTypeInfo | |
203 // in X's cpp code, and instantiate X, i.e. "template class X;". | |
204 #define DECLARE_WRAPPERTYPEINFO() \ | |
205 public: \ | |
206 const WrapperTypeInfo* GetWrapperTypeInfo() const override; \ | |
207 \ | |
208 private: \ | |
209 typedef void end_of_define_wrappertypeinfo_not_reached_t | |
210 | |
211 } // namespace blink | |
212 | |
213 #endif // ScriptWrappable_h | |
OLD | NEW |