[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75

dglazkov at chromium.org dglazkov at chromium.org
Thu Oct 29 20:50:09 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit 4182a3b163602b2ed954b006c5315259337f2d84
Author: dglazkov at chromium.org <dglazkov at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 22 18:35:33 2009 +0000

    2009-10-22  Dimitri Glazkov  <dglazkov at chromium.org>
    
            Reviewed by Adam Barth.
    
            [V8] Rework event listeners to not hold references to frame or V8 context.
    
            https://bugs.webkit.org/show_bug.cgi?id=30648
    
            Covered by existing layout tests: fast/events/attribute-listener*
    
            * bindings/scripts/CodeGeneratorV8.pm: Added passing ScriptExecutionContext*
                to event listener handling code.
            * bindings/v8/DateExtension.cpp:
            (WebCore::DateExtension::setAllowSleep): Changed to use currentContext().
            * bindings/v8/ScriptEventListener.cpp:
            (WebCore::createAttributeEventListener): Reworked to match JSC logic.
            (WebCore::getEventListenerHandlerBody): Added ScriptExecutionContext* param.
            * bindings/v8/V8AbstractEventListener.cpp:
            (WebCore::V8AbstractEventListener::V8AbstractEventListener): Removed Frame* param
                and usage.
            (WebCore::V8AbstractEventListener::handleEvent): Chaged to use ScriptExecutionContext*.
            (WebCore::V8AbstractEventListener::invokeEventHandler): Ditto.
            * bindings/v8/V8AbstractEventListener.h:
            (WebCore::V8AbstractEventListener::getListenerObject): Ditto.
            (WebCore::V8AbstractEventListener::prepareListenerObject): Ditto.
            * bindings/v8/V8DOMWrapper.cpp:
            (WebCore::V8DOMWrapper::convertEventListenerToV8Object):  Added ScriptExecutionContext* param.
            (WebCore::V8DOMWrapper::getEventListener): Ditto.
            * bindings/v8/V8DOMWrapper.h:
            (WebCore::V8DOMWrapper::convertEventListenerToV8Object): Ditto.
            * bindings/v8/V8EventListenerList.h:
            (WebCore::V8EventListenerList::findOrCreateWrapper): Removed ContextType* template param,
                because it's no longer needed.
            * bindings/v8/V8IsolatedWorld.h:
            (WebCore::V8IsolatedWorld::sharedContext): Renamed from shared_context.
            * bindings/v8/V8LazyEventListener.cpp:
            (WebCore::V8LazyEventListener::V8LazyEventListener): Removed Frame* param and usage.
            (WebCore::V8LazyEventListener::callListenerFunction): Added ScriptExecutionContext* param.
            (WebCore::V8LazyEventListener::prepareListenerObject): Ditto.
            * bindings/v8/V8LazyEventListener.h:
            (WebCore::V8LazyEventListener::create): Reordered params to match JSC impl.
            * bindings/v8/V8Proxy.cpp:
            (WebCore::V8Proxy::V8Proxy): Adjusted formatting to match WebKit style.
            (WebCore::V8Proxy::evaluateInNewContext): Changed to use m_context directly.
            (WebCore::V8Proxy::setInjectedScriptContextDebugId): Ditto.
            (WebCore::V8Proxy::createWrapperFromCacheSlowCase): Ditto.
            (WebCore::V8Proxy::isContextInitialized): Ditto.
            (WebCore::V8Proxy::updateDocumentWrapperCache): Ditto.
            (WebCore::V8Proxy::clearDocumentWrapperCache): Ditto.
            (WebCore::V8Proxy::disposeContextHandles): Added explicit disposing of m_context.
            (WebCore::V8Proxy::clearForClose): Changed to use m_context directly.
            (WebCore::V8Proxy::clearForNavigation): Ditto.
            (WebCore::V8Proxy::setSecurityToken): Ditto.
            (WebCore::V8Proxy::updateDocument): Ditto.
            (WebCore::V8Proxy::initContextIfNeeded): Ditto.
            (WebCore::V8Proxy::context): Changed to use v8::Local.
            (WebCore::V8Proxy::mainWorldContext): Changed to use m_context directly.
            (WebCore::V8Proxy::setContextDebugId): Ditto.
            (WebCore::toV8Context):
            * bindings/v8/V8Proxy.h: Removed shared_context decl, changed to use straight
                v8::Persistent for m_context.
            * bindings/v8/V8WorkerContextEventListener.cpp:
            (WebCore::workerProxy): Added.
            (WebCore::V8WorkerContextEventListener::V8WorkerContextEventListener): Removed
                WorkerContextExecutionProxy* param.
            (WebCore::V8WorkerContextEventListener::handleEvent): Started using ScriptExecutionContext*.
            (WebCore::V8WorkerContextEventListener::reportError): Ditto.
            (WebCore::V8WorkerContextEventListener::callListenerFunction): Ditto.
            (WebCore::V8WorkerContextEventListener::getReceiverObject): Ditto.
            * bindings/v8/V8WorkerContextEventListener.h:
            (WebCore::V8WorkerContextEventListener::create): Removed
                WorkerContextExecutionProxy* param.
            * bindings/v8/WorkerContextExecutionProxy.cpp:
            (WebCore::WorkerContextExecutionProxy::findOrCreateEventListener): Removed ContextType*
                template param.
            * bindings/v8/custom/V8CustomEventListener.cpp:
            (WebCore::V8EventListener::V8EventListener): Removed Frame* param.
            (WebCore::V8EventListener::getListenerFunction): Started using ScriptExecutionContext*.
            (WebCore::V8EventListener::callListenerFunction): Ditto.
            * bindings/v8/custom/V8CustomEventListener.h:
            (WebCore::V8EventListener::create): Removed Frame* param.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49949 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 64b0a41..63b4bf8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,85 @@
+2009-10-22  Dimitri Glazkov  <dglazkov at chromium.org>
+
+        Reviewed by Adam Barth.
+
+        [V8] Rework event listeners to not hold references to frame or V8 context.
+
+        https://bugs.webkit.org/show_bug.cgi?id=30648
+
+        Covered by existing layout tests: fast/events/attribute-listener*
+
+        * bindings/scripts/CodeGeneratorV8.pm: Added passing ScriptExecutionContext*
+            to event listener handling code.
+        * bindings/v8/DateExtension.cpp:
+        (WebCore::DateExtension::setAllowSleep): Changed to use currentContext().
+        * bindings/v8/ScriptEventListener.cpp:
+        (WebCore::createAttributeEventListener): Reworked to match JSC logic.
+        (WebCore::getEventListenerHandlerBody): Added ScriptExecutionContext* param.
+        * bindings/v8/V8AbstractEventListener.cpp:
+        (WebCore::V8AbstractEventListener::V8AbstractEventListener): Removed Frame* param
+            and usage.
+        (WebCore::V8AbstractEventListener::handleEvent): Chaged to use ScriptExecutionContext*.
+        (WebCore::V8AbstractEventListener::invokeEventHandler): Ditto.
+        * bindings/v8/V8AbstractEventListener.h:
+        (WebCore::V8AbstractEventListener::getListenerObject): Ditto.
+        (WebCore::V8AbstractEventListener::prepareListenerObject): Ditto.
+        * bindings/v8/V8DOMWrapper.cpp:
+        (WebCore::V8DOMWrapper::convertEventListenerToV8Object):  Added ScriptExecutionContext* param.
+        (WebCore::V8DOMWrapper::getEventListener): Ditto.
+        * bindings/v8/V8DOMWrapper.h:
+        (WebCore::V8DOMWrapper::convertEventListenerToV8Object): Ditto.
+        * bindings/v8/V8EventListenerList.h:
+        (WebCore::V8EventListenerList::findOrCreateWrapper): Removed ContextType* template param,
+            because it's no longer needed.
+        * bindings/v8/V8IsolatedWorld.h:
+        (WebCore::V8IsolatedWorld::sharedContext): Renamed from shared_context.
+        * bindings/v8/V8LazyEventListener.cpp:
+        (WebCore::V8LazyEventListener::V8LazyEventListener): Removed Frame* param and usage.
+        (WebCore::V8LazyEventListener::callListenerFunction): Added ScriptExecutionContext* param.
+        (WebCore::V8LazyEventListener::prepareListenerObject): Ditto.
+        * bindings/v8/V8LazyEventListener.h:
+        (WebCore::V8LazyEventListener::create): Reordered params to match JSC impl.
+        * bindings/v8/V8Proxy.cpp:
+        (WebCore::V8Proxy::V8Proxy): Adjusted formatting to match WebKit style.
+        (WebCore::V8Proxy::evaluateInNewContext): Changed to use m_context directly.
+        (WebCore::V8Proxy::setInjectedScriptContextDebugId): Ditto.
+        (WebCore::V8Proxy::createWrapperFromCacheSlowCase): Ditto.
+        (WebCore::V8Proxy::isContextInitialized): Ditto.
+        (WebCore::V8Proxy::updateDocumentWrapperCache): Ditto.
+        (WebCore::V8Proxy::clearDocumentWrapperCache): Ditto.
+        (WebCore::V8Proxy::disposeContextHandles): Added explicit disposing of m_context. 
+        (WebCore::V8Proxy::clearForClose): Changed to use m_context directly.
+        (WebCore::V8Proxy::clearForNavigation): Ditto.
+        (WebCore::V8Proxy::setSecurityToken): Ditto.
+        (WebCore::V8Proxy::updateDocument): Ditto.
+        (WebCore::V8Proxy::initContextIfNeeded): Ditto.
+        (WebCore::V8Proxy::context): Changed to use v8::Local.
+        (WebCore::V8Proxy::mainWorldContext): Changed to use m_context directly. 
+        (WebCore::V8Proxy::setContextDebugId): Ditto.
+        (WebCore::toV8Context):
+        * bindings/v8/V8Proxy.h: Removed shared_context decl, changed to use straight
+            v8::Persistent for m_context.
+        * bindings/v8/V8WorkerContextEventListener.cpp:
+        (WebCore::workerProxy): Added.
+        (WebCore::V8WorkerContextEventListener::V8WorkerContextEventListener): Removed
+            WorkerContextExecutionProxy* param.
+        (WebCore::V8WorkerContextEventListener::handleEvent): Started using ScriptExecutionContext*.
+        (WebCore::V8WorkerContextEventListener::reportError): Ditto.
+        (WebCore::V8WorkerContextEventListener::callListenerFunction): Ditto.
+        (WebCore::V8WorkerContextEventListener::getReceiverObject): Ditto.
+        * bindings/v8/V8WorkerContextEventListener.h:
+        (WebCore::V8WorkerContextEventListener::create): Removed
+            WorkerContextExecutionProxy* param.
+        * bindings/v8/WorkerContextExecutionProxy.cpp:
+        (WebCore::WorkerContextExecutionProxy::findOrCreateEventListener): Removed ContextType*
+            template param.
+        * bindings/v8/custom/V8CustomEventListener.cpp:
+        (WebCore::V8EventListener::V8EventListener): Removed Frame* param.
+        (WebCore::V8EventListener::getListenerFunction): Started using ScriptExecutionContext*.
+        (WebCore::V8EventListener::callListenerFunction): Ditto.
+        * bindings/v8/custom/V8CustomEventListener.h:
+        (WebCore::V8EventListener::create): Removed Frame* param.
+
 2009-10-14  Gaurav Shah  <gauravsh at google.com>
 
         Reviewed by Darin Fisher.
@@ -3336,7 +3418,6 @@
         (InjectedScript.CallFrameProxy.prototype._wrapScopeChain): don't send call frame properties until they're needed.
         * inspector/front-end/ScriptsPanel.js:
 
->>>>>>> .r49765
 2009-10-13  Yongjun Zhang  <yongjun.zhang at nokia.com>
 
         Reviewed by Ariya Hidayat.
diff --git a/WebCore/bindings/scripts/CodeGeneratorV8.pm b/WebCore/bindings/scripts/CodeGeneratorV8.pm
index 4135414..9ba9959 100644
--- a/WebCore/bindings/scripts/CodeGeneratorV8.pm
+++ b/WebCore/bindings/scripts/CodeGeneratorV8.pm
@@ -2166,7 +2166,7 @@ sub ReturnNativeToJSValue
     }
 
     if ($type eq "EventListener") {
-        return "return V8DOMWrapper::convertEventListenerToV8Object($value)";
+        return "return V8DOMWrapper::convertEventListenerToV8Object(imp->scriptExecutionContext(), $value)";
     }
 
     if ($type eq "SerializedScriptValue") {
diff --git a/WebCore/bindings/v8/DateExtension.cpp b/WebCore/bindings/v8/DateExtension.cpp
index 778a15a..7d8b9be 100644
--- a/WebCore/bindings/v8/DateExtension.cpp
+++ b/WebCore/bindings/v8/DateExtension.cpp
@@ -75,7 +75,7 @@ DateExtension* DateExtension::get()
 
 void DateExtension::setAllowSleep(bool allow)
 {
-    v8::Local<v8::Value> result = V8Proxy::retrieve()->context()->Global()->Get(v8::String::New("Date"));
+    v8::Local<v8::Value> result = V8Proxy::currentContext()->Global()->Get(v8::String::New("Date"));
     if (result.IsEmpty())
         return;
 
diff --git a/WebCore/bindings/v8/ScriptEventListener.cpp b/WebCore/bindings/v8/ScriptEventListener.cpp
index 16ca70f..03713be 100644
--- a/WebCore/bindings/v8/ScriptEventListener.cpp
+++ b/WebCore/bindings/v8/ScriptEventListener.cpp
@@ -36,6 +36,7 @@
 #include "EventListener.h"
 #include "Frame.h"
 #include "ScriptScope.h"
+#include "Tokenizer.h"
 #include "V8AbstractEventListener.h"
 #include "V8Binding.h"
 #include "XSSAuditor.h"
@@ -45,18 +46,29 @@ namespace WebCore {
 PassRefPtr<V8LazyEventListener> createAttributeEventListener(Node* node, Attribute* attr)
 {
     ASSERT(node);
+    int lineNumber = 1;
+    int columnNumber = 0;
+    String sourceURL;
 
-    Frame* frame = node->document()->frame();
+    if (Frame* frame = node->document()->frame()) {
+        ScriptController* scriptController = frame->script();
+        if (!scriptController->isEnabled())
+            return 0;
 
-    if (!frame)
-        return 0;
+        if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+            // This script is not safe to execute.
+            return 0;
+        }
 
-    if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
-        // This script is not safe to execute.
-        return 0;
+        if (frame->document()->tokenizer()) {
+            // FIXME: Change to use script->eventHandlerLineNumber() when implemented.
+            lineNumber = frame->document()->tokenizer()->lineNumber();
+            columnNumber = frame->document()->tokenizer()->columnNumber();
+        }
+        sourceURL = node->document()->url().string();
     }
 
-    return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), node->isSVGElement());
+    return V8LazyEventListener::create(attr->localName().string(), node->isSVGElement(), attr->value(), sourceURL, lineNumber, columnNumber);
 }
 
 PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attribute* attr)
