1f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Copyright 2015 the V8 project authors. All rights reserved. 2f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// found in the LICENSE file. 4f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 5f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-debugger-agent-impl.h" 6f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 7f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include <algorithm> 8f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/debug/debug-interface.h" 10f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/injected-script.h" 11f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/inspected-context.h" 12f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/java-script-call-frame.h" 13f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/protocol/Protocol.h" 14f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/remote-object-id.h" 15f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/script-breakpoint.h" 16f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/search-util.h" 17f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/string-util.h" 18f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-debugger-script.h" 19f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-debugger.h" 20f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-inspector-impl.h" 21f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-inspector-session-impl.h" 22f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-regex.h" 23f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-runtime-agent-impl.h" 24f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/inspector/v8-stack-trace-impl.h" 25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/inspector/v8-value-copier.h" 26f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 27f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "include/v8-inspector.h" 28f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 29f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace v8_inspector { 30f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 31f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Array; 32f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Maybe; 33f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Debugger::BreakpointId; 34f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Debugger::CallFrame; 35f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Runtime::ExceptionDetails; 36f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Runtime::ScriptId; 37f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Runtime::StackTrace; 38f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochusing protocol::Runtime::RemoteObject; 39f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 40f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochnamespace DebuggerAgentState { 41f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char javaScriptBreakpoints[] = "javaScriptBreakopints"; 42f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char pauseOnExceptionsState[] = "pauseOnExceptionsState"; 43f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char asyncCallStackDepth[] = "asyncCallStackDepth"; 44f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char blackboxPattern[] = "blackboxPattern"; 45f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char debuggerEnabled[] = "debuggerEnabled"; 46f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 47f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Breakpoint properties. 48f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char url[] = "url"; 49f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char isRegex[] = "isRegex"; 50f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char lineNumber[] = "lineNumber"; 51f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char columnNumber[] = "columnNumber"; 52f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char condition[] = "condition"; 53f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic const char skipAllPauses[] = "skipAllPauses"; 54f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 55f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} // namespace DebuggerAgentState 56f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 57c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic const char kBacktraceObjectGroup[] = "backtrace"; 58c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic const char kDebuggerNotEnabled[] = "Debugger agent is not enabled"; 59c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic const char kDebuggerNotPaused[] = 60c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Can only perform operation while paused."; 61f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 6262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochnamespace { 6362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 6462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid TranslateWasmStackTraceLocations(Array<CallFrame>* stackTrace, 6562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch WasmTranslation* wasmTranslation) { 6662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0, e = stackTrace->length(); i != e; ++i) { 6762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protocol::Debugger::Location* location = stackTrace->get(i)->getLocation(); 6862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 scriptId = location->getScriptId(); 6962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int lineNumber = location->getLineNumber(); 7062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int columnNumber = location->getColumnNumber(-1); 7162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 7262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( 7362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &scriptId, &lineNumber, &columnNumber)) { 7462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch continue; 7562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 7662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 7762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->setScriptId(std::move(scriptId)); 7862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->setLineNumber(lineNumber); 7962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->setColumnNumber(columnNumber); 8062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 8162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 8262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 8362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochString16 breakpointIdSuffix(V8DebuggerAgentImpl::BreakpointSource source) { 84f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch switch (source) { 85f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case V8DebuggerAgentImpl::UserBreakpointSource: 86f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch break; 87f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case V8DebuggerAgentImpl::DebugCommandBreakpointSource: 88f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ":debug"; 89f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch case V8DebuggerAgentImpl::MonitorCommandBreakpointSource: 90f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return ":monitor"; 91f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 92f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return String16(); 93f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 94f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 9562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen MurdochString16 generateBreakpointId(const ScriptBreakpoint& breakpoint, 9662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V8DebuggerAgentImpl::BreakpointSource source) { 97c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch String16Builder builder; 9862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch builder.append(breakpoint.script_id); 99c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.append(':'); 10062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch builder.appendNumber(breakpoint.line_number); 101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.append(':'); 10262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch builder.appendNumber(breakpoint.column_number); 103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch builder.append(breakpointIdSuffix(source)); 104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return builder.toString(); 105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 10762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool positionComparator(const std::pair<int, int>& a, 10862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const std::pair<int, int>& b) { 109f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (a.first != b.first) return a.first < b.first; 110f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return a.second < b.second; 111f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 11362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochstd::unique_ptr<protocol::Debugger::Location> buildProtocolLocation( 114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& scriptId, int lineNumber, int columnNumber) { 115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return protocol::Debugger::Location::create() 116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch .setScriptId(scriptId) 117f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch .setLineNumber(lineNumber) 118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch .setColumnNumber(columnNumber) 119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch .build(); 120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 12262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} // namespace 12362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8DebuggerAgentImpl::V8DebuggerAgentImpl( 125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel, 126f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue* state) 127f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : m_inspector(session->inspector()), 128f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger(m_inspector->debugger()), 129f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_session(session), 130f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_enabled(false), 131f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state(state), 132f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_frontend(frontendChannel), 133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_isolate(m_inspector->isolate()), 134f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep(NoStep), 135f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_javaScriptPauseScheduled(false), 13662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_recursionLevelForStepOut(0) { 137f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 138f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 139f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8DebuggerAgentImpl::~V8DebuggerAgentImpl() {} 140f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 141c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid V8DebuggerAgentImpl::enableImpl() { 142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_enabled = true; 143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true); 144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->enable(); 145f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 146f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts; 147f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->getCompiledScripts(m_session->contextGroupId(), compiledScripts); 148f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < compiledScripts.size(); i++) 149f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch didParseSource(std::move(compiledScripts[i]), true); 150f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 151f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // FIXME(WK44513): breakpoints activated flag should be synchronized between 152f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // all front-ends 153f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setBreakpointsActivated(true); 154f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 155f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochbool V8DebuggerAgentImpl::enabled() { return m_enabled; } 157f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 158c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::enable() { 159c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (enabled()) return Response::OK(); 160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 161c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) 162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Script execution is prohibited"); 163f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 164c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch enableImpl(); 165c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 168c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::disable() { 169c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::OK(); 170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 171f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, 172f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue::create()); 173f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, 17462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::NoBreakOnException); 175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0); 176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 17762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (isPaused()) m_debugger->continueProgram(); 178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->disable(); 179f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JavaScriptCallFrames emptyCallFrames; 180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames.swap(emptyCallFrames); 181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxedPositions.clear(); 18262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_blackboxPattern.reset(); 18362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resetBlackboxedStateCache(); 18462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_scripts.clear(); 185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.clear(); 186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setAsyncCallStackDepth(this, 0); 187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_continueToLocationBreakpointId = String16(); 188f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch clearBreakDetails(); 189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_javaScriptPauseScheduled = false; 191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_skipAllPauses = false; 19262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_state->setBoolean(DebuggerAgentState::skipAllPauses, false); 193f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->remove(DebuggerAgentState::blackboxPattern); 194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_enabled = false; 195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false); 196c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::restore() { 200f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(!m_enabled); 201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false)) 202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) 204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 206c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch enableImpl(); 207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 20862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int pauseState = v8::debug::NoBreakOnException; 209f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState); 210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch setPauseOnExceptionsImpl(pauseState); 211f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_skipAllPauses = 213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false); 214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int asyncCallStackDepth = 0; 216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->getInteger(DebuggerAgentState::asyncCallStackDepth, 217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch &asyncCallStackDepth); 218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth); 219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 blackboxPattern; 221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_state->getString(DebuggerAgentState::blackboxPattern, 222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch &blackboxPattern)) { 223c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch setBlackboxPattern(blackboxPattern); 224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 226f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 227c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBreakpointsActive(bool active) { 228c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setBreakpointsActivated(active); 230c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 233c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setSkipAllPauses(bool skip) { 23462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip); 235f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_skipAllPauses = skip; 236c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 237f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic std::unique_ptr<protocol::DictionaryValue> 240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochbuildObjectForBreakpointCookie(const String16& url, int lineNumber, 241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int columnNumber, const String16& condition, 242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool isRegex) { 243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> breakpointObject = 244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue::create(); 245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->setString(DebuggerAgentState::url, url); 246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->setInteger(DebuggerAgentState::lineNumber, lineNumber); 247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->setInteger(DebuggerAgentState::columnNumber, columnNumber); 248f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->setString(DebuggerAgentState::condition, condition); 249f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->setBoolean(DebuggerAgentState::isRegex, isRegex); 250f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return breakpointObject; 251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstatic bool matches(V8InspectorImpl* inspector, const String16& url, 254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& pattern, bool isRegex) { 255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (isRegex) { 256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch V8Regex regex(inspector, pattern, true); 257f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return regex.match(url) != -1; 258f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 259f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return url == pattern; 260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 262c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBreakpointByUrl( 263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int lineNumber, Maybe<String16> optionalURL, 264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<String16> optionalURLRegex, Maybe<int> optionalColumnNumber, 265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<String16> optionalCondition, String16* outBreakpointId, 266f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { 267f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *locations = Array<protocol::Debugger::Location>::create(); 268c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (optionalURL.isJust() == optionalURLRegex.isJust()) 269c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Either url or urlRegex must be specified."); 270f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 271f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 url = optionalURL.isJust() ? optionalURL.fromJust() 272f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : optionalURLRegex.fromJust(); 273f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int columnNumber = 0; 274f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (optionalColumnNumber.isJust()) { 275f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch columnNumber = optionalColumnNumber.fromJust(); 276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (columnNumber < 0) return Response::Error("Incorrect column number"); 277f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 278f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 condition = optionalCondition.fromMaybe(""); 279f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool isRegex = optionalURLRegex.isJust(); 280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 breakpointId = (isRegex ? "/" + url + "/" : url) + ":" + 282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16::fromInteger(lineNumber) + ":" + 283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16::fromInteger(columnNumber); 284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue* breakpointsCookie = 285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!breakpointsCookie) { 287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> newValue = 288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue::create(); 289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointsCookie = newValue.get(); 290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setObject(DebuggerAgentState::javaScriptBreakpoints, 291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::move(newValue)); 292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (breakpointsCookie->get(breakpointId)) 294c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Breakpoint at specified location already exists."); 295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointsCookie->setObject( 297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointId, buildObjectForBreakpointCookie( 298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch url, lineNumber, columnNumber, condition, isRegex)); 299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 30062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint breakpoint(String16(), lineNumber, columnNumber, condition); 301f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (const auto& script : m_scripts) { 302f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!matches(m_inspector, script.second->sourceURL(), url, isRegex)) 303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch continue; 30462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakpoint.script_id = script.first; 30562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::Debugger::Location> location = 30662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); 307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (location) (*locations)->addItem(std::move(location)); 308f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *outBreakpointId = breakpointId; 311c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 313f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 314c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBreakpoint( 315f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Debugger::Location> location, 316c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<String16> optionalCondition, String16* outBreakpointId, 317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Debugger::Location>* actualLocation) { 31862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint breakpoint( 31962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->getScriptId(), location->getLineNumber(), 32062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->getColumnNumber(0), optionalCondition.fromMaybe(String16())); 321f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 32262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 breakpointId = 32362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch generateBreakpointId(breakpoint, UserBreakpointSource); 324f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) != 325f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.end()) { 326c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Breakpoint at specified location already exists."); 327f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 32862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch *actualLocation = 32962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolveBreakpoint(breakpointId, breakpoint, UserBreakpointSource); 330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!*actualLocation) return Response::Error("Could not resolve breakpoint"); 331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch *outBreakpointId = breakpointId; 332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 333f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 334f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) { 336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue* breakpointsCookie = 338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (breakpointsCookie) breakpointsCookie->remove(breakpointId); 340c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch removeBreakpointImpl(breakpointId); 341c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 344c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid V8DebuggerAgentImpl::removeBreakpointImpl(const String16& breakpointId) { 345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(enabled()); 346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BreakpointIdToDebuggerBreakpointIdsMap::iterator 347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch debuggerBreakpointIdsIterator = 348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.find(breakpointId); 349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (debuggerBreakpointIdsIterator == 350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.end()) 351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const std::vector<String16>& ids = debuggerBreakpointIdsIterator->second; 353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < ids.size(); ++i) { 354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& debuggerBreakpointId = ids[i]; 355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->removeBreakpoint(debuggerBreakpointId); 357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_serverBreakpoints.erase(debuggerBreakpointId); 358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId); 360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 362c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::getPossibleBreakpoints( 363c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<protocol::Debugger::Location> start, 364c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<protocol::Debugger::Location> end, 365c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) { 366c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch String16 scriptId = start->getScriptId(); 367c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 368c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (start->getLineNumber() < 0 || start->getColumnNumber(0) < 0) 369c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error( 370c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "start.lineNumber and start.columnNumber should be >= 0"); 371c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 37262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::Location v8Start(start->getLineNumber(), 37362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch start->getColumnNumber(0)); 37462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::Location v8End; 375c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (end.isJust()) { 376c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (end.fromJust()->getScriptId() != scriptId) 377c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Locations should contain the same scriptId"); 378c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int line = end.fromJust()->getLineNumber(); 379c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int column = end.fromJust()->getColumnNumber(0); 380c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (line < 0 || column < 0) 381c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error( 382c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "end.lineNumber and end.columnNumber should be >= 0"); 38362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8End = v8::debug::Location(line, column); 384c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 385c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch auto it = m_scripts.find(scriptId); 386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (it == m_scripts.end()) return Response::Error("Script not found"); 387c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 38862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::vector<v8::debug::Location> v8Locations; 389c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!it->second->getPossibleBreakpoints(v8Start, v8End, &v8Locations)) 390c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 391c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 392c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch *locations = protocol::Array<protocol::Debugger::Location>::create(); 393c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch for (size_t i = 0; i < v8Locations.size(); ++i) { 394c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch (*locations) 395c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->addItem(protocol::Debugger::Location::create() 396c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .setScriptId(scriptId) 397c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .setLineNumber(v8Locations[i].GetLineNumber()) 398c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .setColumnNumber(v8Locations[i].GetColumnNumber()) 399c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .build()); 400c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 401c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 402c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch} 403c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 404c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::continueToLocation( 405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Debugger::Location> location) { 406c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_continueToLocationBreakpointId.isEmpty()) { 408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_continueToLocationBreakpointId = ""; 410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 41262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint breakpoint(location->getScriptId(), 41362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->getLineNumber(), 41462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch location->getColumnNumber(0), String16()); 415f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 416f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_continueToLocationBreakpointId = m_debugger->setBreakpoint( 41762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakpoint, &breakpoint.line_number, &breakpoint.column_number); 41862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(kozyatinskiy): Return actual line and column number. 419c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return resume(); 420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 42262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool V8DebuggerAgentImpl::isFunctionBlackboxed(const String16& scriptId, 42362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::debug::Location& start, 42462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const v8::debug::Location& end) { 42562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptsMap::iterator it = m_scripts.find(scriptId); 426f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (it == m_scripts.end()) { 427f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Unknown scripts are blackboxed. 428f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 430f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_blackboxPattern) { 431f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& scriptSourceURL = it->second->sourceURL(); 432f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!scriptSourceURL.isEmpty() && 433f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxPattern->match(scriptSourceURL) != -1) 434f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return true; 435f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 43662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto itBlackboxedPositions = m_blackboxedPositions.find(scriptId); 437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (itBlackboxedPositions == m_blackboxedPositions.end()) return false; 438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 439f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const std::vector<std::pair<int, int>>& ranges = 440f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch itBlackboxedPositions->second; 44162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto itStartRange = std::lower_bound( 442f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ranges.begin(), ranges.end(), 44362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::make_pair(start.GetLineNumber(), start.GetColumnNumber()), 44462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch positionComparator); 44562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto itEndRange = std::lower_bound( 44662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch itStartRange, ranges.end(), 44762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::make_pair(end.GetLineNumber(), end.GetColumnNumber()), 44862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch positionComparator); 449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Ranges array contains positions in script where blackbox state is changed. 450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is 451f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // blackboxed... 45262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return itStartRange == itEndRange && 45362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::distance(ranges.begin(), itStartRange) % 2; 454f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 455f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 456f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::unique_ptr<protocol::Debugger::Location> 457f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben MurdochV8DebuggerAgentImpl::resolveBreakpoint(const String16& breakpointId, 458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const ScriptBreakpoint& breakpoint, 459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BreakpointSource source) { 46062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::HandleScope handles(m_isolate); 461f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(enabled()); 462f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // FIXME: remove these checks once crbug.com/520702 is resolved. 463f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CHECK(!breakpointId.isEmpty()); 46462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch CHECK(!breakpoint.script_id.isEmpty()); 46562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptsMap::iterator scriptIterator = m_scripts.find(breakpoint.script_id); 466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (scriptIterator == m_scripts.end()) return nullptr; 46762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (breakpoint.line_number < scriptIterator->second->startLine() || 46862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptIterator->second->endLine() < breakpoint.line_number) 469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return nullptr; 470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 47162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Translate from protocol location to v8 location for the debugger. 47262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint translatedBreakpoint = breakpoint; 47362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_debugger->wasmTranslation()->TranslateProtocolLocationToWasmScriptLocation( 47462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &translatedBreakpoint.script_id, &translatedBreakpoint.line_number, 47562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &translatedBreakpoint.column_number); 47662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 477f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int actualLineNumber; 478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int actualColumnNumber; 479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 debuggerBreakpointId = m_debugger->setBreakpoint( 48062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch translatedBreakpoint, &actualLineNumber, &actualColumnNumber); 481f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (debuggerBreakpointId.isEmpty()) return nullptr; 482f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 48362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Translate back from v8 location to protocol location for the return value. 48462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_debugger->wasmTranslation()->TranslateWasmScriptLocationToProtocolLocation( 48562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &translatedBreakpoint.script_id, &actualLineNumber, &actualColumnNumber); 48662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_serverBreakpoints[debuggerBreakpointId] = 488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::make_pair(breakpointId, source); 489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch CHECK(!breakpointId.isEmpty()); 490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back( 492f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch debuggerBreakpointId); 49362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return buildProtocolLocation(translatedBreakpoint.script_id, actualLineNumber, 49462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch actualColumnNumber); 495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 497c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::searchInContent( 498c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& scriptId, const String16& query, 499c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex, 500f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) { 501f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ScriptsMap::iterator it = m_scripts.find(scriptId); 503c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (it == m_scripts.end()) 504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("No script for id: " + scriptId); 505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches = 50762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch searchInTextByLinesImpl(m_session, it->second->source(m_isolate), query, 50862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch optionalCaseSensitive.fromMaybe(false), 509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch optionalIsRegex.fromMaybe(false)); 510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *results = protocol::Array<protocol::Debugger::SearchMatch>::create(); 511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < matches.size(); ++i) 512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch (*results)->addItem(std::move(matches[i])); 513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 516c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setScriptSource( 517c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& scriptId, const String16& newContent, Maybe<bool> dryRun, 518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames, 519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<bool>* stackChanged, Maybe<StackTrace>* asyncStackTrace, 520f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) { 521c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 52362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptsMap::iterator it = m_scripts.find(scriptId); 52462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (it == m_scripts.end()) { 52562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Response::Error("No script with given id found"); 52662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 52762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (it->second->isModule()) { 52862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // TODO(kozyatinskiy): LiveEdit should support ES6 module 52962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Response::Error("Editing module's script is not supported."); 53062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 53162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 532f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 533f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::String> newSource = toV8String(m_isolate, newContent); 534c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool compileError = false; 535c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = m_debugger->setScriptSource( 536c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch scriptId, newSource, dryRun.fromMaybe(false), optOutCompileError, 537c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch &m_pausedCallFrames, stackChanged, &compileError); 538c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess() || compileError) return response; 539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 54062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it->second->setSource(newSource); 541c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<Array<CallFrame>> callFrames; 542c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = currentCallFrames(&callFrames); 543c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *newCallFrames = std::move(callFrames); 545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *asyncStackTrace = currentAsyncStackTrace(); 546c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 547f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 548f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 549c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::restartFrame( 550c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& callFrameId, 551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<Array<CallFrame>>* newCallFrames, 552f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<StackTrace>* asyncStackTrace) { 55362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 554c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 555c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callFrameId); 556c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = scope.initialize(); 557c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 558c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 559c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Could not find call frame with given id"); 560f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 561f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Value> resultValue; 562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Boolean> result; 563f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_pausedCallFrames[scope.frameOrdinal()]->restart().ToLocal( 564f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch &resultValue) || 565f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch scope.tryCatch().HasCaught() || 566f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !resultValue->ToBoolean(scope.context()).ToLocal(&result) || 567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !result->Value()) { 568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 569f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 570f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JavaScriptCallFrames frames = m_debugger->currentCallFrames(); 571f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames.swap(frames); 572f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = currentCallFrames(newCallFrames); 574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 575f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch *asyncStackTrace = currentAsyncStackTrace(); 576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 577f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 578f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::getScriptSource(const String16& scriptId, 580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch String16* scriptSource) { 581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 582f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ScriptsMap::iterator it = m_scripts.find(scriptId); 583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (it == m_scripts.end()) 584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("No script for id: " + scriptId); 585f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 58662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch *scriptSource = it->second->source(m_isolate); 587c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 588f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 59062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8DebuggerAgentImpl::pushBreakDetails( 59162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const String16& breakReason, 59262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::DictionaryValue> breakAuxData) { 59362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_breakReason.push_back(std::make_pair(breakReason, std::move(breakAuxData))); 59462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 59562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 59662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8DebuggerAgentImpl::popBreakDetails() { 59762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_breakReason.empty()) return; 59862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_breakReason.pop_back(); 59962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 60062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 60162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8DebuggerAgentImpl::clearBreakDetails() { 60262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::vector<BreakReason> emptyBreakReason; 60362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_breakReason.swap(emptyBreakReason); 60462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 60562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 606f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::schedulePauseOnNextStatement( 607f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& breakReason, 608f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> data) { 609f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!enabled() || m_scheduledDebuggerStep == StepInto || 61062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_javaScriptPauseScheduled || isPaused() || 611f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !m_debugger->breakpointsActivated()) 612f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 61362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(true); 61462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pushBreakDetails(breakReason, std::move(data)); 615f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 616f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 617f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::schedulePauseOnNextStatementIfSteppingInto() { 618f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DCHECK(enabled()); 619f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_scheduledDebuggerStep != StepInto || m_javaScriptPauseScheduled || 62062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isPaused()) 621f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 622f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setPauseOnNextStatement(true); 623f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 624f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 625f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::cancelPauseOnNextStatement() { 62662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_javaScriptPauseScheduled || isPaused()) return; 62762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch popBreakDetails(); 62862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_breakReason.empty()) m_debugger->setPauseOnNextStatement(false); 629f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 630f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 631c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::pause() { 632c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 63362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_javaScriptPauseScheduled || isPaused()) return Response::OK(); 634f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch clearBreakDetails(); 635f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_javaScriptPauseScheduled = true; 636f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 637f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setPauseOnNextStatement(true); 638c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 639f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 641c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::resume() { 64262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 643f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 644c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m_session->releaseObjectGroup(kBacktraceObjectGroup); 645f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->continueProgram(); 646c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 648f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 649c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::stepOver() { 65062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 651f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // StepOver at function return point should fallback to StepInto. 652f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JavaScriptCallFrame* frame = 653f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch !m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr; 654c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (frame && frame->isAtReturn()) return stepInto(); 655f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = StepOver; 656c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m_session->releaseObjectGroup(kBacktraceObjectGroup); 657f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->stepOverStatement(); 658c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 659f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 661c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::stepInto() { 66262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = StepInto; 664c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m_session->releaseObjectGroup(kBacktraceObjectGroup); 665f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->stepIntoStatement(); 666c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 669c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::stepOut() { 67062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 671f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = StepOut; 672f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_recursionLevelForStepOut = 1; 673c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m_session->releaseObjectGroup(kBacktraceObjectGroup); 674f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->stepOutOfFunction(); 675c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 676f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 677f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 678c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setPauseOnExceptions( 679c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& stringPauseState) { 680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 68162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::ExceptionBreakState pauseState; 682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (stringPauseState == "none") { 68362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pauseState = v8::debug::NoBreakOnException; 684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (stringPauseState == "all") { 68562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pauseState = v8::debug::BreakOnAnyException; 686f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else if (stringPauseState == "uncaught") { 68762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pauseState = v8::debug::BreakOnUncaughtException; 688f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 689c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Unknown pause on exceptions mode: " + 690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch stringPauseState); 691f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 692c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch setPauseOnExceptionsImpl(pauseState); 693c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 696c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) { 697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setPauseOnExceptionsState( 69862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch static_cast<v8::debug::ExceptionBreakState>(pauseState)); 699c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState); 700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 702c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::evaluateOnCallFrame( 703c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& callFrameId, const String16& expression, 704c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI, 705c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview, 70662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Maybe<bool> throwOnSideEffect, std::unique_ptr<RemoteObject>* result, 707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) { 70862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callFrameId); 711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = scope.initialize(); 712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 713c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 714c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Could not find call frame with given id"); 715c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 716c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI(); 717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole(); 718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 719f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::MaybeLocal<v8::Value> maybeResultValue = 720f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames[scope.frameOrdinal()]->evaluate( 72162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch toV8String(m_isolate, expression), 72262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch throwOnSideEffect.fromMaybe(false)); 723f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 724f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Re-initialize after running client's code, as it could have destroyed 725f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // context or session. 726c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = scope.initialize(); 727c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return scope.injectedScript()->wrapEvaluateResult( 729c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), 730c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result, 731c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch exceptionDetails); 732f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 733f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 734c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setVariableValue( 735c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int scopeNumber, const String16& variableName, 736f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument, 737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& callFrameId) { 738c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 73962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return Response::Error(kDebuggerNotPaused); 740c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(), 741c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch callFrameId); 742c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = scope.initialize(); 743c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Value> newValue; 745c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(), 746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch &newValue); 747c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 749c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (scope.frameOrdinal() >= m_pausedCallFrames.size()) 750c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Could not find call frame with given id"); 751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::MaybeLocal<v8::Value> result = 752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames[scope.frameOrdinal()]->setVariableValue( 753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch scopeNumber, toV8String(m_isolate, variableName), newValue); 754c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (scope.tryCatch().HasCaught() || result.IsEmpty()) 755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 756c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 759c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setAsyncCallStackDepth(int depth) { 760c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!enabled()) return Response::Error(kDebuggerNotEnabled); 761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth); 762f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setAsyncCallStackDepth(this, depth); 763c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 764f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 765f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 766c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBlackboxPatterns( 767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Array<String16>> patterns) { 768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!patterns->length()) { 769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxPattern = nullptr; 77062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resetBlackboxedStateCache(); 771f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->remove(DebuggerAgentState::blackboxPattern); 772c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 773f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 774f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 775f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16Builder patternBuilder; 776f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch patternBuilder.append('('); 777f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < patterns->length() - 1; ++i) { 778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch patternBuilder.append(patterns->get(i)); 779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch patternBuilder.append("|"); 780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch patternBuilder.append(patterns->get(patterns->length() - 1)); 782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch patternBuilder.append(')'); 783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 pattern = patternBuilder.toString(); 784c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = setBlackboxPattern(pattern); 785c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 78662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resetBlackboxedStateCache(); 787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->setString(DebuggerAgentState::blackboxPattern, pattern); 788c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 791c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBlackboxPattern(const String16& pattern) { 792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<V8Regex> regex(new V8Regex( 793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_inspector, pattern, true /** caseSensitive */, false /** multiline */)); 794c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!regex->isValid()) 795c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Pattern parser error: " + regex->errorMessage()); 796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxPattern = std::move(regex); 797c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 798f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 799f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 80062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8DebuggerAgentImpl::resetBlackboxedStateCache() { 80162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (const auto& it : m_scripts) { 80262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it.second->resetBlackboxedStateCache(); 80362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 80462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch} 80562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 806c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::setBlackboxedRanges( 807c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch const String16& scriptId, 808f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>> 809f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch inPositions) { 81062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch auto it = m_scripts.find(scriptId); 81162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (it == m_scripts.end()) 812c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("No script with passed id."); 813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!inPositions->length()) { 815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxedPositions.erase(scriptId); 81662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it->second->resetBlackboxedStateCache(); 817c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 819f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 820f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::vector<std::pair<int, int>> positions; 821f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch positions.reserve(inPositions->length()); 822f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < inPositions->length(); ++i) { 823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::Debugger::ScriptPosition* position = inPositions->get(i); 824c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (position->getLineNumber() < 0) 825c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Position missing 'line' or 'line' < 0."); 826c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (position->getColumnNumber() < 0) 827c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error("Position missing 'column' or 'column' < 0."); 828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch positions.push_back( 829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::make_pair(position->getLineNumber(), position->getColumnNumber())); 830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 831f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 832f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 1; i < positions.size(); ++i) { 833f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (positions[i - 1].first < positions[i].first) continue; 834f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (positions[i - 1].first == positions[i].first && 835f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch positions[i - 1].second < positions[i].second) 836f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch continue; 837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::Error( 838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch "Input positions array is not sorted or contains duplicate values."); 839f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 840f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 841f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxedPositions[scriptId] = positions; 84262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch it->second->resetBlackboxedStateCache(); 843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 844f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 845f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 846f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::willExecuteScript(int scriptId) { 847f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch changeJavaScriptRecursionLevel(+1); 848f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_scheduledDebuggerStep != StepInto) return; 849f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch schedulePauseOnNextStatementIfSteppingInto(); 850f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 851f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 852f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::didExecuteScript() { 853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch changeJavaScriptRecursionLevel(-1); 854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 855f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 856f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::changeJavaScriptRecursionLevel(int step) { 85762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (m_javaScriptPauseScheduled && !m_skipAllPauses && !isPaused()) { 858f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Do not ever loose user's pause request until we have actually paused. 859f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->setPauseOnNextStatement(true); 860f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 861f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (m_scheduledDebuggerStep == StepOut) { 862f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_recursionLevelForStepOut += step; 863f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_recursionLevelForStepOut) { 864f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // When StepOut crosses a task boundary (i.e. js -> c++) from where it was 865f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // requested, 866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // switch stepping to step into a next JS task, as if we exited to a 867f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // blackboxed framework. 868f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = StepInto; 869f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 870f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 871f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 872f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 873c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochResponse V8DebuggerAgentImpl::currentCallFrames( 874c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<Array<CallFrame>>* result) { 87562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) { 876c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch *result = Array<CallFrame>::create(); 877c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 878c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 879f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 880f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Context> debuggerContext = 88162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::debug::GetDebugContext(m_isolate); 882f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Context::Scope contextScope(debuggerContext); 883f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 884f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Array> objects = v8::Array::New(m_isolate); 885f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 886f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t frameOrdinal = 0; frameOrdinal < m_pausedCallFrames.size(); 887f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ++frameOrdinal) { 888f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const std::unique_ptr<JavaScriptCallFrame>& currentCallFrame = 889f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames[frameOrdinal]; 890f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 89162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Object> details; 89262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!currentCallFrame->details().ToLocal(&details)) 89362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch return Response::InternalError(); 894f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 895f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int contextId = currentCallFrame->contextId(); 896c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 897c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InjectedScript* injectedScript = nullptr; 898c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (contextId) m_session->findInjectedScript(contextId, injectedScript); 899f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 900f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 callFrameId = 901f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal)); 902c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!details 903c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Set(debuggerContext, 904c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8StringInternalized(m_isolate, "callFrameId"), 905c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8String(m_isolate, callFrameId)) 906c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 907c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 908c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 909f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 910f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (injectedScript) { 911f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Value> scopeChain; 912c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!details 913c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Get(debuggerContext, 914c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8StringInternalized(m_isolate, "scopeChain")) 915c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .ToLocal(&scopeChain) || 916c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch !scopeChain->IsArray()) { 917c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 918c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 919f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>(); 920c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = injectedScript->wrapPropertyInArray( 921c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch scopeChainArray, toV8StringInternalized(m_isolate, "object"), 922c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kBacktraceObjectGroup); 923c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 924c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = injectedScript->wrapObjectProperty( 925c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch details, toV8StringInternalized(m_isolate, "this"), 926c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kBacktraceObjectGroup); 927c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 928f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (details 929f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ->Has(debuggerContext, 930f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch toV8StringInternalized(m_isolate, "returnValue")) 931f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch .FromMaybe(false)) { 932c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch response = injectedScript->wrapObjectProperty( 933c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch details, toV8StringInternalized(m_isolate, "returnValue"), 934c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch kBacktraceObjectGroup); 935c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } else { 938c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!details 939c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Set(debuggerContext, 940c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8StringInternalized(m_isolate, "scopeChain"), 941c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch v8::Array::New(m_isolate, 0)) 942c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 943c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 944c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 945f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::Local<v8::Object> remoteObject = v8::Object::New(m_isolate); 946c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!remoteObject 947c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Set(debuggerContext, toV8StringInternalized(m_isolate, "type"), 948c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8StringInternalized(m_isolate, "undefined")) 949c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 950c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 951c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 952c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!details 953c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Set(debuggerContext, toV8StringInternalized(m_isolate, "this"), 954c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch remoteObject) 955c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 956c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 957c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 958c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!details 959c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch ->Delete(debuggerContext, 960c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch toV8StringInternalized(m_isolate, "returnValue")) 961c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 962c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 963c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 964f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 965f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 966c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!objects->Set(debuggerContext, static_cast<int>(frameOrdinal), details) 967c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch .FromMaybe(false)) { 968c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::InternalError(); 969c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 972c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<protocol::Value> protocolValue; 973c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = toProtocolValue(debuggerContext, objects, &protocolValue); 974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) return response; 975f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::ErrorSupport errorSupport; 97662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch *result = Array<CallFrame>::fromValue(protocolValue.get(), &errorSupport); 977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!*result) return Response::Error(errorSupport.errors()); 97862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch TranslateWasmStackTraceLocations(result->get(), 97962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_debugger->wasmTranslation()); 980c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return Response::OK(); 981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 982f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochstd::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() { 98462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!isPaused()) return nullptr; 985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch V8StackTraceImpl* stackTrace = m_debugger->currentAsyncCallChain(); 986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return stackTrace ? stackTrace->buildInspectorObjectForTail(m_debugger) 987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : nullptr; 988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 99062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochbool V8DebuggerAgentImpl::isPaused() const { return m_debugger->isPaused(); } 99162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 992f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::didParseSource( 993f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<V8DebuggerScript> script, bool success) { 994f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 99562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 scriptSource = script->source(m_isolate); 996f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!success) script->setSourceURL(findSourceURL(scriptSource, false)); 997f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!success) 998f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch script->setSourceMappingURL(findSourceMapURL(scriptSource, false)); 999f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 100062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int contextId = script->executionContextId(); 100162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch int contextGroupId = m_inspector->contextGroupId(contextId); 100262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch InspectedContext* inspected = 100362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_inspector->getContext(contextGroupId, contextId); 1004f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> executionContextAuxData; 100562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (inspected) { 100662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Script reused between different groups/sessions can have a stale 100762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // execution context id. 1008f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch executionContextAuxData = protocol::DictionaryValue::cast( 100962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protocol::StringUtil::parseJSON(inspected->auxData())); 101062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 1011f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool isLiveEdit = script->isLiveEdit(); 1012f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool hasSourceURL = script->hasSourceURL(); 101362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool isModule = script->isModule(); 1014f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 scriptId = script->scriptId(); 1015f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 scriptURL = script->sourceURL(); 1016f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 101762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_scripts[scriptId] = std::move(script); 101862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 101962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId); 102062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch DCHECK(scriptIterator != m_scripts.end()); 102162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch V8DebuggerScript* scriptRef = scriptIterator->second.get(); 102262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // V8 could create functions for parsed scripts before reporting and asks 102362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // inspector about blackboxed state, we should reset state each time when we 102462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // make any change that change isFunctionBlackboxed output - adding parsed 102562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // script is changing. 102662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptRef->resetBlackboxedStateCache(); 102762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 102862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Maybe<String16> sourceMapURLParam = scriptRef->sourceMappingURL(); 1029c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Maybe<protocol::DictionaryValue> executionContextAuxDataParam( 1030f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::move(executionContextAuxData)); 1031f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr; 1032f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr; 103362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const bool* isModuleParam = isModule ? &isModule : nullptr; 1034f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (success) 1035f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_frontend.scriptParsed( 103662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), 103762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptRef->endLine(), scriptRef->endColumn(), contextId, 103862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), 103962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam, 104062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch isModuleParam); 1041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch else 1042f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_frontend.scriptFailedToParse( 104362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(), 104462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptRef->endLine(), scriptRef->endColumn(), contextId, 104562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch scriptRef->hash(m_isolate), std::move(executionContextAuxDataParam), 104662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam); 1047f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1048f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (scriptURL.isEmpty() || !success) return; 1049f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1050f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue* breakpointsCookie = 1051f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_state->getObject(DebuggerAgentState::javaScriptBreakpoints); 1052f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!breakpointsCookie) return; 1053f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1054f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (size_t i = 0; i < breakpointsCookie->size(); ++i) { 1055f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch auto cookie = breakpointsCookie->at(i); 1056f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue* breakpointObject = 1057f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protocol::DictionaryValue::cast(cookie.second); 1058f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch bool isRegex; 1059f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->getBoolean(DebuggerAgentState::isRegex, &isRegex); 1060f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch String16 url; 1061f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->getString(DebuggerAgentState::url, &url); 1062f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!matches(m_inspector, scriptURL, url, isRegex)) continue; 1063f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ScriptBreakpoint breakpoint; 106462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakpoint.script_id = scriptId; 1065f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->getInteger(DebuggerAgentState::lineNumber, 106662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &breakpoint.line_number); 1067f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->getInteger(DebuggerAgentState::columnNumber, 106862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch &breakpoint.column_number); 1069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointObject->getString(DebuggerAgentState::condition, 1070f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch &breakpoint.condition); 107162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::Debugger::Location> location = 107262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolveBreakpoint(cookie.first, breakpoint, UserBreakpointSource); 1073f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (location) 1074f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_frontend.breakpointResolved(cookie.first, std::move(location)); 1075f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1076f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1077f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 107862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdochvoid V8DebuggerAgentImpl::didPause(int contextId, 107962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch v8::Local<v8::Value> exception, 108062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const std::vector<String16>& hitBreakpoints, 108162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool isPromiseRejection, bool isUncaught, 108262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool isOOMBreak) { 1083f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JavaScriptCallFrames frames = m_debugger->currentCallFrames(); 1084f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames.swap(frames); 1085f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch v8::HandleScope handles(m_isolate); 1086f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 108762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::vector<BreakReason> hitReasons; 108862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 108962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (isOOMBreak) { 109062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hitReasons.push_back( 109162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::make_pair(protocol::Debugger::Paused::ReasonEnum::OOM, nullptr)); 109262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (!exception.IsEmpty()) { 1093c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch InjectedScript* injectedScript = nullptr; 109462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_session->findInjectedScript(contextId, injectedScript); 1095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (injectedScript) { 109662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 breakReason = 1097f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch isPromiseRejection 1098f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection 1099f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch : protocol::Debugger::Paused::ReasonEnum::Exception; 1100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<protocol::Runtime::RemoteObject> obj; 1101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false, 1102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch &obj); 110362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::DictionaryValue> breakAuxData; 1104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (obj) { 110562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData = obj->toValue(); 110662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData->setBoolean("uncaught", isUncaught); 1107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } else { 110862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData = nullptr; 1109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 111062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hitReasons.push_back( 111162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::make_pair(breakReason, std::move(breakAuxData))); 1112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1113f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1114f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1115f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<Array<String16>> hitBreakpointIds = Array<String16>::create(); 1116f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 111762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch bool hasDebugCommandBreakpointReason = false; 1118f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch for (const auto& point : hitBreakpoints) { 1119f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch DebugServerBreakpointToBreakpointIdAndSourceMap::iterator 1120f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakpointIterator = m_serverBreakpoints.find(point); 1121f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (breakpointIterator != m_serverBreakpoints.end()) { 1122f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& localId = breakpointIterator->second.first; 1123f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch hitBreakpointIds->addItem(localId); 1124f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1125f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BreakpointSource source = breakpointIterator->second.second; 112662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!hasDebugCommandBreakpointReason && 112762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch source == DebugCommandBreakpointSource) { 112862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hasDebugCommandBreakpointReason = true; 112962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hitReasons.push_back(std::make_pair( 113062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protocol::Debugger::Paused::ReasonEnum::DebugCommand, nullptr)); 113162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 113262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 113362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 113462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 113562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0; i < m_breakReason.size(); ++i) { 113662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch hitReasons.push_back(std::move(m_breakReason[i])); 113762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } 113862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch clearBreakDetails(); 113962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch 114062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 breakReason = protocol::Debugger::Paused::ReasonEnum::Other; 114162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::DictionaryValue> breakAuxData; 114262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hitReasons.size() == 1) { 114362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakReason = hitReasons[0].first; 114462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData = std::move(hitReasons[0].second); 114562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch } else if (hitReasons.size() > 1) { 114662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakReason = protocol::Debugger::Paused::ReasonEnum::Ambiguous; 114762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::ListValue> reasons = 114862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protocol::ListValue::create(); 114962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch for (size_t i = 0; i < hitReasons.size(); ++i) { 115062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::unique_ptr<protocol::DictionaryValue> reason = 115162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch protocol::DictionaryValue::create(); 115262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reason->setString("reason", hitReasons[i].first); 115362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (hitReasons[i].second) 115462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reason->setObject("auxData", std::move(hitReasons[i].second)); 115562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch reasons->pushValue(std::move(reason)); 1156f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 115762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData = protocol::DictionaryValue::create(); 115862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch breakAuxData->setArray("reasons", std::move(reasons)); 1159f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1160f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1161c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch std::unique_ptr<Array<CallFrame>> protocolCallFrames; 1162c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch Response response = currentCallFrames(&protocolCallFrames); 1163c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create(); 116462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_frontend.paused(std::move(protocolCallFrames), breakReason, 116562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::move(breakAuxData), std::move(hitBreakpointIds), 1166f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch currentAsyncStackTrace()); 1167f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 1168f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_javaScriptPauseScheduled = false; 1169f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!m_continueToLocationBreakpointId.isEmpty()) { 1171f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->removeBreakpoint(m_continueToLocationBreakpointId); 1172f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_continueToLocationBreakpointId = ""; 1173f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch } 1174f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1175f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1176f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::didContinue() { 1177f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch JavaScriptCallFrames emptyCallFrames; 1178f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_pausedCallFrames.swap(emptyCallFrames); 1179f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch clearBreakDetails(); 1180f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_frontend.resumed(); 1181f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1182f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1183f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::breakProgram( 1184f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& breakReason, 1185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> data) { 118662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch if (!enabled() || !m_debugger->canBreakProgram() || m_skipAllPauses) return; 118762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch std::vector<BreakReason> currentScheduledReason; 118862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch currentScheduledReason.swap(m_breakReason); 118962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch pushBreakDetails(breakReason, std::move(data)); 1190f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 1191f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_debugger->breakProgram(); 119262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch popBreakDetails(); 119362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_breakReason.swap(currentScheduledReason); 1194f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1195f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1196f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::breakProgramOnException( 1197f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& breakReason, 1198f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch std::unique_ptr<protocol::DictionaryValue> data) { 1199f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!enabled() || 120062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_debugger->getPauseOnExceptionsState() == v8::debug::NoBreakOnException) 1201f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch return; 1202f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch breakProgram(breakReason, std::move(data)); 1203f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1204f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1205f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::setBreakpointAt(const String16& scriptId, 1206f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int lineNumber, int columnNumber, 1207f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BreakpointSource source, 1208f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch const String16& condition) { 120962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint breakpoint(scriptId, lineNumber, columnNumber, condition); 121062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch String16 breakpointId = generateBreakpointId(breakpoint, source); 121162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resolveBreakpoint(breakpointId, breakpoint, source); 1212f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1213f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId, 1215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch int lineNumber, int columnNumber, 1216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch BreakpointSource source) { 121762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch removeBreakpointImpl(generateBreakpointId( 121862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch ScriptBreakpoint(scriptId, lineNumber, columnNumber, String16()), 121962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch source)); 1220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1222f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid V8DebuggerAgentImpl::reset() { 1223f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch if (!enabled()) return; 1224f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_scheduledDebuggerStep = NoStep; 1225f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_blackboxedPositions.clear(); 122662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch resetBlackboxedStateCache(); 122762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch m_scripts.clear(); 1228f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch m_breakpointIdToDebuggerBreakpointIds.clear(); 1229f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} 1230f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 1231f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch} // namespace v8_inspector 1232