[V8] Run-time exception in onmessage handler is not forwarded to the worker object.
authorjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2009 20:40:19 +0000 (20:40 +0000)
committerjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 4 Sep 2009 20:40:19 +0000 (20:40 +0000)
https://bugs.webkit.org/show_bug.cgi?id=28980

Reviewed by Adam Barth.

Tested by worker-close.html.

* bindings/v8/ScriptFunctionCall.cpp:
* bindings/v8/V8AbstractEventListener.cpp:
(WebCore::V8AbstractEventListener::invokeEventHandler):
* bindings/v8/V8Utilities.cpp:
(WebCore::getScriptExecutionContext):
(WebCore::reportException):
* bindings/v8/V8Utilities.h:
(WebCore::getScriptExecutionContext):
* bindings/v8/custom/V8MessageChannelConstructor.cpp:
(WebCore::CALLBACK_FUNC_DECL):
* bindings/v8/custom/V8SharedWorkerCustom.cpp:
(WebCore::CALLBACK_FUNC_DECL):
* bindings/v8/custom/V8WorkerCustom.cpp:
(WebCore::CALLBACK_FUNC_DECL):
* bindings/v8/custom/V8XMLHttpRequestConstructor.cpp:
(WebCore::CALLBACK_FUNC_DECL):
* bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
(WebCore::CALLBACK_FUNC_DECL):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@48072 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/bindings/v8/ScriptFunctionCall.cpp
WebCore/bindings/v8/V8AbstractEventListener.cpp
WebCore/bindings/v8/V8Utilities.cpp
WebCore/bindings/v8/V8Utilities.h
WebCore/bindings/v8/custom/V8MessageChannelConstructor.cpp
WebCore/bindings/v8/custom/V8SharedWorkerCustom.cpp
WebCore/bindings/v8/custom/V8WorkerCustom.cpp
WebCore/bindings/v8/custom/V8XMLHttpRequestConstructor.cpp
WebCore/bindings/v8/custom/V8XMLHttpRequestCustom.cpp

index 0c7d554..0858ab1 100644 (file)
@@ -1,3 +1,31 @@
+2009-09-04  Jian Li  <jianli@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        [V8] Run-time exception in onmessage handler is not forwarded to the worker object.
+        https://bugs.webkit.org/show_bug.cgi?id=28980
+
+        Tested by worker-close.html.
+
+        * bindings/v8/ScriptFunctionCall.cpp:
+        * bindings/v8/V8AbstractEventListener.cpp:
+        (WebCore::V8AbstractEventListener::invokeEventHandler):
+        * bindings/v8/V8Utilities.cpp:
+        (WebCore::getScriptExecutionContext):
+        (WebCore::reportException):
+        * bindings/v8/V8Utilities.h:
+        (WebCore::getScriptExecutionContext):
+        * bindings/v8/custom/V8MessageChannelConstructor.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8SharedWorkerCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8WorkerCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8XMLHttpRequestConstructor.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * bindings/v8/custom/V8XMLHttpRequestCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+
 2009-09-04  Dave Hyatt  <hyatt@apple.com>
 
         Reviewed by Anders Carlsson.
index 2fa43d5..9ff6b8c 100644 (file)
@@ -31,8 +31,6 @@
 #include "config.h"
 #include "ScriptFunctionCall.h"
 
-#include "Document.h"
-#include "Frame.h"
 #include "ScriptScope.h"
 #include "ScriptState.h"
 #include "ScriptString.h"
 
 #include "V8Binding.h"
 #include "V8Proxy.h"
