| 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 |