/* * 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: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. 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. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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. */ #include "config.h" #include "bindings/v8/V8PerIsolateData.h" #include "bindings/v8/DOMDataStore.h" #include "bindings/v8/ScriptGCEvent.h" #include "bindings/v8/ScriptProfiler.h" #include "bindings/v8/V8Binding.h" #include "bindings/v8/V8HiddenPropertyName.h" #include "bindings/v8/V8ObjectConstructor.h" #include "bindings/v8/V8ScriptRunner.h" namespace WebCore { V8PerIsolateData::V8PerIsolateData(v8::Isolate* isolate) : m_isolate(isolate) , m_stringCache(adoptPtr(new StringCache())) , m_workerDomDataStore(0) , m_hiddenPropertyName(adoptPtr(new V8HiddenPropertyName())) , m_constructorMode(ConstructorMode::CreateNewObject) , m_recursionLevel(0) #ifndef NDEBUG , m_internalScriptRecursionLevel(0) #endif , m_gcEventData(adoptPtr(new GCEventData())) , m_shouldCollectGarbageSoon(false) { } V8PerIsolateData::~V8PerIsolateData() { } V8PerIsolateData* V8PerIsolateData::create(v8::Isolate* isolate) { ASSERT(isolate); ASSERT(!isolate->GetData(gin::kEmbedderBlink)); V8PerIsolateData* data = new V8PerIsolateData(isolate); isolate->SetData(gin::kEmbedderBlink, data); return data; } void V8PerIsolateData::ensureInitialized(v8::Isolate* isolate) { ASSERT(isolate); if (!isolate->GetData(gin::kEmbedderBlink)) create(isolate); } v8::Persistent& V8PerIsolateData::ensureLiveRoot() { if (m_liveRoot.isEmpty()) m_liveRoot.set(m_isolate, v8::Null(m_isolate)); return m_liveRoot.getUnsafe(); } void V8PerIsolateData::dispose(v8::Isolate* isolate) { void* data = isolate->GetData(gin::kEmbedderBlink); delete static_cast(data); isolate->SetData(gin::kEmbedderBlink, 0); } v8::Handle V8PerIsolateData::toStringTemplate() { if (m_toStringTemplate.isEmpty()) m_toStringTemplate.set(m_isolate, v8::FunctionTemplate::New(m_isolate, constructorOfToString)); return m_toStringTemplate.newLocal(m_isolate); } v8::Handle V8PerIsolateData::privateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::FunctionCallback callback, v8::Handle data, v8::Handle signature, int length) { TemplateMap& templates = templateMap(currentWorldType); TemplateMap::iterator result = templates.find(privatePointer); if (result != templates.end()) return result->value.newLocal(m_isolate); v8::Local templ = v8::FunctionTemplate::New(m_isolate, callback, data, signature, length); templates.add(privatePointer, UnsafePersistent(m_isolate, templ)); return templ; } v8::Handle V8PerIsolateData::privateTemplateIfExists(WrapperWorldType currentWorldType, void* privatePointer) { TemplateMap& templates = templateMap(currentWorldType); TemplateMap::iterator result = templates.find(privatePointer); if (result != templates.end()) return result->value.newLocal(m_isolate); return v8::Local(); } void V8PerIsolateData::setPrivateTemplate(WrapperWorldType currentWorldType, void* privatePointer, v8::Handle templ) { templateMap(currentWorldType).add(privatePointer, UnsafePersistent(m_isolate, templ)); } v8::Handle V8PerIsolateData::rawDOMTemplate(const WrapperTypeInfo* info, WrapperWorldType currentWorldType) { TemplateMap& templates = rawDOMTemplateMap(currentWorldType); TemplateMap::iterator result = templates.find(info); if (result != templates.end()) return result->value.newLocal(m_isolate); v8::EscapableHandleScope handleScope(m_isolate); v8::Local templ = createRawTemplate(m_isolate); templates.add(info, UnsafePersistent(m_isolate, templ)); return handleScope.Escape(templ); } v8::Local V8PerIsolateData::ensureRegexContext() { if (m_regexContext.isEmpty()) { v8::HandleScope handleScope(m_isolate); m_regexContext.set(m_isolate, v8::Context::New(m_isolate)); } return m_regexContext.newLocal(m_isolate); } bool V8PerIsolateData::hasInstance(const WrapperTypeInfo* info, v8::Handle value, WrapperWorldType currentWorldType) { TemplateMap& templates = rawDOMTemplateMap(currentWorldType); TemplateMap::iterator result = templates.find(info); if (result == templates.end()) return false; v8::HandleScope handleScope(m_isolate); return result->value.newLocal(m_isolate)->HasInstance(value); } void V8PerIsolateData::constructorOfToString(const v8::FunctionCallbackInfo& info) { // The DOM constructors' toString functions grab the current toString // for Functions by taking the toString function of itself and then // calling it with the constructor as its receiver. This means that // changes to the Function prototype chain or toString function are // reflected when printing DOM constructors. The only wart is that // changes to a DOM constructor's toString's toString will cause the // toString of the DOM constructor itself to change. This is extremely // obscure and unlikely to be a problem. v8::Handle value = info.Callee()->Get(v8AtomicString(info.GetIsolate(), "toString")); if (!value->IsFunction()) { v8SetReturnValue(info, v8::String::Empty(info.GetIsolate())); return; } v8SetReturnValue(info, V8ScriptRunner::callInternalFunction(v8::Handle::Cast(value), info.This(), 0, 0, v8::Isolate::GetCurrent())); } } // namespace WebCore