Index: Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
diff --git a/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp b/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
index 4d16f15927f373513cf6e29af22d4a684abd86a3..66fe19412bdccd215a616a0e825a82c1e9030ea8 100644 |
--- a/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
+++ b/Source/modules/websockets/WorkerThreadableWebSocketChannel.cpp |
@@ -32,11 +32,14 @@ |
#include "modules/websockets/WorkerThreadableWebSocketChannel.h" |
+#include "RuntimeEnabledFeatures.h" |
+#include "bindings/v8/ScriptCallStackFactory.h" |
#include "core/dom/CrossThreadTask.h" |
#include "core/dom/Document.h" |
#include "core/dom/ScriptExecutionContext.h" |
#include "core/fileapi/Blob.h" |
-#include "RuntimeEnabledFeatures.h" |
+#include "core/inspector/ScriptCallFrame.h" |
+#include "core/inspector/ScriptCallStack.h" |
#include "core/workers/WorkerContext.h" |
#include "core/workers/WorkerLoaderProxy.h" |
#include "core/workers/WorkerRunLoop.h" |
@@ -56,8 +59,14 @@ WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerContext |
: m_workerContext(context) |
, m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(context, client)) |
, m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode)) |
+ , m_callFrameAtConnection("", "", 0) |
{ |
- m_bridge->initialize(); |
+ // We assume that we can take the JS callstack at WebSocket connection here. |
+ ScriptCallFrame frame("", "", 0); |
+ RefPtr<ScriptCallStack> callStack = createScriptCallStack(1, true); |
+ if (callStack && callStack->size() > 0) |
+ frame = callStack->at(0); |
+ m_bridge->initialize(frame); |
} |
WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel() |
@@ -68,6 +77,8 @@ WorkerThreadableWebSocketChannel::~WorkerThreadableWebSocketChannel() |
void WorkerThreadableWebSocketChannel::connect(const KURL& url, const String& protocol) |
{ |
+ RefPtr<ScriptCallStack> callstack = createScriptCallStack(1, true); |
+ m_callFrameAtConnection = (callstack && callstack->size() > 0) ? callstack->at(0) : ScriptCallFrame("", "", 0); |
if (m_bridge) |
m_bridge->connect(url, protocol); |
} |
@@ -118,10 +129,24 @@ void WorkerThreadableWebSocketChannel::close(int code, const String& reason) |
m_bridge->close(code, reason); |
} |
-void WorkerThreadableWebSocketChannel::fail(const String& reason) |
+void WorkerThreadableWebSocketChannel::fail(const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> callStack) |
{ |
if (m_bridge) |
- m_bridge->fail(reason); |
+ m_bridge->fail(reason, level, callStack); |
+} |
+ |
+void WorkerThreadableWebSocketChannel::fail(const String& reason, MessageLevel level) |
+{ |
+ RefPtr<ScriptCallStack> callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); |
+ if (!callStack || !callStack->size()) { |
+ Vector<ScriptCallFrame> frames; |
+ frames.append(m_callFrameAtConnection); |
+ callStack = ScriptCallStack::create(frames); |
+ } |
+ Vector<ScriptCallFrame> frames; |
+ for (size_t i = 0; i < callStack->size(); ++i) |
+ frames.append(callStack->at(i)); |
+ fail(reason, level, adoptPtr<CallStackWrapper>(callStack ? new CallStackWrapper(frames) : 0)); |
} |
void WorkerThreadableWebSocketChannel::disconnect() |
@@ -144,7 +169,7 @@ void WorkerThreadableWebSocketChannel::resume() |
m_bridge->resume(); |
} |
-WorkerThreadableWebSocketChannel::Peer::Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode) |
+WorkerThreadableWebSocketChannel::Peer::Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const ScriptCallFrame& frame) |
: m_workerClientWrapper(clientWrapper) |
, m_loaderProxy(loaderProxy) |
, m_mainWebSocketChannel(0) |
@@ -152,9 +177,9 @@ WorkerThreadableWebSocketChannel::Peer::Peer(PassRefPtr<ThreadableWebSocketChann |
{ |
if (RuntimeEnabledFeatures::experimentalWebSocketEnabled()) { |
// FIXME: Create an "experimental" WebSocketChannel instead of a MainThreadWebSocketChannel. |
- m_mainWebSocketChannel = MainThreadWebSocketChannel::create(toDocument(context), this); |
+ m_mainWebSocketChannel = MainThreadWebSocketChannel::create(toDocument(context), this, frame); |
} else |
- m_mainWebSocketChannel = MainThreadWebSocketChannel::create(toDocument(context), this); |
+ m_mainWebSocketChannel = MainThreadWebSocketChannel::create(toDocument(context), this, frame); |
ASSERT(isMainThread()); |
} |
@@ -229,12 +254,12 @@ void WorkerThreadableWebSocketChannel::Peer::close(int code, const String& reaso |
m_mainWebSocketChannel->close(code, reason); |
} |
-void WorkerThreadableWebSocketChannel::Peer::fail(const String& reason) |
+void WorkerThreadableWebSocketChannel::Peer::fail(const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> callStack) |
{ |
ASSERT(isMainThread()); |
if (!m_mainWebSocketChannel) |
return; |
- m_mainWebSocketChannel->fail(reason); |
+ m_mainWebSocketChannel->fail(reason, level, callStack); |
} |
void WorkerThreadableWebSocketChannel::Peer::disconnect() |
@@ -366,9 +391,7 @@ WorkerThreadableWebSocketChannel::Bridge::~Bridge() |
class WorkerThreadableWebSocketChannel::WorkerContextDidInitializeTask : public ScriptExecutionContext::Task { |
public: |
- static PassOwnPtr<ScriptExecutionContext::Task> create(WorkerThreadableWebSocketChannel::Peer* peer, |
- WorkerLoaderProxy* loaderProxy, |
- PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
+ static PassOwnPtr<ScriptExecutionContext::Task> create(WorkerThreadableWebSocketChannel::Peer* peer, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
{ |
return adoptPtr(new WorkerContextDidInitializeTask(peer, loaderProxy, workerClientWrapper)); |
} |
@@ -388,9 +411,7 @@ public: |
virtual bool isCleanupTask() const OVERRIDE { return true; } |
private: |
- WorkerContextDidInitializeTask(WorkerThreadableWebSocketChannel::Peer* peer, |
- WorkerLoaderProxy* loaderProxy, |
- PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
+ WorkerContextDidInitializeTask(WorkerThreadableWebSocketChannel::Peer* peer, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper) |
: m_peer(peer) |
, m_loaderProxy(loaderProxy) |
, m_workerClientWrapper(workerClientWrapper) |
@@ -402,14 +423,14 @@ private: |
RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper; |
}; |
-void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecutionContext* context, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode) |
+void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecutionContext* context, WorkerLoaderProxy* loaderProxy, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode, const String& sourceURL, unsigned lineNumber) |
{ |
ASSERT(isMainThread()); |
ASSERT_UNUSED(context, context->isDocument()); |
RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper; |
- Peer* peer = Peer::create(clientWrapper, *loaderProxy, context, taskMode); |
+ Peer* peer = Peer::create(clientWrapper, *loaderProxy, context, taskMode, ScriptCallFrame("", sourceURL, lineNumber)); |
bool sent = loaderProxy->postTaskForModeToWorkerContext( |
WorkerThreadableWebSocketChannel::WorkerContextDidInitializeTask::create(peer, loaderProxy, clientWrapper), taskMode); |
if (!sent) { |
@@ -418,14 +439,13 @@ void WorkerThreadableWebSocketChannel::Bridge::mainThreadInitialize(ScriptExecut |
} |
} |
-void WorkerThreadableWebSocketChannel::Bridge::initialize() |
+void WorkerThreadableWebSocketChannel::Bridge::initialize(const ScriptCallFrame& frame) |
{ |
ASSERT(!m_peer); |
setMethodNotCompleted(); |
RefPtr<Bridge> protect(this); |
m_loaderProxy.postTaskToLoader( |
- createCallbackTask(&Bridge::mainThreadInitialize, |
- AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode)); |
+ createCallbackTask(&Bridge::mainThreadInitialize, AllowCrossThreadAccess(&m_loaderProxy), m_workerClientWrapper, m_taskMode, frame.sourceURL(), frame.lineNumber())); |
waitForMethodCompletion(); |
// m_peer may be null when the nested runloop exited before a peer has created. |
m_peer = m_workerClientWrapper->peer(); |
@@ -564,20 +584,20 @@ void WorkerThreadableWebSocketChannel::Bridge::close(int code, const String& rea |
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadClose, AllowCrossThreadAccess(m_peer), code, reason)); |
} |
-void WorkerThreadableWebSocketChannel::mainThreadFail(ScriptExecutionContext* context, Peer* peer, const String& reason) |
+void WorkerThreadableWebSocketChannel::mainThreadFail(ScriptExecutionContext* context, Peer* peer, const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> callStack) |
{ |
ASSERT(isMainThread()); |
ASSERT_UNUSED(context, context->isDocument()); |
ASSERT(peer); |
- peer->fail(reason); |
+ peer->fail(reason, level, callStack); |
} |
-void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason) |
+void WorkerThreadableWebSocketChannel::Bridge::fail(const String& reason, MessageLevel level, PassOwnPtr<CallStackWrapper> callStack) |
{ |
if (!m_peer) |
return; |
- m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadFail, AllowCrossThreadAccess(m_peer), reason)); |
+ m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadFail, AllowCrossThreadAccess(m_peer), reason, level, callStack)); |
} |
void WorkerThreadableWebSocketChannel::mainThreadDestroy(ScriptExecutionContext* context, PassOwnPtr<Peer> peer) |