Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / v8 / DOMDataStore.h
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29  */
30
31 #ifndef DOMDataStore_h
32 #define DOMDataStore_h
33
34 #include "bindings/v8/DOMWrapperMap.h"
35 #include "bindings/v8/DOMWrapperWorld.h"
36 #include "bindings/v8/ScriptWrappable.h"
37 #include "bindings/v8/WrapperTypeInfo.h"
38 #include <v8.h>
39 #include "wtf/Noncopyable.h"
40 #include "wtf/StdLibExtras.h"
41
42 namespace WebCore {
43
44 class Node;
45
46 class DOMDataStore {
47     WTF_MAKE_NONCOPYABLE(DOMDataStore);
48 public:
49     explicit DOMDataStore(WrapperWorldType);
50     ~DOMDataStore();
51
52     static DOMDataStore& current(v8::Isolate*);
53
54     // We can use a wrapper stored in a ScriptWrappable when we're in the main world.
55     // This method does the fast check if we're in the main world. If this method returns true,
56     // it is guaranteed that we're in the main world. On the other hand, if this method returns
57     // false, nothing is guaranteed (we might be in the main world).
58     template<typename T>
59     static bool canUseScriptWrappable(T* object)
60     {
61         return !DOMWrapperWorld::isolatedWorldsExist()
62             && !canExistInWorker(object)
63             && ScriptWrappable::wrapperCanBeStoredInObject(object);
64     }
65
66     template<typename V8T, typename T, typename Wrappable>
67     static bool setReturnValueFromWrapperFast(v8::ReturnValue<v8::Value> returnValue, T* object, v8::Local<v8::Object> holder, Wrappable* wrappable)
68     {
69         if (canUseScriptWrappable(object))
70             return ScriptWrappable::setReturnValueWithSecurityCheck<V8T>(returnValue, object);
71         // The second fastest way to check if we're in the main world is to check if
72         // the wrappable's wrapper is the same as the holder.
73         // FIXME: Investigate if it's worth having this check for performance.
74         if (holderContainsWrapper(holder, wrappable)) {
75             if (ScriptWrappable::wrapperCanBeStoredInObject(object))
76                 return ScriptWrappable::setReturnValueWithSecurityCheck<V8T>(returnValue, object);
77             return DOMWrapperWorld::mainWorld()->domDataStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
78         }
79         return current(returnValue.GetIsolate()).template setReturnValueFrom<V8T>(returnValue, object);
80     }
81
82     template<typename V8T, typename T>
83     static bool setReturnValueFromWrapper(v8::ReturnValue<v8::Value> returnValue, T* object)
84     {
85         if (canUseScriptWrappable(object))
86             return ScriptWrappable::setReturnValueWithSecurityCheck<V8T>(returnValue, object);
87         return current(returnValue.GetIsolate()).template setReturnValueFrom<V8T>(returnValue, object);
88     }
89
90     template<typename V8T, typename T>
91     static bool setReturnValueFromWrapperForMainWorld(v8::ReturnValue<v8::Value> returnValue, T* object)
92     {
93         if (ScriptWrappable::wrapperCanBeStoredInObject(object))
94             return ScriptWrappable::setReturnValue(returnValue, object);
95         return DOMWrapperWorld::mainWorld()->domDataStore().m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
96     }
97
98     template<typename V8T, typename T>
99     static v8::Handle<v8::Object> getWrapper(T* object, v8::Isolate* isolate)
100     {
101         if (canUseScriptWrappable(object)) {
102             v8::Handle<v8::Object> result = ScriptWrappable::getUnsafeWrapperFromObject(object).newLocal(isolate);
103             // Security: always guard against malicious tampering.
104             RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result.IsEmpty() || result->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(object));
105             return result;
106         }
107         return current(isolate).template get<V8T>(object, isolate);
108     }
109
110     template<typename V8T, typename T>
111     static void setWrapperReference(const v8::Persistent<v8::Object>& parent, T* child, v8::Isolate* isolate)
112     {
113         if (canUseScriptWrappable(child)) {
114             UnsafePersistent<v8::Object> unsafePersistent = ScriptWrappable::getUnsafeWrapperFromObject(child);
115             // Security: always guard against malicious tampering.
116             RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(unsafePersistent.isEmpty() || unsafePersistent.value()->GetAlignedPointerFromInternalField(v8DOMWrapperObjectIndex) == V8T::toInternalPointer(child));
117             unsafePersistent.setReferenceFrom(parent, isolate);
118             return;
119         }
120         current(isolate).template setReference<V8T>(parent, child, isolate);
121     }
122
123     template<typename V8T, typename T>
124     static void setWrapper(T* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
125     {
126         if (canUseScriptWrappable(object)) {
127             ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
128             return;
129         }
130         return current(isolate).template set<V8T>(object, wrapper, isolate, configuration);
131     }
132
133     template<typename V8T, typename T>
134     static bool containsWrapper(T* object, v8::Isolate* isolate)
135     {
136         return current(isolate).template containsWrapper<V8T>(object);
137     }
138
139     template<typename V8T, typename T>
140     inline v8::Handle<v8::Object> get(T* object, v8::Isolate* isolate)
141     {
142         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
143             return ScriptWrappable::getUnsafeWrapperFromObject(object).newLocal(isolate);
144         return m_wrapperMap.newLocal(V8T::toInternalPointer(object), isolate);
145     }
146
147     template<typename V8T, typename T>
148     inline void setReference(const v8::Persistent<v8::Object>& parent, T* child, v8::Isolate* isolate)
149     {
150         if (ScriptWrappable::wrapperCanBeStoredInObject(child) && m_type == MainWorld) {
151             ScriptWrappable::getUnsafeWrapperFromObject(child).setReferenceFrom(parent, isolate);
152             return;
153         }
154         m_wrapperMap.setReference(parent, V8T::toInternalPointer(child), isolate);
155     }
156
157     template<typename V8T, typename T>
158     inline bool setReturnValueFrom(v8::ReturnValue<v8::Value> returnValue, T* object)
159     {
160         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
161             return ScriptWrappable::setReturnValue(returnValue, object);
162         return m_wrapperMap.setReturnValueFrom(returnValue, V8T::toInternalPointer(object));
163     }
164
165     template<typename V8T, typename T>
166     inline bool containsWrapper(T* object)
167     {
168         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld)
169             return !ScriptWrappable::getUnsafeWrapperFromObject(object).isEmpty();
170         return m_wrapperMap.containsKey(V8T::toInternalPointer(object));
171     }
172
173 private:
174     template<typename V8T, typename T>
175     inline void set(T* object, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate, const WrapperConfiguration& configuration)
176     {
177         ASSERT(!!object);
178         ASSERT(!wrapper.IsEmpty());
179         if (ScriptWrappable::wrapperCanBeStoredInObject(object) && m_type == MainWorld) {
180             ScriptWrappable::setWrapperInObject(object, wrapper, isolate, configuration);
181             return;
182         }
183         m_wrapperMap.set(V8T::toInternalPointer(object), wrapper, configuration);
184     }
185
186     static bool canExistInWorker(void*) { return true; }
187     static bool canExistInWorker(Node*) { return false; }
188
189     static bool holderContainsWrapper(v8::Local<v8::Object>, void*)
190     {
191         return false;
192     }
193
194     static bool holderContainsWrapper(v8::Local<v8::Object> holder, ScriptWrappable* wrappable)
195     {
196         // Verify our assumptions about the main world.
197         UnsafePersistent<v8::Object> unsafePersistent = wrappable->unsafePersistent();
198         ASSERT(unsafePersistent.isEmpty() || !(holder == *unsafePersistent.persistent()) || current(v8::Isolate::GetCurrent()).m_type == MainWorld);
199         return holder == *unsafePersistent.persistent();
200     }
201
202     WrapperWorldType m_type;
203     DOMWrapperMap<void> m_wrapperMap;
204 };
205
206 } // namespace WebCore
207
208 #endif // DOMDataStore_h