@@ -64,22 +76,36 @@ PassRefPtr<V8LazyEventListener> createAttributeEventListener(Frame* frame, Attri
     if (!frame)
         return 0;
 
-    if (!frame->script()->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
+    int lineNumber = 1;
+    int columnNumber = 0;
+    String sourceURL;
+
+    ScriptController* scriptController = frame->script();
+    if (!scriptController->isEnabled())
+        return 0;
+
+    if (!scriptController->xssAuditor()->canCreateInlineEventListener(attr->localName().string(), attr->value())) {
         // This script is not safe to execute.
         return 0;
     }
 
-    return V8LazyEventListener::create(frame, attr->value(), attr->localName().string(), frame->document()->isSVGDocument());
+    if (frame->document()->tokenizer()) {
+        // FIXME: Change to use script->eventHandlerLineNumber() when implemented.
+        lineNumber = frame->document()->tokenizer()->lineNumber();
+        columnNumber = frame->document()->tokenizer()->columnNumber();
+    }
+    sourceURL = frame->document()->url().string();
+    return V8LazyEventListener::create(attr->localName().string(), frame->document()->isSVGDocument(), attr->value(), sourceURL, lineNumber, columnNumber);
 }
 
-String getEventListenerHandlerBody(ScriptExecutionContext*, ScriptState* scriptState, EventListener* listener)
+String getEventListenerHandlerBody(ScriptExecutionContext* context, ScriptState* scriptState, EventListener* listener)
 {
     if (listener->type() != EventListener::JSEventListenerType)
         return "";
 
     ScriptScope scope(scriptState);
     V8AbstractEventListener* v8Listener = static_cast<V8AbstractEventListener*>(listener);
-    v8::Handle<v8::Object> function = v8Listener->getListenerObject();
+    v8::Handle<v8::Object> function = v8Listener->getListenerObject(context);
     if (function.IsEmpty())
         return "";
 
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.cpp b/WebCore/bindings/v8/V8AbstractEventListener.cpp
index 795358e..f27c619 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.cpp
+++ b/WebCore/bindings/v8/V8AbstractEventListener.cpp
@@ -35,11 +35,12 @@
 #include "Document.h"
 #include "Event.h"
 #include "Frame.h"
-#include "Tokenizer.h"
 #include "V8Binding.h"
 #include "V8EventListenerList.h"
 #include "V8Proxy.h"
 #include "V8Utilities.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
 
 namespace WebCore {
 
@@ -49,28 +50,12 @@ static void weakEventListenerCallback(v8::Persistent<v8::Value>, void* parameter
     listener->disposeListenerObject();
 }
 
-V8AbstractEventListener::V8AbstractEventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, bool isAttribute)
+V8AbstractEventListener::V8AbstractEventListener(PassRefPtr<V8ListenerGuard> guard, bool isAttribute)
     : EventListener(JSEventListenerType)
     , m_isWeak(true)
     , m_isAttribute(isAttribute)
-    , m_frame(frame)
     , m_guard(guard)
-    , m_lineNumber(0)
-    , m_columnNumber(0)
 {
-    if (!m_frame)
-        return;
-
-    // We might be called directly from the parser.
-    v8::HandleScope handleScope;
-
-    m_context = V8Proxy::shared_context(m_frame);
-
-    // Get the position in the source if any.
-    if (m_isAttribute && m_frame->document()->tokenizer()) {
-        m_lineNumber = m_frame->document()->tokenizer()->lineNumber();
-        m_columnNumber = m_frame->document()->tokenizer()->columnNumber();
-    }
 }
 
 V8AbstractEventListener::~V8AbstractEventListener()
@@ -83,7 +68,7 @@ V8AbstractEventListener::~V8AbstractEventListener()
     disposeListenerObject();
 }
 
-void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event)
+void V8AbstractEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
 {
     // EventListener could be disconnected from the frame.
     if (disconnected())
@@ -95,25 +80,17 @@ void V8AbstractEventListener::handleEvent(ScriptExecutionContext* scriptExecutio
 
     v8::HandleScope handleScope;
 
-    if (!m_context)
-        return;
-
-    // Create a new local handle since the persistent handle stored in
-    // m_context may be disposed before we're done.
-    v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context->get());
+    v8::Local<v8::Context> v8Context = toV8Context(context);
     if (v8Context.IsEmpty())
         return;
 
-    // m_frame can removed by the callback function, protect it until the callback function returns.
-    RefPtr<Frame> protectFrame(m_frame);
-
     // Enter the V8 context in which to perform the event handling.
     v8::Context::Scope scope(v8Context);
 
     // Get the V8 wrapper for the event object.
     v8::Handle<v8::Value> jsEvent = V8DOMWrapper::convertEventToV8Object(event);
 
-    invokeEventHandler(v8Context, event, jsEvent);
+    invokeEventHandler(context, event, jsEvent);
 
     Document::updateStyleForAllDocuments();
 }
