Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / bindings / core / v8 / WrapperTypeInfo.h
1 /*
2  * Copyright (C) 2010 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 WrapperTypeInfo_h
32 #define WrapperTypeInfo_h
33
34 #include "gin/public/wrapper_info.h"
35 #include "platform/heap/Handle.h"
36 #include "wtf/Assertions.h"
37 #include <v8.h>
38
39 namespace blink {
40
41 class ActiveDOMObject;
42 class EventTarget;
43 class Node;
44 class ScriptWrappableBase;
45
46 static const int v8DOMWrapperTypeIndex = static_cast<int>(gin::kWrapperInfoIndex);
47 static const int v8DOMWrapperObjectIndex = static_cast<int>(gin::kEncodedValueIndex);
48 static const int v8DefaultWrapperInternalFieldCount = static_cast<int>(gin::kNumberOfInternalFields);
49 static const int v8PrototypeTypeIndex = 0;
50 static const int v8PrototypeInternalFieldcount = 1;
51
52 typedef v8::Handle<v8::FunctionTemplate> (*DomTemplateFunction)(v8::Isolate*);
53 typedef void (*RefObjectFunction)(ScriptWrappableBase* internalPointer);
54 typedef void (*DerefObjectFunction)(ScriptWrappableBase* internalPointer);
55 typedef WrapperPersistentNode* (*CreatePersistentHandleFunction)(ScriptWrappableBase* internalPointer);
56 typedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
57 typedef EventTarget* (*ToEventTargetFunction)(v8::Handle<v8::Object>);
58 typedef void (*ResolveWrapperReachabilityFunction)(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>&, v8::Isolate*);
59 typedef void (*InstallConditionallyEnabledMethodsFunction)(v8::Handle<v8::Object>, v8::Isolate*);
60 typedef void (*InstallConditionallyEnabledPropertiesFunction)(v8::Handle<v8::Object>, v8::Isolate*);
61
62 inline void setObjectGroup(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
63 {
64     isolate->SetObjectGroupId(wrapper, v8::UniqueId(reinterpret_cast<intptr_t>(internalPointer)));
65 }
66
67 // This struct provides a way to store a bunch of information that is helpful when unwrapping
68 // v8 objects. Each v8 bindings class has exactly one static WrapperTypeInfo member, so
69 // comparing pointers is a safe way to determine if types match.
70 struct WrapperTypeInfo {
71     enum WrapperTypePrototype {
72         WrapperTypeObjectPrototype,
73         WrapperTypeExceptionPrototype,
74     };
75
76     enum WrapperClassId {
77         NodeClassId = 1, // NodeClassId must be smaller than ObjectClassId.
78         ObjectClassId,
79     };
80
81     enum Lifetime {
82         Dependent,
83         Independent,
84     };
85
86     enum GCType {
87         GarbageCollectedObject,
88         WillBeGarbageCollectedObject,
89         RefCountedObject,
90     };
91
92     static const WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper)
93     {
94         return reinterpret_cast<const WrapperTypeInfo*>(v8::External::Cast(*typeInfoWrapper)->Value());
95     }
96
97
98     bool equals(const WrapperTypeInfo* that) const
99     {
100         return this == that;
101     }
102
103     bool isSubclass(const WrapperTypeInfo* that) const
104     {
105         for (const WrapperTypeInfo* current = this; current; current = current->parentClass) {
106             if (current == that)
107                 return true;
108         }
109
110         return false;
111     }
112
113     void configureWrapper(v8::PersistentBase<v8::Object>* wrapper) const
114     {
115         wrapper->SetWrapperClassId(wrapperClassId);
116         if (lifetime == Independent)
117             wrapper->MarkIndependent();
118     }
119
120     v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate* isolate) const
121     {
122         return domTemplateFunction(isolate);
123     }
124
125     void refObject(ScriptWrappableBase* internalPointer) const
126     {
127         ASSERT(refObjectFunction);
128         refObjectFunction(internalPointer);
129     }
130
131     void derefObject(ScriptWrappableBase* internalPointer) const
132     {
133         ASSERT(derefObjectFunction);
134         derefObjectFunction(internalPointer);
135     }
136
137     WrapperPersistentNode* createPersistentHandle(ScriptWrappableBase* internalPointer) const
138     {
139         ASSERT(createPersistentHandleFunction);
140         return createPersistentHandleFunction(internalPointer);
141     }
142
143     void installConditionallyEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate) const
144     {
145         if (installConditionallyEnabledMethodsFunction)
146             installConditionallyEnabledMethodsFunction(prototypeTemplate, isolate);
147     }
148
149     void installConditionallyEnabledProperties(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate) const
150     {
151         if (installConditionallyEnabledPropertiesFunction)
152             installConditionallyEnabledPropertiesFunction(prototypeTemplate, isolate);
153     }
154
155     ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object> object) const
156     {
157         if (!toActiveDOMObjectFunction)
158             return 0;
159         return toActiveDOMObjectFunction(object);
160     }
161
162     EventTarget* toEventTarget(v8::Handle<v8::Object> object) const
163     {
164         if (!toEventTargetFunction)
165             return 0;
166         return toEventTargetFunction(object);
167     }
168
169     void visitDOMWrapper(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate) const
170     {
171         if (!visitDOMWrapperFunction)
172             setObjectGroup(internalPointer, wrapper, isolate);
173         else
174             visitDOMWrapperFunction(internalPointer, wrapper, isolate);
175     }
176
177     // This field must be the first member of the struct WrapperTypeInfo. This is also checked by a COMPILE_ASSERT() below.
178     const gin::GinEmbedder ginEmbedder;
179
180     const DomTemplateFunction domTemplateFunction;
181     const RefObjectFunction refObjectFunction;
182     const DerefObjectFunction derefObjectFunction;
183     const CreatePersistentHandleFunction createPersistentHandleFunction;
184     const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
185     const ToEventTargetFunction toEventTargetFunction;
186     const ResolveWrapperReachabilityFunction visitDOMWrapperFunction;
187     const InstallConditionallyEnabledMethodsFunction installConditionallyEnabledMethodsFunction;
188     const InstallConditionallyEnabledPropertiesFunction installConditionallyEnabledPropertiesFunction;
189     const WrapperTypeInfo* parentClass;
190     const WrapperTypePrototype wrapperTypePrototype;
191     const WrapperClassId wrapperClassId;
192     const Lifetime lifetime;
193     const GCType gcType;
194 };
195
196 COMPILE_ASSERT(offsetof(struct WrapperTypeInfo, ginEmbedder) == offsetof(struct gin::WrapperInfo, embedder), wrapper_type_info_compatible_to_gin);
197
198 template<typename T, int offset>
199 inline T* getInternalField(const v8::Persistent<v8::Object>& persistent)
200 {
201     // This would be unsafe, but InternalFieldCount and GetAlignedPointerFromInternalField are guaranteed not to allocate
202     const v8::Handle<v8::Object>& object = reinterpret_cast<const v8::Handle<v8::Object>&>(persistent);
203     ASSERT(offset < object->InternalFieldCount());
204     return static_cast<T*>(object->GetAlignedPointerFromInternalField(offset));
205 }
206
207 template<typename T, int offset>
208 inline T* getInternalField(v8::Handle<v8::Object> wrapper)
209 {
210     ASSERT(offset < wrapper->InternalFieldCount());
211     return static_cast<T*>(wrapper->GetAlignedPointerFromInternalField(offset));
212 }
213
214 inline ScriptWrappableBase* toScriptWrappableBase(v8::Handle<v8::Object> wrapper)
215 {
216     return getInternalField<ScriptWrappableBase, v8DOMWrapperObjectIndex>(wrapper);
217 }
218
219 inline const WrapperTypeInfo* toWrapperTypeInfo(const v8::Persistent<v8::Object>& wrapper)
220 {
221     return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
222 }
223
224 inline const WrapperTypeInfo* toWrapperTypeInfo(v8::Handle<v8::Object> wrapper)
225 {
226     return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
227 }
228
229 inline const WrapperPersistentNode* toPersistentHandle(const v8::Handle<v8::Object>& wrapper)
230 {
231     // Persistent handle is stored in the last internal field.
232     return static_cast<WrapperPersistentNode*>(wrapper->GetAlignedPointerFromInternalField(wrapper->InternalFieldCount() - 1));
233 }
234
235 inline void releaseObject(v8::Handle<v8::Object> wrapper)
236 {
237     const WrapperTypeInfo* typeInfo = toWrapperTypeInfo(wrapper);
238     if (typeInfo->gcType == WrapperTypeInfo::GarbageCollectedObject) {
239         const WrapperPersistentNode* handle = toPersistentHandle(wrapper);
240         // This will be null iff a wrapper for a hidden wrapper object,
241         // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
242         WrapperPersistentNode::destroy(handle);
243     } else if (typeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject) {
244 #if ENABLE(OILPAN)
245         const WrapperPersistentNode* handle = toPersistentHandle(wrapper);
246         // This will be null iff a wrapper for a hidden wrapper object,
247         // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
248         WrapperPersistentNode::destroy(handle);
249 #else
250         typeInfo->derefObject(toScriptWrappableBase(wrapper));
251 #endif
252     } else {
253         typeInfo->derefObject(toScriptWrappableBase(wrapper));
254     }
255 }
256
257 } // namespace blink
258
259 #endif // WrapperTypeInfo_h