1197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch/*
2197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch * Copyright (C) 2009 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 V8DOMWrapper_h
32197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#define V8DOMWrapper_h
33197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
34197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "bindings/core/v8/DOMDataStore.h"
357242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#include "bindings/core/v8/ScriptWrappable.h"
36197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/PassRefPtr.h"
37197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/RawPtr.h"
38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "wtf/text/AtomicString.h"
39197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include <v8.h>
40197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
42197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciclass Node;
44197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstruct WrapperTypeInfo;
45197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
46197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass V8DOMWrapper {
47197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic:
48e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    static v8::Local<v8::Object> createWrapper(v8::Handle<v8::Object> creationContext, const WrapperTypeInfo*, ScriptWrappableBase* internalPointer, v8::Isolate*);
49197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
50197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename V8T, typename T>
517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Object> associateObjectWithWrapper(PassRefPtr<T>, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*);
52197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename V8T, typename T>
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Object> associateObjectWithWrapper(RawPtr<T> object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return associateObjectWithWrapper<V8T, T>(object.get(), wrapperTypeInfo, wrapper, isolate);
56197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    template<typename V8T, typename T>
587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Object> associateObjectWithWrapper(T*, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*);
597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Object> associateObjectWithWrapperNonTemplate(ScriptWrappable*, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*);
607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static v8::Handle<v8::Object> associateObjectWithWrapperNonTemplate(Node*, const WrapperTypeInfo*, v8::Handle<v8::Object>, v8::Isolate*);
617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void setNativeInfo(v8::Handle<v8::Object>, const WrapperTypeInfo*, ScriptWrappableBase* internalPointer);
627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void setNativeInfoForHiddenWrapper(v8::Handle<v8::Object>, const WrapperTypeInfo*, ScriptWrappableBase* internalPointer);
637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void setNativeInfoWithPersistentHandle(v8::Handle<v8::Object>, const WrapperTypeInfo*, ScriptWrappableBase* internalPointer, WrapperPersistentNode*);
647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    static void clearNativeInfo(v8::Handle<v8::Object>, const WrapperTypeInfo*);
65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    static bool isDOMWrapper(v8::Handle<v8::Value>);
67197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
68197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
69e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)inline void V8DOMWrapper::setNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, ScriptWrappableBase* internalPointer)
70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapper->InternalFieldCount() >= 2);
72e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ASSERT(internalPointer);
73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapperTypeInfo);
74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject);
76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#else
777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject || wrapperTypeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject);
78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
79e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, internalPointer);
80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
83e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)inline void V8DOMWrapper::setNativeInfoForHiddenWrapper(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, ScriptWrappableBase* internalPointer)
84197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
85e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // see WindowProxy::installDOMWindow() comment for why this version is needed and safe.
86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapper->InternalFieldCount() >= 2);
87e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ASSERT(internalPointer);
88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapperTypeInfo);
89197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
907242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType != WrapperTypeInfo::RefCountedObject);
91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#else
927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject || wrapperTypeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject);
93197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Clear out the last internal field, which is assumed to contain a valid persistent pointer value.
967242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (wrapperTypeInfo->gcType == WrapperTypeInfo::GarbageCollectedObject) {
97197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, 0);
987242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    } else if (wrapperTypeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject) {
99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(OILPAN)
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, 0);
101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif
102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
103e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, internalPointer);
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1077242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline void V8DOMWrapper::setNativeInfoWithPersistentHandle(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo, ScriptWrappableBase* internalPointer, WrapperPersistentNode* handle)
108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapper->InternalFieldCount() >= 3);
110e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ASSERT(internalPointer);
111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapperTypeInfo);
1127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#if ENABLE(OILPAN)
1137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::WillBeGarbageCollectedObject || wrapperTypeInfo->gcType == WrapperTypeInfo::GarbageCollectedObject);
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#else
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::GarbageCollectedObject);
1167242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif
117e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, internalPointer);
118197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Persistent handle is stored in the last internal field.
120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(wrapper->InternalFieldCount() - 1, handle);
121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
122197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
123197021e6b966cfb06891637935ef33fff06433d1Ben Murdochinline void V8DOMWrapper::clearNativeInfo(v8::Handle<v8::Object> wrapper, const WrapperTypeInfo* wrapperTypeInfo)
124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapper->InternalFieldCount() >= 2);
126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(wrapperTypeInfo);
127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // clearNativeInfo() is used only by NP objects, which are not garbage collected.
1287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject);
129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast<WrapperTypeInfo*>(wrapperTypeInfo));
130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, 0);
131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
133197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<typename V8T, typename T>
1347242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapper(PassRefPtr<T> object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1367242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setNativeInfo(wrapper, wrapperTypeInfo, V8T::toScriptWrappableBase(object.get()));
137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(isDOMWrapper(wrapper));
1387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DOMDataStore::setWrapper<V8T>(object.leakRef(), wrapper, isolate, wrapperTypeInfo);
139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return wrapper;
140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
141197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
142197021e6b966cfb06891637935ef33fff06433d1Ben Murdochtemplate<typename V8T, typename T>
1437242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapper(T* object, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
1447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
1457242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, V8T::toScriptWrappableBase(object), WrapperPersistent<T>::create(object));
1467242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(isDOMWrapper(wrapper));
1477242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DOMDataStore::setWrapper<V8T>(object, wrapper, isolate, wrapperTypeInfo);
1487242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return wrapper;
1497242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
1507242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1517242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapperNonTemplate(ScriptWrappable* impl, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    wrapperTypeInfo->refObject(impl->toScriptWrappableBase());
1547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#if ENABLE(OILPAN)
1557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject)
1567242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfo(wrapper, wrapperTypeInfo, impl->toScriptWrappableBase());
1577242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
1587242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, impl->toScriptWrappableBase(), wrapperTypeInfo->createPersistentHandle(impl));
1597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#else
1607242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (wrapperTypeInfo->gcType != WrapperTypeInfo::GarbageCollectedObject)
1617242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfo(wrapper, wrapperTypeInfo, impl->toScriptWrappableBase());
1627242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
1637242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, impl->toScriptWrappableBase(), wrapperTypeInfo->createPersistentHandle(impl));
1647242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif
1657242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(isDOMWrapper(wrapper));
1667242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DOMDataStore::setWrapperNonTemplate(impl, wrapper, isolate, wrapperTypeInfo);
1677242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    return wrapper;
1687242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci}
1697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucciinline v8::Handle<v8::Object> V8DOMWrapper::associateObjectWithWrapperNonTemplate(Node* node, const WrapperTypeInfo* wrapperTypeInfo, v8::Handle<v8::Object> wrapper, v8::Isolate* isolate)
1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci{
1727242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    wrapperTypeInfo->refObject(ScriptWrappable::fromObject(node)->toScriptWrappableBase());
1737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#if ENABLE(OILPAN)
1747242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (wrapperTypeInfo->gcType == WrapperTypeInfo::RefCountedObject)
1757242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfo(wrapper, wrapperTypeInfo, ScriptWrappable::fromObject(node)->toScriptWrappableBase());
1767242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
1777242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, ScriptWrappable::fromObject(node)->toScriptWrappableBase(), wrapperTypeInfo->createPersistentHandle(ScriptWrappable::fromObject(node)));
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#else
1797242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (wrapperTypeInfo->gcType != WrapperTypeInfo::GarbageCollectedObject)
1807242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfo(wrapper, wrapperTypeInfo, ScriptWrappable::fromObject(node)->toScriptWrappableBase());
1817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    else
1827242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        setNativeInfoWithPersistentHandle(wrapper, wrapperTypeInfo, ScriptWrappable::fromObject(node)->toScriptWrappableBase(), wrapperTypeInfo->createPersistentHandle(ScriptWrappable::fromObject(node)));
1837242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci#endif
184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ASSERT(isDOMWrapper(wrapper));
1857242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    DOMDataStore::setWrapperNonTemplate(node, wrapper, isolate, wrapperTypeInfo);
186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return wrapper;
187197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
188197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
189197021e6b966cfb06891637935ef33fff06433d1Ben Murdochclass V8WrapperInstantiationScope {
190197021e6b966cfb06891637935ef33fff06433d1Ben Murdochpublic:
191197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    V8WrapperInstantiationScope(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
192197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        : m_didEnterContext(false)
193197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        , m_context(isolate->GetCurrentContext())
194197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
195197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // creationContext should not be empty. Because if we have an
196197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // empty creationContext, we will end up creating
197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // a new object in the context currently entered. This is wrong.
198197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        RELEASE_ASSERT(!creationContext.IsEmpty());
199197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        v8::Handle<v8::Context> contextForWrapper = creationContext->CreationContext();
200197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // For performance, we enter the context only if the currently running context
201197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        // is different from the context that we are about to enter.
202197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (contextForWrapper == m_context)
203197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return;
204197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_context = v8::Local<v8::Context>::New(isolate, contextForWrapper);
205197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_didEnterContext = true;
206197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_context->Enter();
207197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
208197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
209197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    ~V8WrapperInstantiationScope()
210197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    {
211197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (!m_didEnterContext)
212197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return;
213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        m_context->Exit();
214197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    }
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Handle<v8::Context> context() const { return m_context; }
217197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
218197021e6b966cfb06891637935ef33fff06433d1Ben Murdochprivate:
219197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool m_didEnterContext;
220197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    v8::Handle<v8::Context> m_context;
221197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch};
222197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
223c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
224197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
225197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif // V8DOMWrapper_h
226