@@ -140,8 +117,13 @@ void V8AbstractEventListener::setListenerObject(v8::Handle<v8::Object> listener)
         m_listener.MakeWeak(this, &weakEventListenerCallback);
 }
 
-void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Context, Event* event, v8::Handle<v8::Value> jsEvent)
+void V8AbstractEventListener::invokeEventHandler(ScriptExecutionContext* context, Event* event, v8::Handle<v8::Value> jsEvent)
 {
+
+    v8::Local<v8::Context> v8Context = toV8Context(context);
+    if (v8Context.IsEmpty())
+        return;
+
     // We push the event being processed into the global object, so that it can be exposed by DOMWindow's bindings.
     v8::Local<v8::String> eventSymbol = v8::String::NewSymbol("event");
     v8::Local<v8::Value> returnValue;
@@ -165,7 +147,7 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
 
         // Call the event handler.
         tryCatch.SetVerbose(false); // We do not want to report the exception to the inspector console.
-        returnValue = callListenerFunction(jsEvent, event);
+        returnValue = callListenerFunction(context, jsEvent, event);
         if (!tryCatch.CanContinue())
             return;
 
diff --git a/WebCore/bindings/v8/V8AbstractEventListener.h b/WebCore/bindings/v8/V8AbstractEventListener.h
index c7736be..ceff001 100644
--- a/WebCore/bindings/v8/V8AbstractEventListener.h
+++ b/WebCore/bindings/v8/V8AbstractEventListener.h
@@ -97,15 +97,12 @@ namespace WebCore {
 
         virtual void handleEvent(ScriptExecutionContext*, Event*);
 
-        // Returns the owner frame of the listener.
-        Frame* frame() { return m_frame; }
-
         virtual bool isLazy() const { return false; }
 
         // Returns the listener object, either a function or an object.
-        v8::Local<v8::Object> getListenerObject()
+        v8::Local<v8::Object> getListenerObject(ScriptExecutionContext* context)
         {
-            prepareListenerObject();
+            prepareListenerObject(context);
             return v8::Local<v8::Object>::New(m_listener);
         }
 
@@ -122,30 +119,24 @@ namespace WebCore {
         // Dispose listener object and clear the handle.
         void disposeListenerObject();
 
-        // Detach the listener from its owner frame.
-        void disconnectFrame() { m_frame = 0; }
-
         virtual bool disconnected() const { return m_guard && m_guard->isDisconnected(); }
 
     protected:
-        V8AbstractEventListener(Frame*, PassRefPtr<V8ListenerGuard>, bool isAttribute);
+        V8AbstractEventListener(PassRefPtr<V8ListenerGuard>, bool isAttribute);
 
-        virtual void prepareListenerObject() { }
+        virtual void prepareListenerObject(ScriptExecutionContext*) { }
 
         void setListenerObject(v8::Handle<v8::Object> listener);
 
-        void invokeEventHandler(v8::Handle<v8::Context>, Event*, v8::Handle<v8::Value> jsEvent);
+        void invokeEventHandler(ScriptExecutionContext*, Event*, v8::Handle<v8::Value> jsEvent);
 
         // Get the receiver object to use for event listener call.
         v8::Local<v8::Object> getReceiverObject(Event*);
-
-        int lineNumber() const { return m_lineNumber; }
-
     private:
         // Implementation of EventListener function.
         virtual bool virtualisAttribute() const { return m_isAttribute; }
 
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsevent, Event*) = 0;
+        virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsevent, Event*) = 0;
 
         v8::Persistent<v8::Object> m_listener;
 
@@ -155,16 +146,7 @@ namespace WebCore {
         // Indicates if this is an HTML type listener.
         bool m_isAttribute;
 
-        // Frame to which the event listener is attached to. An event listener must be destroyed before its owner frame is
-        // deleted. See fast/dom/replaceChild.html
-        // FIXME: this could hold m_frame live until the event listener is deleted.
-        Frame* m_frame;
-        RefPtr<SharedPersistent<v8::Context> > m_context;
         RefPtr<V8ListenerGuard> m_guard;
-
-        // Position in the HTML source for HTML event listeners.
-        int m_lineNumber;
-        int m_columnNumber;
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8DOMWrapper.cpp b/WebCore/bindings/v8/V8DOMWrapper.cpp
index 377f279..e09059b 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.cpp
+++ b/WebCore/bindings/v8/V8DOMWrapper.cpp
@@ -1386,14 +1386,14 @@ v8::Handle<v8::Value> V8DOMWrapper::convertEventTargetToV8Object(EventTarget* ta
     return notHandledByInterceptor();
 }
 
-v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(EventListener* listener)
+v8::Handle<v8::Value> V8DOMWrapper::convertEventListenerToV8Object(ScriptExecutionContext* context, EventListener* listener)
 {
     if (!listener)
         return v8::Null();
 
     // FIXME: can a user take a lazy event listener and set to other places?
     V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListener*>(listener);
-    return v8listener->getListenerObject();
+    return v8listener->getListenerObject(context);
 }
 
 PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
@@ -1409,7 +1409,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Node* node, v8::Local<v
         proxy = V8Proxy::retrieve(V8Proxy::retrieveFrameForEnteredContext());
 
     if (proxy)
-        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute);
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute);
 
     return 0;
 }
