| Index: Source/core/inspector/InspectorDebuggerAgent.cpp
|
| diff --git a/Source/core/inspector/InspectorDebuggerAgent.cpp b/Source/core/inspector/InspectorDebuggerAgent.cpp
|
| index b95de81a82054a004a522b05426118e6e4caac5d..6689936dd467661c45ba5d59791d7d16a6a4e366 100644
|
| --- a/Source/core/inspector/InspectorDebuggerAgent.cpp
|
| +++ b/Source/core/inspector/InspectorDebuggerAgent.cpp
|
| @@ -47,6 +47,7 @@
|
| #include "core/inspector/ScriptCallFrame.h"
|
| #include "core/inspector/ScriptCallStack.h"
|
| #include "platform/JSONValues.h"
|
| +#include "wtf/Vector.h"
|
| #include "wtf/text/WTFString.h"
|
|
|
| using WebCore::TypeBuilder::Array;
|
| @@ -1034,10 +1035,57 @@ void InspectorDebuggerAgent::scriptExecutionBlockedByCSP(const String& directive
|
| }
|
| }
|
|
|
| +double lookupTimestamp(PassRefPtr<CallFrame> frame)
|
| +{
|
| + double timestamp = 0;
|
| + bool ALLOW_UNUSED hasTimestamp = frame->asObject()->getNumber("timestamp", ×tamp);
|
| + ASSERT(hasTimestamp);
|
| + return timestamp;
|
| +}
|
| +
|
| +static inline bool compareCallFrameTimestamps(PassRefPtr<CallFrame> frame1, PassRefPtr<CallFrame> frame2)
|
| +{
|
| + return lookupTimestamp(frame1) > lookupTimestamp(frame2);
|
| +}
|
| +
|
| +void addFramesToVector(PassRefPtr<Array<CallFrame> > trace, Vector<RefPtr<CallFrame> > & v)
|
| +{
|
| + RefPtr<JSONArray> traceArray = trace->asArray();
|
| + for (JSONArray::iterator it = traceArray->begin(); it != traceArray->end(); ++it) {
|
| + v.append(CallFrame::runtimeCast(*it));
|
| + }
|
| +}
|
| +
|
| +PassRefPtr<Array<CallFrame> > mergeStackTraces(PassRefPtr<Array<CallFrame> > trace1, PassRefPtr<Array<CallFrame> > trace2)
|
| +{
|
| + Vector<RefPtr<CallFrame> > mergedFrames;
|
| + addFramesToVector(trace1, mergedFrames);
|
| + addFramesToVector(trace2, mergedFrames);
|
| + std::stable_sort(mergedFrames.begin(), mergedFrames.end(), compareCallFrameTimestamps);
|
| +
|
| + RefPtr<Array<CallFrame> > ret = Array<CallFrame>::create();
|
| + for (size_t i = 0; i < mergedFrames.size(); ++i)
|
| + ret->addItem(mergedFrames[i]);
|
| + return ret;
|
| +}
|
| +
|
| PassRefPtr<Array<CallFrame> > InspectorDebuggerAgent::currentCallFrames()
|
| {
|
| if (!m_pausedScriptState || m_currentCallStack.isNull())
|
| return Array<TypeBuilder::Debugger::CallFrame>::create();
|
| + if (m_currentCallStack.isMixedLanguageStackTrace()) {
|
| + return mergeStackTraces(
|
| + m_injectedScriptManager->injectedScriptFor(m_currentCallStack.dartScriptState()).wrapCallFrames(m_currentCallStack, 0),
|
| + // FIXMEDART: passing in -1 as hack to force AsyncStack mode
|
| + // evaluation as V8 cannot handle regular evaluation of a call
|
| + // frame if not stopped at a v8 breakpoint due to an assert
|
| + // in the V8 code base that should probably be removed.
|
| + // Async call frame evaluation works almost as well as regular
|
| + // call frame evaluation with the only difference being that
|
| + // local variable modifications have no impact.
|
| + m_injectedScriptManager->injectedScriptFor(m_currentCallStack.v8ScriptState()).wrapCallFrames(m_currentCallStack, m_pausedScriptState->isJavaScript() ? 0 : -1));
|
| + }
|
| +
|
| InjectedScript& injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState.get());
|
| if (injectedScript.isEmpty()) {
|
| ASSERT_NOT_REACHED();
|
| @@ -1147,8 +1195,9 @@ void InspectorDebuggerAgent::failedToParseSource(const String& url, const String
|
| m_frontend->scriptFailedToParse(url, data, firstLine, errorLine, errorMessage);
|
| }
|
|
|
| -ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const StackTrace& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
|
| +ScriptDebugListener::SkipPauseRequest InspectorDebuggerAgent::didPause(ScriptState* scriptState, const ScriptValue& exception, const Vector<String>& hitBreakpoints)
|
| {
|
| + const StackTrace& callFrames = scriptDebugServer().currentCallFrames();
|
| ScriptDebugListener::SkipPauseRequest result;
|
| if (m_javaScriptPauseScheduled)
|
| result = ScriptDebugListener::NoSkip; // Don't skip explicit pause requests from front-end.
|
|
|