OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 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 DOMDataStore_h | 31 // This file has been moved to platform/bindings/DOMDataStore.h. |
32 #define DOMDataStore_h | 32 // TODO(adithyas): Remove this file. |
33 | 33 #include "platform/bindings/DOMDataStore.h" |
34 #include <memory> | |
35 | |
36 #include "bindings/core/v8/DOMWrapperMap.h" | |
37 #include "bindings/core/v8/DOMWrapperWorld.h" | |
38 #include "bindings/core/v8/ScriptWrappable.h" | |
39 #include "bindings/core/v8/WrapperTypeInfo.h" | |
40 #include "platform/wtf/Allocator.h" | |
41 #include "platform/wtf/Noncopyable.h" | |
42 #include "platform/wtf/Optional.h" | |
43 #include "platform/wtf/StackUtil.h" | |
44 #include "platform/wtf/StdLibExtras.h" | |
45 #include "v8/include/v8.h" | |
46 | |
47 namespace blink { | |
48 | |
49 class DOMDataStore { | |
50 WTF_MAKE_NONCOPYABLE(DOMDataStore); | |
51 USING_FAST_MALLOC(DOMDataStore); | |
52 | |
53 public: | |
54 DOMDataStore(v8::Isolate* isolate, bool is_main_world) | |
55 : is_main_world_(is_main_world) { | |
56 // We never use |m_wrapperMap| when it's the main world. | |
57 if (!is_main_world) | |
58 wrapper_map_.emplace(isolate); | |
59 } | |
60 | |
61 static DOMDataStore& Current(v8::Isolate* isolate) { | |
62 return DOMWrapperWorld::Current(isolate).DomDataStore(); | |
63 } | |
64 | |
65 static bool SetReturnValue(v8::ReturnValue<v8::Value> return_value, | |
66 ScriptWrappable* object) { | |
67 if (CanUseMainWorldWrapper()) | |
68 return object->SetReturnValue(return_value); | |
69 return Current(return_value.GetIsolate()) | |
70 .SetReturnValueFrom(return_value, object); | |
71 } | |
72 | |
73 static bool SetReturnValueForMainWorld( | |
74 v8::ReturnValue<v8::Value> return_value, | |
75 ScriptWrappable* object) { | |
76 return object->SetReturnValue(return_value); | |
77 } | |
78 | |
79 static bool SetReturnValueFast(v8::ReturnValue<v8::Value> return_value, | |
80 ScriptWrappable* object, | |
81 v8::Local<v8::Object> holder, | |
82 const ScriptWrappable* wrappable) { | |
83 if (CanUseMainWorldWrapper() | |
84 // The second fastest way to check if we're in the main world is to | |
85 // check if the wrappable's wrapper is the same as the holder. | |
86 || HolderContainsWrapper(holder, wrappable)) | |
87 return object->SetReturnValue(return_value); | |
88 return Current(return_value.GetIsolate()) | |
89 .SetReturnValueFrom(return_value, object); | |
90 } | |
91 | |
92 static v8::Local<v8::Object> GetWrapper(ScriptWrappable* object, | |
93 v8::Isolate* isolate) { | |
94 if (CanUseMainWorldWrapper()) | |
95 return object->MainWorldWrapper(isolate); | |
96 return Current(isolate).Get(object, isolate); | |
97 } | |
98 | |
99 // Associates the given |object| with the given |wrapper| if the object is | |
100 // not yet associated with any wrapper. Returns true if the given wrapper | |
101 // is associated with the object, or false if the object is already | |
102 // associated with a wrapper. In the latter case, |wrapper| will be updated | |
103 // to the existing wrapper. | |
104 WARN_UNUSED_RESULT static bool SetWrapper( | |
105 v8::Isolate* isolate, | |
106 ScriptWrappable* object, | |
107 const WrapperTypeInfo* wrapper_type_info, | |
108 v8::Local<v8::Object>& wrapper) { | |
109 if (CanUseMainWorldWrapper()) | |
110 return object->SetWrapper(isolate, wrapper_type_info, wrapper); | |
111 return Current(isolate).Set(isolate, object, wrapper_type_info, wrapper); | |
112 } | |
113 | |
114 static bool ContainsWrapper(ScriptWrappable* object, v8::Isolate* isolate) { | |
115 return Current(isolate).ContainsWrapper(object); | |
116 } | |
117 | |
118 v8::Local<v8::Object> Get(ScriptWrappable* object, v8::Isolate* isolate) { | |
119 if (is_main_world_) | |
120 return object->MainWorldWrapper(isolate); | |
121 return wrapper_map_->NewLocal(isolate, object); | |
122 } | |
123 | |
124 WARN_UNUSED_RESULT bool Set(v8::Isolate* isolate, | |
125 ScriptWrappable* object, | |
126 const WrapperTypeInfo* wrapper_type_info, | |
127 v8::Local<v8::Object>& wrapper) { | |
128 DCHECK(object); | |
129 DCHECK(!wrapper.IsEmpty()); | |
130 if (is_main_world_) | |
131 return object->SetWrapper(isolate, wrapper_type_info, wrapper); | |
132 return wrapper_map_->Set(object, wrapper_type_info, wrapper); | |
133 } | |
134 | |
135 void MarkWrapper(ScriptWrappable* script_wrappable) { | |
136 wrapper_map_->MarkWrapper(script_wrappable); | |
137 } | |
138 | |
139 // Dissociates a wrapper, if any, from |script_wrappable|. | |
140 void UnsetWrapperIfAny(ScriptWrappable* script_wrappable) { | |
141 DCHECK(!is_main_world_); | |
142 wrapper_map_->RemoveIfAny(script_wrappable); | |
143 } | |
144 | |
145 bool SetReturnValueFrom(v8::ReturnValue<v8::Value> return_value, | |
146 ScriptWrappable* object) { | |
147 if (is_main_world_) | |
148 return object->SetReturnValue(return_value); | |
149 return wrapper_map_->SetReturnValueFrom(return_value, object); | |
150 } | |
151 | |
152 bool ContainsWrapper(ScriptWrappable* object) { | |
153 if (is_main_world_) | |
154 return object->ContainsWrapper(); | |
155 return wrapper_map_->ContainsKey(object); | |
156 } | |
157 | |
158 private: | |
159 // We can use a wrapper stored in a ScriptWrappable when we're in the main | |
160 // world. This method does the fast check if we're in the main world. If this | |
161 // method returns true, it is guaranteed that we're in the main world. On the | |
162 // other hand, if this method returns false, nothing is guaranteed (we might | |
163 // be in the main world). | |
164 static bool CanUseMainWorldWrapper() { | |
165 return !WTF::MayNotBeMainThread() && | |
166 !DOMWrapperWorld::NonMainWorldsExistInMainThread(); | |
167 } | |
168 | |
169 static bool HolderContainsWrapper(v8::Local<v8::Object> holder, | |
170 const ScriptWrappable* wrappable) { | |
171 // Verify our assumptions about the main world. | |
172 DCHECK(wrappable); | |
173 DCHECK(!wrappable->ContainsWrapper() || !wrappable->IsEqualTo(holder) || | |
174 Current(v8::Isolate::GetCurrent()).is_main_world_); | |
175 return wrappable->IsEqualTo(holder); | |
176 } | |
177 | |
178 bool is_main_world_; | |
179 WTF::Optional<DOMWrapperMap<ScriptWrappable>> wrapper_map_; | |
180 }; | |
181 | |
182 template <> | |
183 inline void DOMWrapperMap<ScriptWrappable>::PersistentValueMapTraits::Dispose( | |
184 v8::Isolate*, | |
185 v8::Global<v8::Object>, | |
186 ScriptWrappable*) { | |
187 WrapperTypeInfo::WrapperDestroyed(); | |
188 } | |
189 | |
190 template <> | |
191 inline void | |
192 DOMWrapperMap<ScriptWrappable>::PersistentValueMapTraits::DisposeWeak( | |
193 const v8::WeakCallbackInfo<WeakCallbackDataType>&) { | |
194 WrapperTypeInfo::WrapperDestroyed(); | |
195 } | |
196 | |
197 } // namespace blink | |
198 | |
199 #endif // DOMDataStore_h | |
OLD | NEW |