@@ -1429,7 +1429,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(AbstractWorker* worker,
 
     V8Proxy* proxy = V8Proxy::retrieve(worker->scriptExecutionContext());
     if (proxy)
-        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute);
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute);
 
     return 0;
 }
@@ -1445,7 +1445,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(Notification* notificat
 
     V8Proxy* proxy = V8Proxy::retrieve(notification->scriptExecutionContext());
     if (proxy)
-        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute);
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute);
 
     return 0;
 }
@@ -1469,7 +1469,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarge
 {
     V8Proxy* proxy = V8Proxy::retrieve(eventTarget->scriptExecutionContext());
     if (proxy)
-        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute);
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute);
 
 #if ENABLE(WORKERS)
     WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
@@ -1483,7 +1483,7 @@ PassRefPtr<EventListener> V8DOMWrapper::getEventListener(EventTarget* eventTarge
 PassRefPtr<EventListener> V8DOMWrapper::getEventListener(V8Proxy* proxy, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup)
 {
     if (proxy)
-        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->frame(), proxy->listenerGuard(), value, isAttribute);
+        return (lookup == ListenerFindOnly) ? V8EventListenerList::findWrapper(value, isAttribute) : V8EventListenerList::findOrCreateWrapper<V8EventListener>(proxy->listenerGuard(), value, isAttribute);
 
     return 0;
 }
diff --git a/WebCore/bindings/v8/V8DOMWrapper.h b/WebCore/bindings/v8/V8DOMWrapper.h
index 2257688..4c3b018 100644
--- a/WebCore/bindings/v8/V8DOMWrapper.h
+++ b/WebCore/bindings/v8/V8DOMWrapper.h
@@ -216,12 +216,12 @@ namespace WebCore {
         static v8::Handle<v8::Value> convertEventTargetToV8Object(EventTarget*);
 
         // Wrap and unwrap JS event listeners.
-        static v8::Handle<v8::Value> convertEventListenerToV8Object(PassRefPtr<EventListener> eventListener)
+        static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext* context, PassRefPtr<EventListener> eventListener)
         {
-            return convertEventListenerToV8Object(eventListener.get());
+            return convertEventListenerToV8Object(context, eventListener.get());
         }
 
-        static v8::Handle<v8::Value> convertEventListenerToV8Object(EventListener*);
+        static v8::Handle<v8::Value> convertEventListenerToV8Object(ScriptExecutionContext*, EventListener*);
 
         static PassRefPtr<EventListener> getEventListener(Node* node, v8::Local<v8::Value> value, bool isAttribute, ListenerLookupType lookup);
 
diff --git a/WebCore/bindings/v8/V8EventListenerList.h b/WebCore/bindings/v8/V8EventListenerList.h
index 506e5dc..29b4874 100644
--- a/WebCore/bindings/v8/V8EventListenerList.h
+++ b/WebCore/bindings/v8/V8EventListenerList.h
@@ -54,8 +54,8 @@ namespace WebCore {
             return doFindWrapper(v8::Local<v8::Object>::Cast(value), wrapperProperty);
         }
 
-        template<typename WrapperType, typename ContextType>
-        static PassRefPtr<V8EventListener> findOrCreateWrapper(ContextType*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute);
+        template<typename WrapperType>
+        static PassRefPtr<V8EventListener> findOrCreateWrapper(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Value>, bool isAttribute);
 
         static void clearWrapper(v8::Handle<v8::Object> listenerObject, bool isAttribute)
         {
@@ -80,8 +80,8 @@ namespace WebCore {
         }
     };
 
