1197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch/*
2197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2010 Google Inc. All rights reserved.
3197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
4197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Redistribution and use in source and binary forms, with or without
5197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * modification, are permitted provided that the following conditions are
6197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * met:
7197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
8197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Redistributions of source code must retain the above copyright
9197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * notice, this list of conditions and the following disclaimer.
10197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Redistributions in binary form must reproduce the above
11197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * copyright notice, this list of conditions and the following disclaimer
12197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * in the documentation and/or other materials provided with the
13197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * distribution.
14197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *     * Neither the name of Google Inc. nor the names of its
15197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * contributors may be used to endorse or promote products derived from
16197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * this software without specific prior written permission.
17197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch *
18197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch */
30197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
31197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#ifndef WrapperTypeInfo_h
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define WrapperTypeInfo_h
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "gin/public/wrapper_info.h"
35197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "platform/heap/Handle.h"
36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/Assertions.h"
37197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <v8.h>
38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
41197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass ActiveDOMObject;
42197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass EventTarget;
43197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass Node;
44e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)class ScriptWrappableBase;
45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic const int v8DOMWrapperTypeIndex = static_cast<int>(gin::kWrapperInfoIndex);
47197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic const int v8DOMWrapperObjectIndex = static_cast<int>(gin::kEncodedValueIndex);
48197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic const int v8DefaultWrapperInternalFieldCount = static_cast<int>(gin::kNumberOfInternalFields);
49197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic const int v8PrototypeTypeIndex = 0;
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic const int v8PrototypeInternalFieldcount = 1;
51197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtypedef v8::Handle<v8::FunctionTemplate> (*DomTemplateFunction)(v8::Isolate*);
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitypedef void (*RefObjectFunction)(ScriptWrappableBase* internalPointer);
54e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)typedef void (*DerefObjectFunction)(ScriptWrappableBase* internalPointer);
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccitypedef WrapperPersistentNode* (*CreatePersistentHandleFunction)(ScriptWrappableBase* internalPointer);
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtypedef ActiveDOMObject* (*ToActiveDOMObjectFunction)(v8::Handle<v8::Object>);
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtypedef EventTarget* (*ToEventTargetFunction)(v8::Handle<v8::Object>);
58e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)typedef void (*ResolveWrapperReachabilityFunction)(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>&, v8::Isolate*);
599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)typedef void (*InstallConditionallyEnabledMethodsFunction)(v8::Handle<v8::Object>, v8::Isolate*);
609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)typedef void (*InstallConditionallyEnabledPropertiesFunction)(v8::Handle<v8::Object>, v8::Isolate*);
61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
62e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)inline void setObjectGroup(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate)
63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
64e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    isolate->SetObjectGroupId(wrapper, v8::UniqueId(reinterpret_cast<intptr_t>(internalPointer)));
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// This struct provides a way to store a bunch of information that is helpful when unwrapping
68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// v8 objects. Each v8 bindings class has exactly one static WrapperTypeInfo member, so
69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch// comparing pointers is a safe way to determine if types match.
70197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstruct WrapperTypeInfo {
717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    enum WrapperTypePrototype {
727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperTypeObjectPrototype,
737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperTypeExceptionPrototype,
747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    enum WrapperClassId {
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        NodeClassId = 1, // NodeClassId must be smaller than ObjectClassId.
787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ObjectClassId,
797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    enum Lifetime {
827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        Dependent,
837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        Independent,
847242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
867242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    enum GCType {
877242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        GarbageCollectedObject,
887242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WillBeGarbageCollectedObject,
897242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        RefCountedObject,
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    };
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
92197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static const WrapperTypeInfo* unwrap(v8::Handle<v8::Value> typeInfoWrapper)
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return reinterpret_cast<const WrapperTypeInfo*>(v8::External::Cast(*typeInfoWrapper)->Value());
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
97197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
98197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool equals(const WrapperTypeInfo* that) const
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return this == that;
101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool isSubclass(const WrapperTypeInfo* that) const
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        for (const WrapperTypeInfo* current = this; current; current = current->parentClass) {
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (current == that)
107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                return true;
108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        }
109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
110197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return false;
111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
112197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void configureWrapper(v8::PersistentBase<v8::Object>* wrapper) const
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        wrapper->SetWrapperClassId(wrapperClassId);
1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (lifetime == Independent)
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            wrapper->MarkIndependent();
1187242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1197242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Handle<v8::FunctionTemplate> domTemplate(v8::Isolate* isolate) const
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return domTemplateFunction(isolate);
123197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void refObject(ScriptWrappableBase* internalPointer) const
1267242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1277242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(refObjectFunction);
1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        refObjectFunction(internalPointer);
1297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1307242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1317242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    void derefObject(ScriptWrappableBase* internalPointer) const
1327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1337242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(derefObjectFunction);
1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        derefObjectFunction(internalPointer);
1357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    WrapperPersistentNode* createPersistentHandle(ScriptWrappableBase* internalPointer) const
1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    {
1397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        ASSERT(createPersistentHandleFunction);
1407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return createPersistentHandleFunction(internalPointer);
1417242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    }
1427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1439e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    void installConditionallyEnabledMethods(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate) const
144197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
1459e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (installConditionallyEnabledMethodsFunction)
1469e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            installConditionallyEnabledMethodsFunction(prototypeTemplate, isolate);
1479e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
1489e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
1499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    void installConditionallyEnabledProperties(v8::Handle<v8::Object> prototypeTemplate, v8::Isolate* isolate) const
1509e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    {
1519e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        if (installConditionallyEnabledPropertiesFunction)
1529e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            installConditionallyEnabledPropertiesFunction(prototypeTemplate, isolate);
153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ActiveDOMObject* toActiveDOMObject(v8::Handle<v8::Object> object) const
156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!toActiveDOMObjectFunction)
158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return 0;
159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return toActiveDOMObjectFunction(object);
160197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
161197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    EventTarget* toEventTarget(v8::Handle<v8::Object> object) const
163197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
164197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!toEventTargetFunction)
165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return 0;
166197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        return toEventTargetFunction(object);
167197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
168197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
169e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    void visitDOMWrapper(ScriptWrappableBase* internalPointer, const v8::Persistent<v8::Object>& wrapper, v8::Isolate* isolate) const
170197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
171197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!visitDOMWrapperFunction)
172e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            setObjectGroup(internalPointer, wrapper, isolate);
173197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        else
174e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            visitDOMWrapperFunction(internalPointer, wrapper, isolate);
175197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
176197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
177197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // This field must be the first member of the struct WrapperTypeInfo. This is also checked by a COMPILE_ASSERT() below.
178197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const gin::GinEmbedder ginEmbedder;
179197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
180197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const DomTemplateFunction domTemplateFunction;
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const RefObjectFunction refObjectFunction;
182197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const DerefObjectFunction derefObjectFunction;
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const CreatePersistentHandleFunction createPersistentHandleFunction;
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const ToActiveDOMObjectFunction toActiveDOMObjectFunction;
185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const ToEventTargetFunction toEventTargetFunction;
186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const ResolveWrapperReachabilityFunction visitDOMWrapperFunction;
1879e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    const InstallConditionallyEnabledMethodsFunction installConditionallyEnabledMethodsFunction;
1889e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    const InstallConditionallyEnabledPropertiesFunction installConditionallyEnabledPropertiesFunction;
189197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const WrapperTypeInfo* parentClass;
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const WrapperTypePrototype wrapperTypePrototype;
1917242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const WrapperClassId wrapperClassId;
1927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    const Lifetime lifetime;
193197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const GCType gcType;
194197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
195197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
196197021e6b966cfb06891637935ef33fff06433d1Ben MurdochCOMPILE_ASSERT(offsetof(struct WrapperTypeInfo, ginEmbedder) == offsetof(struct gin::WrapperInfo, embedder), wrapper_type_info_compatible_to_gin);
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<typename T, int offset>
199197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline T* getInternalField(const v8::Persistent<v8::Object>& persistent)
200197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
201197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // This would be unsafe, but InternalFieldCount and GetAlignedPointerFromInternalField are guaranteed not to allocate
202197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const v8::Handle<v8::Object>& object = reinterpret_cast<const v8::Handle<v8::Object>&>(persistent);
203197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(offset < object->InternalFieldCount());
204197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return static_cast<T*>(object->GetAlignedPointerFromInternalField(offset));
205197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
206197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
207197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<typename T, int offset>
208197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline T* getInternalField(v8::Handle<v8::Object> wrapper)
209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
210197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(offset < wrapper->InternalFieldCount());
211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return static_cast<T*>(wrapper->GetAlignedPointerFromInternalField(offset));
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
2147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline ScriptWrappableBase* toScriptWrappableBase(v8::Handle<v8::Object> wrapper)
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
216e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return getInternalField<ScriptWrappableBase, v8DOMWrapperObjectIndex>(wrapper);
217197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
218197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
219197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline const WrapperTypeInfo* toWrapperTypeInfo(const v8::Persistent<v8::Object>& wrapper)
220197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
221197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
222197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
223197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
224197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline const WrapperTypeInfo* toWrapperTypeInfo(v8::Handle<v8::Object> wrapper)
225197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
226197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return getInternalField<WrapperTypeInfo, v8DOMWrapperTypeIndex>(wrapper);
227197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
228197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
2297242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline const WrapperPersistentNode* toPersistentHandle(const v8::Handle<v8::Object>& wrapper)
230197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
231197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Persistent handle is stored in the last internal field.
2327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return static_cast<WrapperPersistentNode*>(wrapper->GetAlignedPointerFromInternalField(wrapper->InternalFieldCount() - 1));
233197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
234197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
235197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline void releaseObject(v8::Handle<v8::Object> wrapper)
236197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
237197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    const WrapperTypeInfo* typeInfo = toWrapperTypeInfo(wrapper);
2387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (typeInfo->gcType == WrapperTypeInfo::GarbageCollectedObject) {
2397242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        const WrapperPersistentNode* handle = toPersistentHandle(wrapper);
240197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // This will be null iff a wrapper for a hidden wrapper object,
241197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
2427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperPersistentNode::destroy(handle);
2437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    } else if (typeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject) {
244197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
2457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        const WrapperPersistentNode* handle = toPersistentHandle(wrapper);
246197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // This will be null iff a wrapper for a hidden wrapper object,
247197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // see V8DOMWrapper::setNativeInfoForHiddenWrapper().
2487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        WrapperPersistentNode::destroy(handle);
249197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#else
2507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        typeInfo->derefObject(toScriptWrappableBase(wrapper));
251197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
252197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    } else {
2537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        typeInfo->derefObject(toScriptWrappableBase(wrapper));
254197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
255197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
256197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
257c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
259197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif // WrapperTypeInfo_h
260