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