-    template<typename WrapperType, typename ContextType>
-    PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(ContextType* context, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute)
+    template<typename WrapperType>
+    PassRefPtr<V8EventListener> V8EventListenerList::findOrCreateWrapper(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Value> value, bool isAttribute)
     {
         ASSERT(v8::Context::InContext());
         if (!value->IsObject())
@@ -94,7 +94,7 @@ namespace WebCore {
         if (wrapper)
             return wrapper;
 
-        PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(context, guard, object, isAttribute);
+        PassRefPtr<V8EventListener> wrapperPtr = WrapperType::create(guard, object, isAttribute);
         if (wrapperPtr)
             object->SetHiddenValue(wrapperProperty, v8::External::Wrap(wrapperPtr.get()));
 
diff --git a/WebCore/bindings/v8/V8IsolatedWorld.h b/WebCore/bindings/v8/V8IsolatedWorld.h
index 15d8711..663f4bd 100644
--- a/WebCore/bindings/v8/V8IsolatedWorld.h
+++ b/WebCore/bindings/v8/V8IsolatedWorld.h
@@ -88,7 +88,7 @@ namespace WebCore {
         }
 
         v8::Handle<v8::Context> context() { return m_context->get(); }
-        PassRefPtr<SharedPersistent<v8::Context> > shared_context() { return m_context; }
+        PassRefPtr<SharedPersistent<v8::Context> > sharedContext() { return m_context; }
 
         DOMDataStore* getDOMDataStore() const { return m_domDataStore.getStore(); }
 
diff --git a/WebCore/bindings/v8/V8LazyEventListener.cpp b/WebCore/bindings/v8/V8LazyEventListener.cpp
index 9b58571..54740a9 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.cpp
+++ b/WebCore/bindings/v8/V8LazyEventListener.cpp
@@ -40,25 +40,30 @@
 
 namespace WebCore {
 
-V8LazyEventListener::V8LazyEventListener(Frame* frame, const String& code, const String& functionName, bool isSVGEvent)
-    : V8AbstractEventListener(frame, 0, true)
-    , m_code(code)
+V8LazyEventListener::V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber)
+    : V8AbstractEventListener(0, true)
     , m_functionName(functionName)
     , m_isSVGEvent(isSVGEvent)
+    , m_code(code)
+    , m_sourceURL(sourceURL)
+    , m_lineNumber(lineNumber)
+    , m_columnNumber(columnNumber)
 {
 }
 
-v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8LazyEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
 {
-    v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject());
+    v8::Local<v8::Function> handlerFunction = v8::Local<v8::Function>::Cast(getListenerObject(context));
     v8::Local<v8::Object> receiver = getReceiverObject(event);
     if (handlerFunction.IsEmpty() || receiver.IsEmpty())
         return v8::Local<v8::Value>();
 
     v8::Handle<v8::Value> parameters[1] = { jsEvent };
 
-    V8Proxy* proxy = V8Proxy::retrieve(frame());
-    return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+    if (V8Proxy* proxy = V8Proxy::retrieve(context))
+        return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+
+    return v8::Local<v8::Value>();
 }
 
 static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& args)
@@ -66,16 +71,19 @@ static v8::Handle<v8::Value> V8LazyEventListenerToString(const v8::Arguments& ar
     return args.Holder()->GetHiddenValue(V8HiddenPropertyName::toStringString());
 }
 
