diff options
Diffstat (limited to 'WebCore/bindings/v8/V8DOMWindowShell.cpp')
-rw-r--r-- | WebCore/bindings/v8/V8DOMWindowShell.cpp | 97 |
1 files changed, 52 insertions, 45 deletions
diff --git a/WebCore/bindings/v8/V8DOMWindowShell.cpp b/WebCore/bindings/v8/V8DOMWindowShell.cpp index cdf4393..6087479 100644 --- a/WebCore/bindings/v8/V8DOMWindowShell.cpp +++ b/WebCore/bindings/v8/V8DOMWindowShell.cpp @@ -31,12 +31,10 @@ #include "config.h" #include "V8DOMWindowShell.h" -#include "CString.h" #include "PlatformBridge.h" #include "CSSMutableStyleDeclaration.h" #include "DateExtension.h" #include "DocumentLoader.h" -#include "DOMObjectsInclude.h" #include "Frame.h" #include "FrameLoaderClient.h" #include "InspectorTimelineAgent.h" @@ -51,9 +49,9 @@ #include "V8DOMMap.h" #include "V8DOMWindow.h" #include "V8Document.h" +#include "V8GCForContextDispose.h" #include "V8HiddenPropertyName.h" #include "V8History.h" -#include "V8Index.h" #include "V8Location.h" #include "V8Proxy.h" #include "WorkerContextExecutionProxy.h" @@ -68,6 +66,7 @@ #include <wtf/StdLibExtras.h> #include <wtf/StringExtras.h> #include <wtf/UnusedParam.h> +#include <wtf/text/CString.h> #ifdef ANDROID_INSTRUMENT #include "TimeCounter.h" @@ -96,28 +95,20 @@ static void reportFatalErrorInV8(const char* location, const char* message) static Frame* getTargetFrame(v8::Local<v8::Object> host, v8::Local<v8::Value> data) { Frame* target = 0; - switch (V8ClassIndex::FromInt(data->Int32Value())) { - case V8ClassIndex::DOMWINDOW: { + WrapperTypeInfo* type = WrapperTypeInfo::unwrap(data); + if (V8DOMWindow::info.equals(type)) { v8::Handle<v8::Object> window = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), host); if (window.IsEmpty()) return target; DOMWindow* targetWindow = V8DOMWindow::toNative(window); target = targetWindow->frame(); - break; - } - case V8ClassIndex::LOCATION: { + } else if (V8History::info.equals(type)) { History* history = V8History::toNative(host); target = history->frame(); - break; - } - case V8ClassIndex::HISTORY: { + } else if (V8Location::info.equals(type)) { Location* location = V8Location::toNative(host); target = location->frame(); - break; - } - default: - break; } return target; } @@ -144,7 +135,6 @@ bool V8DOMWindowShell::isContextInitialized() // m_context, m_global, and m_wrapperBoilerplates should // all be non-empty if if m_context is non-empty. ASSERT(m_context.IsEmpty() || !m_global.IsEmpty()); - ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty()); return !m_context.IsEmpty(); } @@ -154,15 +144,20 @@ void V8DOMWindowShell::disposeContextHandles() m_frame->loader()->client()->didDestroyScriptContextForFrame(); m_context.Dispose(); m_context.Clear(); + + // It's likely that disposing the context has created a lot of + // garbage. Notify V8 about this so it'll have a chance of cleaning + // it up when idle. + V8GCForContextDispose::instance().notifyContextDisposed(); } - if (!m_wrapperBoilerplates.IsEmpty()) { -#ifndef NDEBUG - V8GCController::unregisterGlobalHandle(this, m_wrapperBoilerplates); -#endif - m_wrapperBoilerplates.Dispose(); - m_wrapperBoilerplates.Clear(); + WrapperBoilerplateMap::iterator it = m_wrapperBoilerplates.begin(); + for (; it != m_wrapperBoilerplates.end(); ++it) { + v8::Persistent<v8::Object> wrapper = it->second; + wrapper.Dispose(); + wrapper.Clear(); } + m_wrapperBoilerplates.clear(); } void V8DOMWindowShell::destroyGlobal() @@ -299,19 +294,15 @@ void V8DOMWindowShell::initContextIfNeeded() #endif } - installHiddenObjectPrototype(v8Context); - m_wrapperBoilerplates = v8::Persistent<v8::Array>::New(v8::Array::New(V8ClassIndex::WRAPPER_TYPE_COUNT)); - // Bail out if allocation failed. - if (m_wrapperBoilerplates.IsEmpty()) { + if (!installHiddenObjectPrototype(v8Context)) { disposeContextHandles(); return; } -#ifndef NDEBUG - V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates); -#endif - if (!installDOMWindow(v8Context, m_frame->domWindow())) + if (!installDOMWindow(v8Context, m_frame->domWindow())) { disposeContextHandles(); + return; + } updateDocument(); @@ -357,7 +348,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob // Note: we check the loader URL here instead of the document URL // because we might be currently loading an URL into a blank page. // See http://code.google.com/p/chromium/issues/detail?id=10924 - if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol() || extensions[i].scheme != m_frame->page()->mainFrame()->loader()->activeDocumentLoader()->url().protocol())) + if (extensions[i].scheme.length() > 0 && (extensions[i].scheme != m_frame->loader()->activeDocumentLoader()->url().protocol())) continue; extensionNames[index++] = extensions[i].extension->name(); @@ -369,6 +360,7 @@ v8::Persistent<v8::Context> V8DOMWindowShell::createNewContext(v8::Handle<v8::Ob } void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context) +<<<<<<< HEAD { // if we already have a context, clear it before setting the new one. if (!m_context.IsEmpty()) { @@ -379,29 +371,37 @@ void V8DOMWindowShell::setContext(v8::Handle<v8::Context> context) } bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window) +======= +>>>>>>> webkit.org at r58033 { - v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); - if (implicitProtoString.IsEmpty()) - return false; + // if we already have a context, clear it before setting the new one. + if (!m_context.IsEmpty()) { + m_context.Dispose(); + m_context.Clear(); + } + m_context = v8::Persistent<v8::Context>::New(context); +} +bool V8DOMWindowShell::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* window) +{ // Create a new JS window object and use it as the prototype for the shadow global object. - v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(V8ClassIndex::DOMWINDOW, getHiddenObjectPrototype(context)); + v8::Handle<v8::Function> windowConstructor = V8DOMWrapper::getConstructor(&V8DOMWindow::info, getHiddenObjectPrototype(context)); v8::Local<v8::Object> jsWindow = SafeAllocation::newInstance(windowConstructor); // Bail out if allocation failed. if (jsWindow.IsEmpty()) return false; // Wrap the window. - V8DOMWrapper::setDOMWrapper(jsWindow, V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window); - V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window); + V8DOMWrapper::setDOMWrapper(jsWindow, &V8DOMWindow::info, window); + V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(jsWindow->GetPrototype()), &V8DOMWindow::info, window); window->ref(); V8DOMWrapper::setJSWrapperForDOMObject(window, v8::Persistent<v8::Object>::New(jsWindow)); // Insert the window instance as the prototype of the shadow object. - v8::Handle<v8::Object> v8Global = context->Global(); - V8DOMWrapper::setDOMWrapper(v8::Handle<v8::Object>::Cast(v8Global->GetPrototype()), V8ClassIndex::ToInt(V8ClassIndex::DOMWINDOW), window); - v8Global->Set(implicitProtoString, jsWindow); + v8::Handle<v8::Object> v8RealGlobal = v8::Handle<v8::Object>::Cast(context->Global()->GetPrototype()); + V8DOMWrapper::setDOMWrapper(v8RealGlobal, &V8DOMWindow::info, window); + v8RealGlobal->SetPrototype(jsWindow); return true; } @@ -533,31 +533,38 @@ v8::Handle<v8::Value> V8DOMWindowShell::getHiddenObjectPrototype(v8::Handle<v8:: return context->Global()->GetHiddenValue(V8HiddenPropertyName::objectPrototype()); } -void V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context) +bool V8DOMWindowShell::installHiddenObjectPrototype(v8::Handle<v8::Context> context) { v8::Handle<v8::String> objectString = v8::String::New("Object"); v8::Handle<v8::String> prototypeString = v8::String::New("prototype"); v8::Handle<v8::String> hiddenObjectPrototypeString = V8HiddenPropertyName::objectPrototype(); // Bail out if allocation failed. if (objectString.IsEmpty() || prototypeString.IsEmpty() || hiddenObjectPrototypeString.IsEmpty()) - return; + return false; v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(context->Global()->Get(objectString)); + // Bail out if fetching failed. + if (object.IsEmpty()) + return false; v8::Handle<v8::Value> objectPrototype = object->Get(prototypeString); + // Bail out if fetching failed. + if (objectPrototype.IsEmpty()) + return false; context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype); + + return true; } -v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(V8ClassIndex::V8WrapperType type) +v8::Local<v8::Object> V8DOMWindowShell::createWrapperFromCacheSlowCase(WrapperTypeInfo* type) { // Not in cache. - int classIndex = V8ClassIndex::ToInt(type); initContextIfNeeded(); v8::Context::Scope scope(m_context); v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(m_context)); v8::Local<v8::Object> instance = SafeAllocation::newInstance(function); if (!instance.IsEmpty()) { - m_wrapperBoilerplates->Set(v8::Integer::New(classIndex), instance); + m_wrapperBoilerplates.set(type, v8::Persistent<v8::Object>::New(instance)); return instance->Clone(); } return notHandledByInterceptor(); |