/* * Copyright (C) 2009 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * Neither the name of Google Inc. nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef V8DOMWrapper_h #define V8DOMWrapper_h #include "bindings/v8/DOMDataStore.h" #include #include "wtf/PassRefPtr.h" #include "wtf/text/AtomicString.h" namespace WebCore { struct WrapperTypeInfo; class V8DOMWrapper { public: #ifndef NDEBUG // Checks if a v8 value can be a DOM wrapper static bool maybeDOMWrapper(v8::Handle); #endif static v8::Local createWrapper(v8::Handle creationContext, const WrapperTypeInfo*, void*, v8::Isolate*); template static inline v8::Handle associateObjectWithWrapper(PassRefPtr, const WrapperTypeInfo*, v8::Handle, v8::Isolate*, WrapperConfiguration::Lifetime); static inline void setNativeInfo(v8::Handle, const WrapperTypeInfo*, void*); static inline void clearNativeInfo(v8::Handle, const WrapperTypeInfo*); static bool isDOMWrapper(v8::Handle); static bool isWrapperOfType(v8::Handle, const WrapperTypeInfo*); }; inline void V8DOMWrapper::setNativeInfo(v8::Handle wrapper, const WrapperTypeInfo* type, void* object) { ASSERT(wrapper->InternalFieldCount() >= 2); ASSERT(object); ASSERT(type); wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, object); wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast(type)); } inline void V8DOMWrapper::clearNativeInfo(v8::Handle wrapper, const WrapperTypeInfo* type) { ASSERT(wrapper->InternalFieldCount() >= 2); ASSERT(type); wrapper->SetAlignedPointerInInternalField(v8DOMWrapperTypeIndex, const_cast(type)); wrapper->SetAlignedPointerInInternalField(v8DOMWrapperObjectIndex, 0); } template inline v8::Handle V8DOMWrapper::associateObjectWithWrapper(PassRefPtr object, const WrapperTypeInfo* type, v8::Handle wrapper, v8::Isolate* isolate, WrapperConfiguration::Lifetime lifetime) { setNativeInfo(wrapper, type, V8T::toInternalPointer(object.get())); ASSERT(maybeDOMWrapper(wrapper)); WrapperConfiguration configuration = buildWrapperConfiguration(object.get(), lifetime); DOMDataStore::setWrapper(object.leakRef(), wrapper, isolate, configuration); return wrapper; } class V8WrapperInstantiationScope { public: V8WrapperInstantiationScope(v8::Handle creationContext, v8::Isolate* isolate) : m_didEnterContext(false) , m_context(isolate->GetCurrentContext()) { // FIXME: Remove all empty creationContexts from caller sites. // If a creationContext is empty, we will end up creating a new object // in the context currently entered. This is wrong. if (creationContext.IsEmpty()) return; v8::Handle contextForWrapper = creationContext->CreationContext(); // For performance, we enter the context only if the currently running context // is different from the context that we are about to enter. if (contextForWrapper == m_context) return; m_context = v8::Local::New(isolate, contextForWrapper); m_didEnterContext = true; m_context->Enter(); } ~V8WrapperInstantiationScope() { if (!m_didEnterContext) return; m_context->Exit(); } v8::Handle context() const { return m_context; } private: bool m_didEnterContext; v8::Handle m_context; }; } #endif // V8DOMWrapper_h