summaryrefslogtreecommitdiffstats
path: root/WebCore/bindings/v8/V8DOMWindowShell.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/bindings/v8/V8DOMWindowShell.cpp')
-rw-r--r--WebCore/bindings/v8/V8DOMWindowShell.cpp97
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();