+#include "V8Utilities.h"
 
 #include <v8.h>
 #include <wtf/OwnArrayPtr.h>
 
 namespace WebCore {
 
-static void reportException(ScriptState* scriptState, v8::TryCatch &exceptionCatcher)
-{
-    v8::Local<v8::Message> message = exceptionCatcher.Message();
-    scriptState->frame()->document()->reportException(toWebCoreString(message->Get()), message->GetLineNumber(), toWebCoreString(message->GetScriptResourceName()));
-    exceptionCatcher.Reset();
-}
-
 ScriptFunctionCall::ScriptFunctionCall(ScriptState* scriptState, const ScriptObject& thisObject, const String& name)
     : m_scriptState(scriptState)
     , m_thisObject(thisObject)
index 2c55b0f..f65f999 100644 (file)
@@ -36,6 +36,7 @@
 #include "Frame.h"
 #include "Tokenizer.h"
 #include "V8Binding.h"
+#include "V8Utilities.h"
 
 namespace WebCore {
 
@@ -81,10 +82,17 @@ void V8AbstractEventListener::invokeEventHandler(v8::Handle<v8::Context> v8Conte
         tryCatch.Reset();
 
         // Call the event handler.
+        tryCatch.SetVerbose(false);   // We do not want to report the exception to the inspector console.
         returnValue = callListenerFunction(jsEvent, event, isWindowEvent);
-        tryCatch.Reset();
+
+        // If an error occurs while handling the event, it should be reported.
+        if (tryCatch.HasCaught()) {
+            reportException(0, tryCatch);
+            tryCatch.Reset();
+        }
 
         // Restore the old event. This must be done for all exit paths through this method.
+        tryCatch.SetVerbose(true);
         if (savedEvent.IsEmpty())
             v8Context->Global()->SetHiddenValue(eventSymbol, v8::Undefined());
         else
index f20add8..a8aa924 100644 (file)
 
 #include <v8.h>
 
+#include "Document.h"
+#include "Frame.h"
+#include "ScriptExecutionContext.h"
+#include "ScriptState.h"
 #include "V8CustomBinding.h"
+#include "V8Binding.h"
 #include "V8Proxy.h"
+#include "WorkerContext.h"
+#include "WorkerContextExecutionProxy.h"
 
 #include <wtf/Assertions.h>
 #include "Frame.h"
@@ -101,4 +108,30 @@ void navigateIfAllowed(Frame* frame, const KURL& url, bool lockHistory, bool loc
         frame->loader()->scheduleLocationChange(url.string(), callingFrame->loader()->outgoingReferrer(), lockHistory, lockBackForwardList, processingUserGesture());
 }
 
+ScriptExecutionContext* getScriptExecutionContext(ScriptState* scriptState)
+{
+#if ENABLE(WORKERS)
+    WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
+    if (proxy)
+        return proxy->workerContext()->scriptExecutionContext();
+#endif
+
+    if (scriptState)
+        return scriptState->frame()->document()->scriptExecutionContext();
+    else {
+        Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
+        if (frame)
+            return frame->document()->scriptExecutionContext();
+    }
+
+    return 0;
+}
+
+void reportException(ScriptState* scriptState, v8::TryCatch& exceptionCatcher)
+{
+    v8::Local<v8::Message> message = exceptionCatcher.Message();
+    getScriptExecutionContext(scriptState)->reportException(toWebCoreString(message->Get()), message->GetLineNumber(), toWebCoreString(message->GetScriptResourceName()));
+    exceptionCatcher.Reset();
+}
+
 } // namespace WebCore
index 2e48c4c..36dce24 100644 (file)
@@ -37,6 +37,8 @@ namespace WebCore {
 
     class Frame;
     class KURL;
+    class ScriptExecutionContext;
+    class ScriptState;
     class String;
 
     // Use an array to hold dependents. It works like a ref-counted scheme. A value can be added more than once to the DOM object.
@@ -48,6 +50,13 @@ namespace WebCore {
     KURL completeURL(const String& relativeURL);
     void navigateIfAllowed(Frame*, const KURL&, bool lockHistory, bool lockBackForwardList);
 
+    ScriptExecutionContext* getScriptExecutionContext(ScriptState*);
+    inline ScriptExecutionContext* getScriptExecutionContext() {
+        return getScriptExecutionContext(0);
+    }
+
+    void reportException(ScriptState*, v8::TryCatch&);
+
     class AllowAllocation {
     public:
         inline AllowAllocation()
index f45aecf..ca02b16 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "Document.h"
 #include "Frame.h"
+#include "V8Utilities.h"
 #include "WorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
 
@@ -52,16 +53,9 @@ CALLBACK_FUNC_DECL(MessageChannelConstructor)
         return throwError("DOM object constructor cannot be called as a function.");
 
     // Get the ScriptExecutionContext (WorkerContext or Document)
-    ScriptExecutionContext* context = 0;
-    WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
-    if (proxy)
-        context = proxy->workerContext();
-    else {
-        Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
-        if (!frame)
-            return v8::Undefined();
-        context = frame->document();
-    }
+    ScriptExecutionContext* context = getScriptExecutionContext();
+    if (!context)
+        return v8::Undefined();
 
     // Note: it's OK to let this RefPtr go out of scope because we also call
     // SetDOMWrapper(), which effectively holds a reference to obj.
index 3ab2f8e..755977c 100644 (file)
@@ -66,16 +66,9 @@ CALLBACK_FUNC_DECL(SharedWorkerConstructor)
         return v8::Undefined();
 
     // Get the script execution context.
-    ScriptExecutionContext* context = 0;
-    WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
-    if (proxy)
-        context = proxy->workerContext();
-    else {
-        Frame* frame = V8Proxy::retrieveFrame();
-        if (!frame)
-            return v8::Undefined();
-        context = frame->document();
-    }
+    ScriptExecutionContext* context = getScriptExecutionContext();
+    if (!context)
+        return v8::Undefined();
 
     // Create the worker object.
     // Note: it's OK to let this RefPtr go out of scope because we also call SetDOMWrapper(), which effectively holds a reference to obj.
index acfcacb..1cecde0 100644 (file)
@@ -66,16 +66,9 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
         return v8::Undefined();
 
     // Get the script execution context.
-    ScriptExecutionContext* context = 0;
-    WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
-    if (proxy)
-        context = proxy->workerContext();
-    else {
-        Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
-        if (!frame)
-            return v8::Undefined();
-        context = frame->document();
-    }
+    ScriptExecutionContext* context = getScriptExecutionContext();
+    if (!context)
+        return v8::Undefined();
 
     // Create the worker object.
     // Note: it's OK to let this RefPtr go out of scope because we also call setDOMWrapper(), which effectively holds a reference to obj.
index 02ce8e2..62e923f 100644 (file)
@@ -35,6 +35,7 @@
 #include "V8CustomBinding.h"
 #include "V8ObjectEventListener.h"
 #include "V8Proxy.h"
+#include "V8Utilities.h"
 #include "XMLHttpRequest.h"
 #include "WorkerContext.h"
 #include "WorkerContextExecutionProxy.h"
@@ -50,20 +51,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestConstructor)
 
     // Expect no parameters.
     // Allocate a XMLHttpRequest object as its internal field.
-    ScriptExecutionContext* context = 0;
-#if ENABLE(WORKERS)
-    WorkerContextExecutionProxy* proxy = WorkerContextExecutionProxy::retrieve();
-    if (proxy)
-        context = proxy->workerContext();
-    else {
-#endif
-        Frame* frame = V8Proxy::retrieveFrameForCurrentContext();
-        if (!frame)
-            return throwError("XMLHttpRequest constructor's associated frame is not available", V8Proxy::ReferenceError);
-        context = frame->document();
-#if ENABLE(WORKERS)
-    }
-#endif
+    ScriptExecutionContext* context = getScriptExecutionContext();
+    if (!context)
+        return throwError("XMLHttpRequest constructor's associated context is not available", V8Proxy::ReferenceError);
     RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context);
     V8DOMWrapper::setDOMWrapper(args.Holder(), V8ClassIndex::ToInt(V8ClassIndex::XMLHTTPREQUEST), xmlHttpRequest.get());
 
index 7204a61..b980680 100644 (file)
@@ -323,22 +323,9 @@ CALLBACK_FUNC_DECL(XMLHttpRequestOpen)
 
     String method = toWebCoreString(args[0]);
     String urlstring = toWebCoreString(args[1]);
-    ScriptExecutionContext* context = 0;
-#if ENABLE(WORKERS)
-    WorkerContextExecutionProxy* workerContextProxy = WorkerContextExecutionProxy::retrieve();
-    if (workerContextProxy) {
-        context = workerContextProxy->workerContext();
-        ASSERT(context);
-    }
-#endif
-
-    if (!context) {
-        V8Proxy* proxy = V8Proxy::retrieve();
-        if (!proxy)
-            return v8::Undefined();
-        context = proxy->frame()->document();
-        ASSERT(context);
-    }
+    ScriptExecutionContext* context = getScriptExecutionContext();
+    if (!context)
+        return v8::Undefined();
 
     KURL url = context->completeURL(urlstring);