-void V8LazyEventListener::prepareListenerObject()
+void V8LazyEventListener::prepareListenerObject(ScriptExecutionContext* context)
 {
     if (hasExistingListenerObject())
         return;
 
-    // Switch to the context of m_frame.
     v8::HandleScope handleScope;
 
+    V8Proxy* proxy = V8Proxy::retrieve(context);
+    if (!proxy)
+        return;
+
     // Use the outer scope to hold context.
-    v8::Handle<v8::Context> v8Context = V8Proxy::mainWorldContext(frame());
+    v8::Handle<v8::Context> v8Context = proxy->context();
     // Bail out if we cannot get the context.
     if (v8Context.IsEmpty())
         return;
@@ -101,10 +109,8 @@ void V8LazyEventListener::prepareListenerObject()
     // Insert '\n' otherwise //-style comments could break the handler.
     code.append(  "\n}).call(this, evt);}}}})");
     v8::Handle<v8::String> codeExternalString = v8ExternalString(code);
-    v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, frame()->document()->url(), lineNumber());
+    v8::Handle<v8::Script> script = V8Proxy::compileScript(codeExternalString, m_sourceURL, m_lineNumber);
     if (!script.IsEmpty()) {
-        V8Proxy* proxy = V8Proxy::retrieve(frame());
-        ASSERT(proxy);
         v8::Local<v8::Value> value = proxy->runScript(script, false);
         if (!value.IsEmpty()) {
             ASSERT(value->IsFunction());
diff --git a/WebCore/bindings/v8/V8LazyEventListener.h b/WebCore/bindings/v8/V8LazyEventListener.h
index ba460e6..699460b 100644
--- a/WebCore/bindings/v8/V8LazyEventListener.h
+++ b/WebCore/bindings/v8/V8LazyEventListener.h
@@ -45,24 +45,27 @@ namespace WebCore {
     // A V8LazyEventListener is always a HTML event handler.
     class V8LazyEventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8LazyEventListener> create(Frame* frame, const String& code, const String& functionName, bool isSVGEvent)
+        static PassRefPtr<V8LazyEventListener> create(const String& functionName, bool isSVGEvent, const String& code, const String& sourceURL, int lineNumber, int columnNumber)
         {
-            return adoptRef(new V8LazyEventListener(frame, code, functionName, isSVGEvent));
+            return adoptRef(new V8LazyEventListener(functionName, isSVGEvent, code, sourceURL, lineNumber, columnNumber));
         }
 
         virtual bool isLazy() const { return true; }
 
     protected:
-        virtual void prepareListenerObject();
+        virtual void prepareListenerObject(ScriptExecutionContext*);
 
     private:
-        V8LazyEventListener(Frame*, const String& code, const String& functionName, bool isSVGEvent);
+        V8LazyEventListener(const String& functionName, bool isSVGEvent, const String& code, const String sourceURL, int lineNumber, int columnNumber);
 
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
+        virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
 
-        String m_code;
         String m_functionName;
         bool m_isSVGEvent;
+        String m_code;
+        String m_sourceURL;
+        int m_lineNumber;
+        int m_columnNumber;
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Proxy.cpp b/WebCore/bindings/v8/V8Proxy.cpp
index 53f6e5b..1e2100c 100644
--- a/WebCore/bindings/v8/V8Proxy.cpp
+++ b/WebCore/bindings/v8/V8Proxy.cpp
@@ -50,6 +50,7 @@
 #include "V8HiddenPropertyName.h"
 #include "V8Index.h"
 #include "V8IsolatedWorld.h"
+#include "WorkerContextExecutionProxy.h"
 
 #include <algorithm>
 #include <utility>
@@ -205,12 +206,13 @@ static void reportFatalErrorInV8(const char* location, const char* message)
 }
 
 V8Proxy::V8Proxy(Frame* frame)
-    : m_frame(frame),
-      m_context(SharedPersistent<v8::Context>::create()),
-      m_listenerGuard(V8ListenerGuard::create()),
-      m_inlineCode(false),
-      m_timerCallback(false),
-      m_recursion(0) { }
+    : m_frame(frame)
+    , m_listenerGuard(V8ListenerGuard::create())
+    , m_inlineCode(false)
+    , m_timerCallback(false)
+    , m_recursion(0)
+{
+}
 
 V8Proxy::~V8Proxy()
 {
@@ -305,7 +307,7 @@ void V8Proxy::evaluateInNewContext(const Vector<ScriptSourceCode>& sources, int
     v8::HandleScope handleScope;
 
     // Set up the DOM window as the prototype of the new global object.
-    v8::Handle<v8::Context> windowContext = context();
+    v8::Handle<v8::Context> windowContext = m_context;
     v8::Handle<v8::Object> windowGlobal = windowContext->Global();
     v8::Handle<v8::Object> windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8ClassIndex::DOMWINDOW, windowGlobal);
 
@@ -347,7 +349,7 @@ void V8Proxy::setInjectedScriptContextDebugId(v8::Handle<v8::Context> targetCont
     v8::Context::Scope contextScope(targetContext);
     v8::Handle<v8::Object> contextData = v8::Object::New();
 
-    v8::Handle<v8::Value> windowContextData = context()->GetData();
+    v8::Handle<v8::Value> windowContextData = m_context->GetData();
     if (windowContextData->IsObject()) {
         v8::Handle<v8::String> propertyName = v8::String::New(kContextDebugDataValue);
         contextData->Set(propertyName, v8::Object::Cast(*windowContextData)->Get(propertyName));
@@ -508,8 +510,8 @@ v8::Local<v8::Object> V8Proxy::createWrapperFromCacheSlowCase(V8ClassIndex::V8Wr
     // Not in cache.
     int classIndex = V8ClassIndex::ToInt(type);
     initContextIfNeeded();
-    v8::Context::Scope scope(context());
-    v8::Local<v8::Function> function = V8DOMWrapper::getConstructor(type, getHiddenObjectPrototype(context()));
+    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);
@@ -522,9 +524,9 @@ bool V8Proxy::isContextInitialized()
 {
     // m_context, m_global, and m_wrapperBoilerplates should
     // all be non-empty if if m_context is non-empty.
-    ASSERT(context().IsEmpty() || !m_global.IsEmpty());
-    ASSERT(context().IsEmpty() || !m_wrapperBoilerplates.IsEmpty());
-    return !context().IsEmpty();
+    ASSERT(m_context.IsEmpty() || !m_global.IsEmpty());
+    ASSERT(m_context.IsEmpty() || !m_wrapperBoilerplates.IsEmpty());
+    return !m_context.IsEmpty();
 }
 
 DOMWindow* V8Proxy::retrieveWindow(v8::Handle<v8::Context> context)
@@ -668,7 +670,7 @@ void V8Proxy::clearDocumentWrapper()
 void V8Proxy::updateDocumentWrapperCache()
 {
     v8::HandleScope handleScope;
-    v8::Context::Scope contextScope(context());
+    v8::Context::Scope contextScope(m_context);
 
     // If the document has no frame, NodeToV8Object might get the
     // document wrapper for a document that is about to be deleted.
@@ -690,20 +692,21 @@ void V8Proxy::updateDocumentWrapperCache()
         clearDocumentWrapperCache();
         return;
     }
-    context()->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
+    m_context->Global()->ForceSet(v8::String::New("document"), documentWrapper, static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
 }
 
 void V8Proxy::clearDocumentWrapperCache()
 {
-    ASSERT(!context().IsEmpty());
-    context()->Global()->ForceDelete(v8::String::New("document"));
+    ASSERT(!m_context.IsEmpty());
+    m_context->Global()->ForceDelete(v8::String::New("document"));
 }
 
 void V8Proxy::disposeContextHandles()
 {
-    if (!context().IsEmpty()) {
+    if (!m_context.IsEmpty()) {
         m_frame->loader()->client()->didDestroyScriptContextForFrame();
-        shared_context()->disposeHandle();
+        m_context.Dispose();
+        m_context.Clear();
     }
 
     if (!m_wrapperBoilerplates.IsEmpty()) {
@@ -748,7 +751,7 @@ void V8Proxy::clearForClose()
 {
     resetIsolatedWorlds();
 
-    if (!context().IsEmpty()) {
+    if (!m_context.IsEmpty()) {
         v8::HandleScope handleScope;
 
         clearDocumentWrapper();
@@ -761,11 +764,11 @@ void V8Proxy::clearForNavigation()
     disconnectEventListeners();
     resetIsolatedWorlds();
 
-    if (!context().IsEmpty()) {
+    if (!m_context.IsEmpty()) {
         v8::HandleScope handle;
         clearDocumentWrapper();
 
-        v8::Context::Scope contextScope(context());
+        v8::Context::Scope contextScope(m_context);
 
         // Clear the document wrapper cache before turning on access checks on
         // the old DOMWindow wrapper. This way, access to the document wrapper
@@ -778,7 +781,7 @@ void V8Proxy::clearForNavigation()
         wrapper->TurnOnAccessCheck();
 
         // Separate the context from its global object.
-        context()->DetachGlobal();
+        m_context->DetachGlobal();
 
         disposeContextHandles();
     }
@@ -789,7 +792,7 @@ void V8Proxy::setSecurityToken()
     Document* document = m_frame->document();
     // Setup security origin and security token.
     if (!document) {
-        context()->UseDefaultSecurityToken();
+        m_context->UseDefaultSecurityToken();
         return;
     }
 
@@ -809,14 +812,14 @@ void V8Proxy::setSecurityToken()
     // case, we use the global object as the security token to avoid
     // calling canAccess when a script accesses its own objects.
     if (token.isEmpty() || token == "null") {
-        context()->UseDefaultSecurityToken();
+        m_context->UseDefaultSecurityToken();
         return;
     }
 
     CString utf8Token = token.utf8();
     // NOTE: V8 does identity comparison in fast path, must use a symbol
     // as the security token.
-    context()->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.length()));
+    m_context->SetSecurityToken(v8::String::NewSymbol(utf8Token.data(), utf8Token.length()));
 }
 
 void V8Proxy::updateDocument()
@@ -835,7 +838,7 @@ void V8Proxy::updateDocument()
     initContextIfNeeded();
 
     // Bail out if context initialization failed.
-    if (context().IsEmpty())
+    if (m_context.IsEmpty())
         return;
 
     // We have a new document and we need to update the cache.
@@ -1043,7 +1046,7 @@ bool V8Proxy::installDOMWindow(v8::Handle<v8::Context> context, DOMWindow* windo
 void V8Proxy::initContextIfNeeded()
 {
     // Bail out if the context has already been initialized.
-    if (!context().IsEmpty())
+    if (!m_context.IsEmpty())
         return;
 
     // Create a handle scope for all local handles.
@@ -1069,17 +1072,16 @@ void V8Proxy::initContextIfNeeded()
     }
 
 
-    v8::Persistent<v8::Context> context = createNewContext(m_global, 0);
-    if (context.IsEmpty())
+    m_context = createNewContext(m_global, 0);
+    if (m_context.IsEmpty())
         return;
-    m_context->set(context);
 
-
-    v8::Context::Scope contextScope(context);
+    v8::Local<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context);
+    v8::Context::Scope contextScope(v8Context);
 
     // Store the first global object created so we can reuse it.
     if (m_global.IsEmpty()) {
-        m_global = v8::Persistent<v8::Object>::New(context->Global());
+        m_global = v8::Persistent<v8::Object>::New(v8Context->Global());
         // Bail out if allocation of the first global objects fails.
         if (m_global.IsEmpty()) {
             disposeContextHandles();
@@ -1090,7 +1092,7 @@ void V8Proxy::initContextIfNeeded()
 #endif
     }
 
-    installHiddenObjectPrototype(context);
+    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()) {
@@ -1101,7 +1103,7 @@ void V8Proxy::initContextIfNeeded()
     V8GCController::registerGlobalHandle(PROXY, this, m_wrapperBoilerplates);
 #endif
 
-    if (!installDOMWindow(context, m_frame->domWindow()))
+    if (!installDOMWindow(v8Context, m_frame->domWindow()))
         disposeContextHandles();
 
     updateDocument();
@@ -1184,21 +1186,16 @@ v8::Local<v8::Context> V8Proxy::context(Frame* frame)
     return context;
 }
 
-PassRefPtr<SharedPersistent<v8::Context> > V8Proxy::shared_context(Frame* frame)
+v8::Local<v8::Context> V8Proxy::context()
 {
-    V8Proxy *proxy = V8Proxy::retrieve(frame);
-    if (!proxy)
-        return 0;
-
-    proxy->initContextIfNeeded();
-    RefPtr<SharedPersistent<v8::Context> > context = proxy->shared_context();
     if (V8IsolatedWorld* world = V8IsolatedWorld::getEntered()) {
-        context = world->shared_context();
-        if (frame != V8Proxy::retrieveFrame(context->get()))
-            return 0;
+        RefPtr<SharedPersistent<v8::Context> > context = world->sharedContext();
+        if (m_frame != V8Proxy::retrieveFrame(context->get()))
+            return v8::Local<v8::Context>();
+        return v8::Local<v8::Context>::New(context->get());
     }
-
-    return context;
+    initContextIfNeeded();
+    return v8::Local<v8::Context>::New(m_context);;
 }
 
 v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
@@ -1208,7 +1205,7 @@ v8::Local<v8::Context> V8Proxy::mainWorldContext(Frame* frame)
         return v8::Local<v8::Context>();
 
     proxy->initContextIfNeeded();
-    return v8::Local<v8::Context>::New(proxy->context());
+    return v8::Local<v8::Context>::New(proxy->m_context);
 }
 
 v8::Local<v8::Context> V8Proxy::currentContext()
@@ -1342,17 +1339,17 @@ void V8Proxy::registerExtension(v8::Extension* extension, int extensionGroup)
 bool V8Proxy::setContextDebugId(int debugId)
 {
     ASSERT(debugId > 0);
-    if (context().IsEmpty())
+    if (m_context.IsEmpty())
         return false;
     v8::HandleScope scope;
-    if (!context()->GetData()->IsUndefined())
+    if (!m_context->GetData()->IsUndefined())
         return false;
 
-    v8::Context::Scope contextScope(context());
+    v8::Context::Scope contextScope(m_context);
     v8::Handle<v8::Object> contextData = v8::Object::New();
     contextData->Set(v8::String::New(kContextDebugDataType), v8::String::New("page"));
     contextData->Set(v8::String::New(kContextDebugDataValue), v8::Integer::New(debugId));
-    context()->SetData(contextData);
+    m_context->SetData(contextData);
     return true;
 }
 
@@ -1385,4 +1382,16 @@ void V8Proxy::installHiddenObjectPrototype(v8::Handle<v8::Context> context)
     context->Global()->SetHiddenValue(hiddenObjectPrototypeString, objectPrototype);
 }
 
+v8::Local<v8::Context> toV8Context(ScriptExecutionContext* context)
+{
+    if (context->isDocument()) {
+        if (V8Proxy* proxy = V8Proxy::retrieve(context))
+            return proxy->context();
+    } else if (context->isWorkerContext()) {
+        if (WorkerContextExecutionProxy* proxy = static_cast<WorkerContext*>(context)->script()->proxy())
+            return proxy->context();
+    }
+    return v8::Local<v8::Context>();
+}
+
 }  // namespace WebCore
diff --git a/WebCore/bindings/v8/V8Proxy.h b/WebCore/bindings/v8/V8Proxy.h
index e52c58d..9443ca8 100644
--- a/WebCore/bindings/v8/V8Proxy.h
+++ b/WebCore/bindings/v8/V8Proxy.h
@@ -257,7 +257,6 @@ namespace WebCore {
         // Returns V8 Context of a frame. If none exists, creates
         // a new context. It is potentially slow and consumes memory.
         static v8::Local<v8::Context> context(Frame*);
-        static PassRefPtr<SharedPersistent<v8::Context> > shared_context(Frame*);
         static v8::Local<v8::Context> mainWorldContext(Frame*);
         static v8::Local<v8::Context> currentContext();
 
@@ -298,15 +297,7 @@ namespace WebCore {
         static int sourceLineNumber();
         static String sourceName();
 
-        v8::Handle<v8::Context> context()
-        {
-            return m_context->get();
-        }
-
-        PassRefPtr<SharedPersistent<v8::Context> > shared_context()
-        {
-            return m_context;
-        }
+        v8::Local<v8::Context> context();
 
         PassRefPtr<V8ListenerGuard> listenerGuard()
         {
@@ -396,7 +387,7 @@ namespace WebCore {
 
         Frame* m_frame;
 
-        RefPtr<SharedPersistent<v8::Context> > m_context;
+        v8::Persistent<v8::Context> m_context;
 
         RefPtr<V8ListenerGuard> m_listenerGuard;
 
@@ -457,6 +448,8 @@ namespace WebCore {
     }
 
 
+    v8::Local<v8::Context> toV8Context(ScriptExecutionContext*);
+
     // Used by an interceptor callback that it hasn't found anything to
     // intercept.
     inline static v8::Local<v8::Object> notHandledByInterceptor()
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
index 8563c58..8dc4b8d 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.cpp
@@ -36,17 +36,24 @@
 
 #include "Event.h"
 #include "V8Binding.h"
+#include "WorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
 
 namespace WebCore {
 
-V8WorkerContextEventListener::V8WorkerContextEventListener(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline)
-    : V8EventListener(0, guard, listener, isInline)
-    , m_proxy(proxy)
+static WorkerContextExecutionProxy* workerProxy(ScriptExecutionContext* context)
 {
+    ASSERT(context->isWorkerContext());
+    WorkerContext* workerContext = static_cast<WorkerContext*>(context);
+    return workerContext->script()->proxy();
 }
 
-void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* event)
+V8WorkerContextEventListener::V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline)
+    : V8EventListener(guard, listener, isInline)
+{
+}
+
+void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext* context, Event* event)
 {
     // Is the EventListener disconnected?
     if (disconnected())
@@ -58,12 +65,16 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* e
 
     v8::HandleScope handleScope;
 
-    v8::Handle<v8::Context> context = m_proxy->context();
-    if (context.IsEmpty())
+    WorkerContextExecutionProxy* proxy = workerProxy(context);
+    if (!proxy)
+        return;
+
+    v8::Handle<v8::Context> v8Context = proxy->context();
+    if (v8Context.IsEmpty())
         return;
 
     // Enter the V8 context in which to perform the event handling.
-    v8::Context::Scope scope(context);
+    v8::Context::Scope scope(v8Context);
 
     // Get the V8 wrapper for the event object.
     v8::Handle<v8::Value> jsEvent = WorkerContextExecutionProxy::convertEventToV8Object(event);
@@ -71,7 +82,7 @@ void V8WorkerContextEventListener::handleEvent(ScriptExecutionContext*, Event* e
     invokeEventHandler(context, event, jsEvent);
 }
 
-bool V8WorkerContextEventListener::reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber)
+bool V8WorkerContextEventListener::reportError(ScriptExecutionContext* context, const String& message, const String& url, int lineNumber)
 {
     // Is the EventListener disconnected?
     if (disconnected())
@@ -82,14 +93,18 @@ bool V8WorkerContextEventListener::reportError(ScriptExecutionContext*, const St
 
     v8::HandleScope handleScope;
 
-    v8::Handle<v8::Context> context = m_proxy->context();
-    if (context.IsEmpty())
+    WorkerContextExecutionProxy* proxy = workerProxy(context);
+    if (!proxy)
+        return false;
+
+    v8::Handle<v8::Context> v8Context = proxy->context();
+    if (v8Context.IsEmpty())
         return false;
 
     // Enter the V8 context in which to perform the event handling.
-    v8::Context::Scope scope(context);
+    v8::Context::Scope scope(v8Context);
 
-    v8::Local<v8::Object> listener = getListenerObject();
+    v8::Local<v8::Object> listener = getListenerObject(context);
     v8::Local<v8::Value> returnValue;
     {
         // Catch exceptions thrown in calling the function so they do not propagate to javascript code that caused the event to fire.
@@ -118,24 +133,25 @@ bool V8WorkerContextEventListener::reportError(ScriptExecutionContext*, const St
     return errorHandled;
 }
 
-v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8WorkerContextEventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
 {
-    v8::Local<v8::Function> handlerFunction = getListenerFunction();
-    v8::Local<v8::Object> receiver = getReceiverObject(event);
+    v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
+    v8::Local<v8::Object> receiver = getReceiverObject(context, event);
     if (handlerFunction.IsEmpty() || receiver.IsEmpty())
         return v8::Local<v8::Value>();
 
     v8::Handle<v8::Value> parameters[1] = { jsEvent };
     v8::Local<v8::Value> result = handlerFunction->Call(receiver, 1, parameters);
 
-    m_proxy->trackEvent(event);
+    if (WorkerContextExecutionProxy* proxy = workerProxy(context))
+        proxy->trackEvent(event);
 
     return result;
 }
 
-v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(Event* event)
+v8::Local<v8::Object> V8WorkerContextEventListener::getReceiverObject(ScriptExecutionContext* context, Event* event)
 {
-    v8::Local<v8::Object> listener = getListenerObject();
+    v8::Local<v8::Object> listener = getListenerObject(context);
 
     if (!listener.IsEmpty() && !listener->IsFunction())
         return listener;
diff --git a/WebCore/bindings/v8/V8WorkerContextEventListener.h b/WebCore/bindings/v8/V8WorkerContextEventListener.h
index a6555a0..3f9f862 100644
--- a/WebCore/bindings/v8/V8WorkerContextEventListener.h
+++ b/WebCore/bindings/v8/V8WorkerContextEventListener.h
@@ -44,22 +44,19 @@ namespace WebCore {
 
     class V8WorkerContextEventListener : public V8EventListener {
     public:
-        static PassRefPtr<V8WorkerContextEventListener> create(WorkerContextExecutionProxy* proxy, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline)
+        static PassRefPtr<V8WorkerContextEventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isInline)
         {
-            return adoptRef(new V8WorkerContextEventListener(proxy, guard, listener, isInline));
+            return adoptRef(new V8WorkerContextEventListener(guard, listener, isInline));
         }
 
         virtual void handleEvent(ScriptExecutionContext*, Event*);
         virtual bool reportError(ScriptExecutionContext*, const String& message, const String& url, int lineNumber);
 
-        WorkerContextExecutionProxy* proxy() const { return m_proxy; }
-
     private:
-        V8WorkerContextEventListener(WorkerContextExecutionProxy*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline);
+        V8WorkerContextEventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isInline);
 
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
-        v8::Local<v8::Object> getReceiverObject(Event*);
-        WorkerContextExecutionProxy* m_proxy;
+        virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
+        v8::Local<v8::Object> getReceiverObject(ScriptExecutionContext*, Event*);
     };
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
index 4a2cd0e..247b016 100644
--- a/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
+++ b/WebCore/bindings/v8/WorkerContextExecutionProxy.cpp
@@ -406,7 +406,7 @@ v8::Local<v8::Value> WorkerContextExecutionProxy::runScript(v8::Handle<v8::Scrip
 
 PassRefPtr<V8EventListener> WorkerContextExecutionProxy::findOrCreateEventListener(v8::Local<v8::Value> object, bool isInline, bool findOnly)
 {
-    return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(this, m_listenerGuard, object, isInline);
+    return findOnly ? V8EventListenerList::findWrapper(object, isInline) : V8EventListenerList::findOrCreateWrapper<V8WorkerContextEventListener>(m_listenerGuard, object, isInline);
 }
 
 void WorkerContextExecutionProxy::trackEvent(Event* event)
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
index 91abecd..17c86a3 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.cpp
@@ -35,15 +35,15 @@
 
 namespace WebCore {
 
-V8EventListener::V8EventListener(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute)
-    : V8AbstractEventListener(frame, guard, isAttribute)
+V8EventListener::V8EventListener(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute)
+    : V8AbstractEventListener(guard, isAttribute)
 {
     setListenerObject(listener);
 }
 
-v8::Local<v8::Function> V8EventListener::getListenerFunction()
+v8::Local<v8::Function> V8EventListener::getListenerFunction(ScriptExecutionContext* context)
 {
-    v8::Local<v8::Object> listener = getListenerObject();
+    v8::Local<v8::Object> listener = getListenerObject(context);
 
     // Has the listener been disposed?
     if (listener.IsEmpty())
@@ -61,19 +61,20 @@ v8::Local<v8::Function> V8EventListener::getListenerFunction()
     return v8::Local<v8::Function>();
 }
 
-v8::Local<v8::Value> V8EventListener::callListenerFunction(v8::Handle<v8::Value> jsEvent, Event* event)
+v8::Local<v8::Value> V8EventListener::callListenerFunction(ScriptExecutionContext* context, v8::Handle<v8::Value> jsEvent, Event* event)
 {
-    v8::Local<v8::Function> handlerFunction = getListenerFunction();
+
+    v8::Local<v8::Function> handlerFunction = getListenerFunction(context);
     v8::Local<v8::Object> receiver = getReceiverObject(event);
     if (handlerFunction.IsEmpty() || receiver.IsEmpty())
         return v8::Local<v8::Value>();
 
     v8::Handle<v8::Value> parameters[1] = { jsEvent };
 
-    V8Proxy* proxy = V8Proxy::retrieve(frame());
-    if (!proxy)
-        return v8::Local<v8::Value>();
-    return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+    if (V8Proxy* proxy = V8Proxy::retrieve(context))
+        return proxy->callFunction(handlerFunction, receiver, 1, parameters);
+
+    return v8::Local<v8::Value>();
 }
 
 } // namespace WebCore
diff --git a/WebCore/bindings/v8/custom/V8CustomEventListener.h b/WebCore/bindings/v8/custom/V8CustomEventListener.h
index e34f24f..dc9d33b 100644
--- a/WebCore/bindings/v8/custom/V8CustomEventListener.h
+++ b/WebCore/bindings/v8/custom/V8CustomEventListener.h
@@ -44,18 +44,18 @@ namespace WebCore {
     // that can handle the event.
     class V8EventListener : public V8AbstractEventListener {
     public:
-        static PassRefPtr<V8EventListener> create(Frame* frame, PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute)
+        static PassRefPtr<V8EventListener> create(PassRefPtr<V8ListenerGuard> guard, v8::Local<v8::Object> listener, bool isAttribute)
         {
-            return adoptRef(new V8EventListener(frame, guard, listener, isAttribute));
+            return adoptRef(new V8EventListener(guard, listener, isAttribute));
         }
 
     protected:
-        V8EventListener(Frame*, PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute);
+        V8EventListener(PassRefPtr<V8ListenerGuard>, v8::Local<v8::Object> listener, bool isAttribute);
 
-        v8::Local<v8::Function> getListenerFunction();
+        v8::Local<v8::Function> getListenerFunction(ScriptExecutionContext*);
 
     private:
-        virtual v8::Local<v8::Value> callListenerFunction(v8::Handle<v8::Value> jsEvent, Event*);
+      virtual v8::Local<v8::Value> callListenerFunction(ScriptExecutionContext*, v8::Handle<v8::Value> jsEvent, Event*);
      };
 
 } // namespace WebCore

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list