Merge V8 5.6.326.50
Test: manual, ran D8, tested connecting through PAC proxy.
Change-Id: I6067097f8ded999e9930a7dfd2fdc3733d7c6284
diff --git a/src/inspector/v8-debugger-agent-impl.cc b/src/inspector/v8-debugger-agent-impl.cc
index 80e2611..224ae28 100644
--- a/src/inspector/v8-debugger-agent-impl.cc
+++ b/src/inspector/v8-debugger-agent-impl.cc
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "src/debug/debug-interface.h"
#include "src/inspector/injected-script.h"
#include "src/inspector/inspected-context.h"
#include "src/inspector/java-script-call-frame.h"
@@ -21,6 +22,7 @@
#include "src/inspector/v8-regex.h"
#include "src/inspector/v8-runtime-agent-impl.h"
#include "src/inspector/v8-stack-trace-impl.h"
+#include "src/inspector/v8-value-copier.h"
#include "include/v8-inspector.h"
@@ -52,8 +54,11 @@
} // namespace DebuggerAgentState
-static const int maxSkipStepFrameCount = 128;
-static const char backtraceObjectGroup[] = "backtrace";
+static const int kMaxSkipStepFrameCount = 128;
+static const char kBacktraceObjectGroup[] = "backtrace";
+static const char kDebuggerNotEnabled[] = "Debugger agent is not enabled";
+static const char kDebuggerNotPaused[] =
+ "Can only perform operation while paused.";
static String16 breakpointIdSuffix(
V8DebuggerAgentImpl::BreakpointSource source) {
@@ -71,8 +76,14 @@
static String16 generateBreakpointId(
const String16& scriptId, int lineNumber, int columnNumber,
V8DebuggerAgentImpl::BreakpointSource source) {
- return scriptId + ":" + String16::fromInteger(lineNumber) + ":" +
- String16::fromInteger(columnNumber) + breakpointIdSuffix(source);
+ String16Builder builder;
+ builder.append(scriptId);
+ builder.append(':');
+ builder.appendNumber(lineNumber);
+ builder.append(':');
+ builder.appendNumber(columnNumber);
+ builder.append(breakpointIdSuffix(source));
+ return builder.toString();
}
static bool positionComparator(const std::pair<int, int>& a,
@@ -81,11 +92,6 @@
return a.second < b.second;
}
-static bool hasInternalError(ErrorString* errorString, bool hasError) {
- if (hasError) *errorString = "Internal error";
- return hasError;
-}
-
static std::unique_ptr<protocol::Debugger::Location> buildProtocolLocation(
const String16& scriptId, int lineNumber, int columnNumber) {
return protocol::Debugger::Location::create()
@@ -120,13 +126,7 @@
V8DebuggerAgentImpl::~V8DebuggerAgentImpl() {}
-bool V8DebuggerAgentImpl::checkEnabled(ErrorString* errorString) {
- if (enabled()) return true;
- *errorString = "Debugger agent is not enabled";
- return false;
-}
-
-void V8DebuggerAgentImpl::enable() {
+void V8DebuggerAgentImpl::enableImpl() {
// m_inspector->addListener may result in reporting all parsed scripts to
// the agent so it should already be in enabled state by then.
m_enabled = true;
@@ -145,24 +145,23 @@
bool V8DebuggerAgentImpl::enabled() { return m_enabled; }
-void V8DebuggerAgentImpl::enable(ErrorString* errorString) {
- if (enabled()) return;
+Response V8DebuggerAgentImpl::enable() {
+ if (enabled()) return Response::OK();
- if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId())) {
- *errorString = "Script execution is prohibited";
- return;
- }
+ if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
+ return Response::Error("Script execution is prohibited");
- enable();
+ enableImpl();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::disable(ErrorString*) {
- if (!enabled()) return;
+Response V8DebuggerAgentImpl::disable() {
+ if (!enabled()) return Response::OK();
m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
protocol::DictionaryValue::create());
m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
- V8Debugger::DontPauseOnExceptions);
+ v8::DebugInterface::NoBreakOnException);
m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
if (!m_pausedContext.IsEmpty()) m_debugger->continueProgram();
@@ -188,6 +187,7 @@
m_state->remove(DebuggerAgentState::blackboxPattern);
m_enabled = false;
m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
+ return Response::OK();
}
void V8DebuggerAgentImpl::restore() {
@@ -197,13 +197,11 @@
if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
return;
- enable();
- ErrorString error;
+ enableImpl();
- int pauseState = V8Debugger::DontPauseOnExceptions;
+ int pauseState = v8::DebugInterface::NoBreakOnException;
m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
- setPauseOnExceptionsImpl(&error, pauseState);
- DCHECK(error.isEmpty());
+ setPauseOnExceptionsImpl(pauseState);
m_skipAllPauses =
m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
@@ -216,19 +214,20 @@
String16 blackboxPattern;
if (m_state->getString(DebuggerAgentState::blackboxPattern,
&blackboxPattern)) {
- if (!setBlackboxPattern(&error, blackboxPattern)) UNREACHABLE();
+ setBlackboxPattern(blackboxPattern);
}
}
-void V8DebuggerAgentImpl::setBreakpointsActive(ErrorString* errorString,
- bool active) {
- if (!checkEnabled(errorString)) return;
+Response V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
m_debugger->setBreakpointsActivated(active);
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setSkipAllPauses(ErrorString*, bool skip) {
+Response V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
m_skipAllPauses = skip;
m_state->setBoolean(DebuggerAgentState::skipAllPauses, m_skipAllPauses);
+ return Response::OK();
}
static std::unique_ptr<protocol::DictionaryValue>
@@ -254,27 +253,21 @@
return url == pattern;
}
-void V8DebuggerAgentImpl::setBreakpointByUrl(
- ErrorString* errorString, int lineNumber,
- const Maybe<String16>& optionalURL, const Maybe<String16>& optionalURLRegex,
- const Maybe<int>& optionalColumnNumber,
- const Maybe<String16>& optionalCondition, String16* outBreakpointId,
+Response V8DebuggerAgentImpl::setBreakpointByUrl(
+ int lineNumber, Maybe<String16> optionalURL,
+ Maybe<String16> optionalURLRegex, Maybe<int> optionalColumnNumber,
+ Maybe<String16> optionalCondition, String16* outBreakpointId,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) {
*locations = Array<protocol::Debugger::Location>::create();
- if (optionalURL.isJust() == optionalURLRegex.isJust()) {
- *errorString = "Either url or urlRegex must be specified.";
- return;
- }
+ if (optionalURL.isJust() == optionalURLRegex.isJust())
+ return Response::Error("Either url or urlRegex must be specified.");
String16 url = optionalURL.isJust() ? optionalURL.fromJust()
: optionalURLRegex.fromJust();
int columnNumber = 0;
if (optionalColumnNumber.isJust()) {
columnNumber = optionalColumnNumber.fromJust();
- if (columnNumber < 0) {
- *errorString = "Incorrect column number";
- return;
- }
+ if (columnNumber < 0) return Response::Error("Incorrect column number");
}
String16 condition = optionalCondition.fromMaybe("");
bool isRegex = optionalURLRegex.isJust();
@@ -291,10 +284,8 @@
m_state->setObject(DebuggerAgentState::javaScriptBreakpoints,
std::move(newValue));
}
- if (breakpointsCookie->get(breakpointId)) {
- *errorString = "Breakpoint at specified location already exists.";
- return;
- }
+ if (breakpointsCookie->get(breakpointId))
+ return Response::Error("Breakpoint at specified location already exists.");
breakpointsCookie->setObject(
breakpointId, buildObjectForBreakpointCookie(
@@ -310,30 +301,16 @@
}
*outBreakpointId = breakpointId;
+ return Response::OK();
}
-static bool parseLocation(
- ErrorString* errorString,
- std::unique_ptr<protocol::Debugger::Location> location, String16* scriptId,
- int* lineNumber, int* columnNumber) {
- *scriptId = location->getScriptId();
- *lineNumber = location->getLineNumber();
- *columnNumber = location->getColumnNumber(0);
- return true;
-}
-
-void V8DebuggerAgentImpl::setBreakpoint(
- ErrorString* errorString,
+Response V8DebuggerAgentImpl::setBreakpoint(
std::unique_ptr<protocol::Debugger::Location> location,
- const Maybe<String16>& optionalCondition, String16* outBreakpointId,
+ Maybe<String16> optionalCondition, String16* outBreakpointId,
std::unique_ptr<protocol::Debugger::Location>* actualLocation) {
- String16 scriptId;
- int lineNumber;
- int columnNumber;
-
- if (!parseLocation(errorString, std::move(location), &scriptId, &lineNumber,
- &columnNumber))
- return;
+ String16 scriptId = location->getScriptId();
+ int lineNumber = location->getLineNumber();
+ int columnNumber = location->getColumnNumber(0);
String16 condition = optionalCondition.fromMaybe("");
@@ -341,28 +318,26 @@
scriptId, lineNumber, columnNumber, UserBreakpointSource);
if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
m_breakpointIdToDebuggerBreakpointIds.end()) {
- *errorString = "Breakpoint at specified location already exists.";
- return;
+ return Response::Error("Breakpoint at specified location already exists.");
}
ScriptBreakpoint breakpoint(lineNumber, columnNumber, condition);
*actualLocation = resolveBreakpoint(breakpointId, scriptId, breakpoint,
UserBreakpointSource);
- if (*actualLocation)
- *outBreakpointId = breakpointId;
- else
- *errorString = "Could not resolve breakpoint";
+ if (!*actualLocation) return Response::Error("Could not resolve breakpoint");
+ *outBreakpointId = breakpointId;
+ return Response::OK();
}
-void V8DebuggerAgentImpl::removeBreakpoint(ErrorString* errorString,
- const String16& breakpointId) {
- if (!checkEnabled(errorString)) return;
+Response V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
protocol::DictionaryValue* breakpointsCookie =
m_state->getObject(DebuggerAgentState::javaScriptBreakpoints);
if (breakpointsCookie) breakpointsCookie->remove(breakpointId);
- removeBreakpoint(breakpointId);
+ removeBreakpointImpl(breakpointId);
+ return Response::OK();
}
-void V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
+void V8DebuggerAgentImpl::removeBreakpointImpl(const String16& breakpointId) {
DCHECK(enabled());
BreakpointIdToDebuggerBreakpointIdsMap::iterator
debuggerBreakpointIdsIterator =
@@ -380,27 +355,64 @@
m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId);
}
-void V8DebuggerAgentImpl::continueToLocation(
- ErrorString* errorString,
+Response V8DebuggerAgentImpl::getPossibleBreakpoints(
+ std::unique_ptr<protocol::Debugger::Location> start,
+ Maybe<protocol::Debugger::Location> end,
+ std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) {
+ String16 scriptId = start->getScriptId();
+
+ if (start->getLineNumber() < 0 || start->getColumnNumber(0) < 0)
+ return Response::Error(
+ "start.lineNumber and start.columnNumber should be >= 0");
+
+ v8::DebugInterface::Location v8Start(start->getLineNumber(),
+ start->getColumnNumber(0));
+ v8::DebugInterface::Location v8End;
+ if (end.isJust()) {
+ if (end.fromJust()->getScriptId() != scriptId)
+ return Response::Error("Locations should contain the same scriptId");
+ int line = end.fromJust()->getLineNumber();
+ int column = end.fromJust()->getColumnNumber(0);
+ if (line < 0 || column < 0)
+ return Response::Error(
+ "end.lineNumber and end.columnNumber should be >= 0");
+ v8End = v8::DebugInterface::Location(line, column);
+ }
+ auto it = m_scripts.find(scriptId);
+ if (it == m_scripts.end()) return Response::Error("Script not found");
+
+ std::vector<v8::DebugInterface::Location> v8Locations;
+ if (!it->second->getPossibleBreakpoints(v8Start, v8End, &v8Locations))
+ return Response::InternalError();
+
+ *locations = protocol::Array<protocol::Debugger::Location>::create();
+ for (size_t i = 0; i < v8Locations.size(); ++i) {
+ (*locations)
+ ->addItem(protocol::Debugger::Location::create()
+ .setScriptId(scriptId)
+ .setLineNumber(v8Locations[i].GetLineNumber())
+ .setColumnNumber(v8Locations[i].GetColumnNumber())
+ .build());
+ }
+ return Response::OK();
+}
+
+Response V8DebuggerAgentImpl::continueToLocation(
std::unique_ptr<protocol::Debugger::Location> location) {
- if (!checkEnabled(errorString)) return;
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
if (!m_continueToLocationBreakpointId.isEmpty()) {
m_debugger->removeBreakpoint(m_continueToLocationBreakpointId);
m_continueToLocationBreakpointId = "";
}
- String16 scriptId;
- int lineNumber;
- int columnNumber;
-
- if (!parseLocation(errorString, std::move(location), &scriptId, &lineNumber,
- &columnNumber))
- return;
+ String16 scriptId = location->getScriptId();
+ int lineNumber = location->getLineNumber();
+ int columnNumber = location->getColumnNumber(0);
ScriptBreakpoint breakpoint(lineNumber, columnNumber, "");
m_continueToLocationBreakpointId = m_debugger->setBreakpoint(
scriptId, breakpoint, &lineNumber, &columnNumber);
- resume(errorString);
+ return resume();
}
bool V8DebuggerAgentImpl::isCurrentCallStackEmptyOrBlackboxed() {
@@ -471,7 +483,7 @@
if (!isCallFrameWithUnknownScriptOrBlackboxed(topCallFrame))
return RequestNoSkip;
- if (m_skippedStepFrameCount >= maxSkipStepFrameCount) return RequestStepOut;
+ if (m_skippedStepFrameCount >= kMaxSkipStepFrameCount) return RequestStepOut;
if (!m_skippedStepFrameCount) m_recursionLevelForStepFrame = 1;
@@ -509,17 +521,14 @@
return buildProtocolLocation(scriptId, actualLineNumber, actualColumnNumber);
}
-void V8DebuggerAgentImpl::searchInContent(
- ErrorString* error, const String16& scriptId, const String16& query,
- const Maybe<bool>& optionalCaseSensitive,
- const Maybe<bool>& optionalIsRegex,
+Response V8DebuggerAgentImpl::searchInContent(
+ const String16& scriptId, const String16& query,
+ Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) {
v8::HandleScope handles(m_isolate);
ScriptsMap::iterator it = m_scripts.find(scriptId);
- if (it == m_scripts.end()) {
- *error = String16("No script for id: " + scriptId);
- return;
- }
+ if (it == m_scripts.end())
+ return Response::Error("No script for id: " + scriptId);
std::vector<std::unique_ptr<protocol::Debugger::SearchMatch>> matches =
searchInTextByLinesImpl(m_session,
@@ -529,44 +538,46 @@
*results = protocol::Array<protocol::Debugger::SearchMatch>::create();
for (size_t i = 0; i < matches.size(); ++i)
(*results)->addItem(std::move(matches[i]));
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setScriptSource(
- ErrorString* errorString, const String16& scriptId,
- const String16& newContent, const Maybe<bool>& dryRun,
+Response V8DebuggerAgentImpl::setScriptSource(
+ const String16& scriptId, const String16& newContent, Maybe<bool> dryRun,
Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames,
Maybe<bool>* stackChanged, Maybe<StackTrace>* asyncStackTrace,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
- if (!checkEnabled(errorString)) return;
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
v8::HandleScope handles(m_isolate);
v8::Local<v8::String> newSource = toV8String(m_isolate, newContent);
- if (!m_debugger->setScriptSource(scriptId, newSource, dryRun.fromMaybe(false),
- errorString, optOutCompileError,
- &m_pausedCallFrames, stackChanged))
- return;
+ bool compileError = false;
+ Response response = m_debugger->setScriptSource(
+ scriptId, newSource, dryRun.fromMaybe(false), optOutCompileError,
+ &m_pausedCallFrames, stackChanged, &compileError);
+ if (!response.isSuccess() || compileError) return response;
ScriptsMap::iterator it = m_scripts.find(scriptId);
- if (it != m_scripts.end()) it->second->setSource(m_isolate, newSource);
+ if (it != m_scripts.end()) it->second->setSource(newSource);
- std::unique_ptr<Array<CallFrame>> callFrames = currentCallFrames(errorString);
- if (!callFrames) return;
+ std::unique_ptr<Array<CallFrame>> callFrames;
+ response = currentCallFrames(&callFrames);
+ if (!response.isSuccess()) return response;
*newCallFrames = std::move(callFrames);
*asyncStackTrace = currentAsyncStackTrace();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::restartFrame(
- ErrorString* errorString, const String16& callFrameId,
+Response V8DebuggerAgentImpl::restartFrame(
+ const String16& callFrameId,
std::unique_ptr<Array<CallFrame>>* newCallFrames,
Maybe<StackTrace>* asyncStackTrace) {
- if (!assertPaused(errorString)) return;
- InjectedScript::CallFrameScope scope(
- errorString, m_inspector, m_session->contextGroupId(), callFrameId);
- if (!scope.initialize()) return;
- if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
- *errorString = "Could not find call frame with given id";
- return;
- }
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+ InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
+ callFrameId);
+ Response response = scope.initialize();
+ if (!response.isSuccess()) return response;
+ if (scope.frameOrdinal() >= m_pausedCallFrames.size())
+ return Response::Error("Could not find call frame with given id");
v8::Local<v8::Value> resultValue;
v8::Local<v8::Boolean> result;
@@ -575,28 +586,26 @@
scope.tryCatch().HasCaught() ||
!resultValue->ToBoolean(scope.context()).ToLocal(&result) ||
!result->Value()) {
- *errorString = "Internal error";
- return;
+ return Response::InternalError();
}
JavaScriptCallFrames frames = m_debugger->currentCallFrames();
m_pausedCallFrames.swap(frames);
- *newCallFrames = currentCallFrames(errorString);
- if (!*newCallFrames) return;
+ response = currentCallFrames(newCallFrames);
+ if (!response.isSuccess()) return response;
*asyncStackTrace = currentAsyncStackTrace();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::getScriptSource(ErrorString* error,
- const String16& scriptId,
- String16* scriptSource) {
- if (!checkEnabled(error)) return;
+Response V8DebuggerAgentImpl::getScriptSource(const String16& scriptId,
+ String16* scriptSource) {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
ScriptsMap::iterator it = m_scripts.find(scriptId);
- if (it == m_scripts.end()) {
- *error = "No script for id: " + scriptId;
- return;
- }
+ if (it == m_scripts.end())
+ return Response::Error("No script for id: " + scriptId);
v8::HandleScope handles(m_isolate);
*scriptSource = toProtocolString(it->second->source(m_isolate));
+ return Response::OK();
}
void V8DebuggerAgentImpl::schedulePauseOnNextStatement(
@@ -632,103 +641,100 @@
m_debugger->setPauseOnNextStatement(false);
}
-void V8DebuggerAgentImpl::pause(ErrorString* errorString) {
- if (!checkEnabled(errorString)) return;
- if (m_javaScriptPauseScheduled || m_debugger->isPaused()) return;
+Response V8DebuggerAgentImpl::pause() {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
+ if (m_javaScriptPauseScheduled || m_debugger->isPaused())
+ return Response::OK();
clearBreakDetails();
m_javaScriptPauseScheduled = true;
m_scheduledDebuggerStep = NoStep;
m_skippedStepFrameCount = 0;
m_steppingFromFramework = false;
m_debugger->setPauseOnNextStatement(true);
+ return Response::OK();
}
-void V8DebuggerAgentImpl::resume(ErrorString* errorString) {
- if (!assertPaused(errorString)) return;
+Response V8DebuggerAgentImpl::resume() {
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
m_scheduledDebuggerStep = NoStep;
m_steppingFromFramework = false;
- m_session->releaseObjectGroup(backtraceObjectGroup);
+ m_session->releaseObjectGroup(kBacktraceObjectGroup);
m_debugger->continueProgram();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::stepOver(ErrorString* errorString) {
- if (!assertPaused(errorString)) return;
+Response V8DebuggerAgentImpl::stepOver() {
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
// StepOver at function return point should fallback to StepInto.
JavaScriptCallFrame* frame =
!m_pausedCallFrames.empty() ? m_pausedCallFrames[0].get() : nullptr;
- if (frame && frame->isAtReturn()) {
- stepInto(errorString);
- return;
- }
+ if (frame && frame->isAtReturn()) return stepInto();
m_scheduledDebuggerStep = StepOver;
m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
- m_session->releaseObjectGroup(backtraceObjectGroup);
+ m_session->releaseObjectGroup(kBacktraceObjectGroup);
m_debugger->stepOverStatement();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::stepInto(ErrorString* errorString) {
- if (!assertPaused(errorString)) return;
+Response V8DebuggerAgentImpl::stepInto() {
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
m_scheduledDebuggerStep = StepInto;
m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
- m_session->releaseObjectGroup(backtraceObjectGroup);
+ m_session->releaseObjectGroup(kBacktraceObjectGroup);
m_debugger->stepIntoStatement();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::stepOut(ErrorString* errorString) {
- if (!assertPaused(errorString)) return;
+Response V8DebuggerAgentImpl::stepOut() {
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
m_scheduledDebuggerStep = StepOut;
m_skipNextDebuggerStepOut = false;
m_recursionLevelForStepOut = 1;
m_steppingFromFramework = isTopPausedCallFrameBlackboxed();
- m_session->releaseObjectGroup(backtraceObjectGroup);
+ m_session->releaseObjectGroup(kBacktraceObjectGroup);
m_debugger->stepOutOfFunction();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setPauseOnExceptions(
- ErrorString* errorString, const String16& stringPauseState) {
- if (!checkEnabled(errorString)) return;
- V8Debugger::PauseOnExceptionsState pauseState;
+Response V8DebuggerAgentImpl::setPauseOnExceptions(
+ const String16& stringPauseState) {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
+ v8::DebugInterface::ExceptionBreakState pauseState;
if (stringPauseState == "none") {
- pauseState = V8Debugger::DontPauseOnExceptions;
+ pauseState = v8::DebugInterface::NoBreakOnException;
} else if (stringPauseState == "all") {
- pauseState = V8Debugger::PauseOnAllExceptions;
+ pauseState = v8::DebugInterface::BreakOnAnyException;
} else if (stringPauseState == "uncaught") {
- pauseState = V8Debugger::PauseOnUncaughtExceptions;
+ pauseState = v8::DebugInterface::BreakOnUncaughtException;
} else {
- *errorString = "Unknown pause on exceptions mode: " + stringPauseState;
- return;
+ return Response::Error("Unknown pause on exceptions mode: " +
+ stringPauseState);
}
- setPauseOnExceptionsImpl(errorString, pauseState);
+ setPauseOnExceptionsImpl(pauseState);
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(ErrorString* errorString,
- int pauseState) {
+void V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) {
m_debugger->setPauseOnExceptionsState(
- static_cast<V8Debugger::PauseOnExceptionsState>(pauseState));
- if (m_debugger->getPauseOnExceptionsState() != pauseState)
- *errorString = "Internal error. Could not change pause on exceptions state";
- else
- m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
+ static_cast<v8::DebugInterface::ExceptionBreakState>(pauseState));
+ m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
}
-void V8DebuggerAgentImpl::evaluateOnCallFrame(
- ErrorString* errorString, const String16& callFrameId,
- const String16& expression, const Maybe<String16>& objectGroup,
- const Maybe<bool>& includeCommandLineAPI, const Maybe<bool>& silent,
- const Maybe<bool>& returnByValue, const Maybe<bool>& generatePreview,
+Response V8DebuggerAgentImpl::evaluateOnCallFrame(
+ const String16& callFrameId, const String16& expression,
+ Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
+ Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
std::unique_ptr<RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
- if (!assertPaused(errorString)) return;
- InjectedScript::CallFrameScope scope(
- errorString, m_inspector, m_session->contextGroupId(), callFrameId);
- if (!scope.initialize()) return;
- if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
- *errorString = "Could not find call frame with given id";
- return;
- }
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+ InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
+ callFrameId);
+ Response response = scope.initialize();
+ if (!response.isSuccess()) return response;
+ if (scope.frameOrdinal() >= m_pausedCallFrames.size())
+ return Response::Error("Could not find call frame with given id");
- if (includeCommandLineAPI.fromMaybe(false) && !scope.installCommandLineAPI())
- return;
+ if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
v8::MaybeLocal<v8::Value> maybeResultValue =
@@ -737,56 +743,52 @@
// Re-initialize after running client's code, as it could have destroyed
// context or session.
- if (!scope.initialize()) return;
- scope.injectedScript()->wrapEvaluateResult(
- errorString, maybeResultValue, scope.tryCatch(),
- objectGroup.fromMaybe(""), returnByValue.fromMaybe(false),
- generatePreview.fromMaybe(false), result, exceptionDetails);
+ response = scope.initialize();
+ if (!response.isSuccess()) return response;
+ return scope.injectedScript()->wrapEvaluateResult(
+ maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""),
+ returnByValue.fromMaybe(false), generatePreview.fromMaybe(false), result,
+ exceptionDetails);
}
-void V8DebuggerAgentImpl::setVariableValue(
- ErrorString* errorString, int scopeNumber, const String16& variableName,
+Response V8DebuggerAgentImpl::setVariableValue(
+ int scopeNumber, const String16& variableName,
std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
const String16& callFrameId) {
- if (!checkEnabled(errorString)) return;
- if (!assertPaused(errorString)) return;
- InjectedScript::CallFrameScope scope(
- errorString, m_inspector, m_session->contextGroupId(), callFrameId);
- if (!scope.initialize()) return;
-
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
+ if (m_pausedContext.IsEmpty()) return Response::Error(kDebuggerNotPaused);
+ InjectedScript::CallFrameScope scope(m_inspector, m_session->contextGroupId(),
+ callFrameId);
+ Response response = scope.initialize();
+ if (!response.isSuccess()) return response;
v8::Local<v8::Value> newValue;
- if (!scope.injectedScript()
- ->resolveCallArgument(errorString, newValueArgument.get())
- .ToLocal(&newValue))
- return;
+ response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(),
+ &newValue);
+ if (!response.isSuccess()) return response;
- if (scope.frameOrdinal() >= m_pausedCallFrames.size()) {
- *errorString = "Could not find call frame with given id";
- return;
- }
+ if (scope.frameOrdinal() >= m_pausedCallFrames.size())
+ return Response::Error("Could not find call frame with given id");
v8::MaybeLocal<v8::Value> result =
m_pausedCallFrames[scope.frameOrdinal()]->setVariableValue(
scopeNumber, toV8String(m_isolate, variableName), newValue);
- if (scope.tryCatch().HasCaught() || result.IsEmpty()) {
- *errorString = "Internal error";
- return;
- }
+ if (scope.tryCatch().HasCaught() || result.IsEmpty())
+ return Response::InternalError();
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setAsyncCallStackDepth(ErrorString* errorString,
- int depth) {
- if (!checkEnabled(errorString)) return;
+Response V8DebuggerAgentImpl::setAsyncCallStackDepth(int depth) {
+ if (!enabled()) return Response::Error(kDebuggerNotEnabled);
m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth);
m_debugger->setAsyncCallStackDepth(this, depth);
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setBlackboxPatterns(
- ErrorString* errorString,
+Response V8DebuggerAgentImpl::setBlackboxPatterns(
std::unique_ptr<protocol::Array<String16>> patterns) {
if (!patterns->length()) {
m_blackboxPattern = nullptr;
m_state->remove(DebuggerAgentState::blackboxPattern);
- return;
+ return Response::OK();
}
String16Builder patternBuilder;
@@ -798,48 +800,41 @@
patternBuilder.append(patterns->get(patterns->length() - 1));
patternBuilder.append(')');
String16 pattern = patternBuilder.toString();
- if (!setBlackboxPattern(errorString, pattern)) return;
+ Response response = setBlackboxPattern(pattern);
+ if (!response.isSuccess()) return response;
m_state->setString(DebuggerAgentState::blackboxPattern, pattern);
+ return Response::OK();
}
-bool V8DebuggerAgentImpl::setBlackboxPattern(ErrorString* errorString,
- const String16& pattern) {
+Response V8DebuggerAgentImpl::setBlackboxPattern(const String16& pattern) {
std::unique_ptr<V8Regex> regex(new V8Regex(
m_inspector, pattern, true /** caseSensitive */, false /** multiline */));
- if (!regex->isValid()) {
- *errorString = "Pattern parser error: " + regex->errorMessage();
- return false;
- }
+ if (!regex->isValid())
+ return Response::Error("Pattern parser error: " + regex->errorMessage());
m_blackboxPattern = std::move(regex);
- return true;
+ return Response::OK();
}
-void V8DebuggerAgentImpl::setBlackboxedRanges(
- ErrorString* error, const String16& scriptId,
+Response V8DebuggerAgentImpl::setBlackboxedRanges(
+ const String16& scriptId,
std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
inPositions) {
- if (m_scripts.find(scriptId) == m_scripts.end()) {
- *error = "No script with passed id.";
- return;
- }
+ if (m_scripts.find(scriptId) == m_scripts.end())
+ return Response::Error("No script with passed id.");
if (!inPositions->length()) {
m_blackboxedPositions.erase(scriptId);
- return;
+ return Response::OK();
}
std::vector<std::pair<int, int>> positions;
positions.reserve(inPositions->length());
for (size_t i = 0; i < inPositions->length(); ++i) {
protocol::Debugger::ScriptPosition* position = inPositions->get(i);
- if (position->getLineNumber() < 0) {
- *error = "Position missing 'line' or 'line' < 0.";
- return;
- }
- if (position->getColumnNumber() < 0) {
- *error = "Position missing 'column' or 'column' < 0.";
- return;
- }
+ if (position->getLineNumber() < 0)
+ return Response::Error("Position missing 'line' or 'line' < 0.");
+ if (position->getColumnNumber() < 0)
+ return Response::Error("Position missing 'column' or 'column' < 0.");
positions.push_back(
std::make_pair(position->getLineNumber(), position->getColumnNumber()));
}
@@ -849,12 +844,12 @@
if (positions[i - 1].first == positions[i].first &&
positions[i - 1].second < positions[i].second)
continue;
- *error =
- "Input positions array is not sorted or contains duplicate values.";
- return;
+ return Response::Error(
+ "Input positions array is not sorted or contains duplicate values.");
}
m_blackboxedPositions[scriptId] = positions;
+ return Response::OK();
}
void V8DebuggerAgentImpl::willExecuteScript(int scriptId) {
@@ -907,14 +902,15 @@
}
}
-std::unique_ptr<Array<CallFrame>> V8DebuggerAgentImpl::currentCallFrames(
- ErrorString* errorString) {
- if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size())
- return Array<CallFrame>::create();
- ErrorString ignored;
+Response V8DebuggerAgentImpl::currentCallFrames(
+ std::unique_ptr<Array<CallFrame>>* result) {
+ if (m_pausedContext.IsEmpty() || !m_pausedCallFrames.size()) {
+ *result = Array<CallFrame>::create();
+ return Response::OK();
+ }
v8::HandleScope handles(m_isolate);
v8::Local<v8::Context> debuggerContext =
- v8::Debug::GetDebugContext(m_isolate);
+ v8::DebugInterface::GetDebugContext(m_isolate);
v8::Context::Scope contextScope(debuggerContext);
v8::Local<v8::Array> objects = v8::Array::New(m_isolate);
@@ -925,104 +921,92 @@
m_pausedCallFrames[frameOrdinal];
v8::Local<v8::Object> details = currentCallFrame->details();
- if (hasInternalError(errorString, details.IsEmpty()))
- return Array<CallFrame>::create();
+ if (details.IsEmpty()) return Response::InternalError();
int contextId = currentCallFrame->contextId();
- InjectedScript* injectedScript =
- contextId ? m_session->findInjectedScript(&ignored, contextId)
- : nullptr;
+
+ InjectedScript* injectedScript = nullptr;
+ if (contextId) m_session->findInjectedScript(contextId, injectedScript);
String16 callFrameId =
RemoteCallFrameId::serialize(contextId, static_cast<int>(frameOrdinal));
- if (hasInternalError(
- errorString,
- !details
- ->Set(debuggerContext,
- toV8StringInternalized(m_isolate, "callFrameId"),
- toV8String(m_isolate, callFrameId))
- .FromMaybe(false)))
- return Array<CallFrame>::create();
+ if (!details
+ ->Set(debuggerContext,
+ toV8StringInternalized(m_isolate, "callFrameId"),
+ toV8String(m_isolate, callFrameId))
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
if (injectedScript) {
v8::Local<v8::Value> scopeChain;
- if (hasInternalError(
- errorString,
- !details->Get(debuggerContext,
- toV8StringInternalized(m_isolate, "scopeChain"))
- .ToLocal(&scopeChain) ||
- !scopeChain->IsArray()))
- return Array<CallFrame>::create();
+ if (!details
+ ->Get(debuggerContext,
+ toV8StringInternalized(m_isolate, "scopeChain"))
+ .ToLocal(&scopeChain) ||
+ !scopeChain->IsArray()) {
+ return Response::InternalError();
+ }
v8::Local<v8::Array> scopeChainArray = scopeChain.As<v8::Array>();
- if (!injectedScript->wrapPropertyInArray(
- errorString, scopeChainArray,
- toV8StringInternalized(m_isolate, "object"),
- backtraceObjectGroup))
- return Array<CallFrame>::create();
- if (!injectedScript->wrapObjectProperty(
- errorString, details, toV8StringInternalized(m_isolate, "this"),
- backtraceObjectGroup))
- return Array<CallFrame>::create();
+ Response response = injectedScript->wrapPropertyInArray(
+ scopeChainArray, toV8StringInternalized(m_isolate, "object"),
+ kBacktraceObjectGroup);
+ if (!response.isSuccess()) return response;
+ response = injectedScript->wrapObjectProperty(
+ details, toV8StringInternalized(m_isolate, "this"),
+ kBacktraceObjectGroup);
+ if (!response.isSuccess()) return response;
if (details
->Has(debuggerContext,
toV8StringInternalized(m_isolate, "returnValue"))
.FromMaybe(false)) {
- if (!injectedScript->wrapObjectProperty(
- errorString, details,
- toV8StringInternalized(m_isolate, "returnValue"),
- backtraceObjectGroup))
- return Array<CallFrame>::create();
+ response = injectedScript->wrapObjectProperty(
+ details, toV8StringInternalized(m_isolate, "returnValue"),
+ kBacktraceObjectGroup);
+ if (!response.isSuccess()) return response;
}
} else {
- if (hasInternalError(errorString, !details
- ->Set(debuggerContext,
- toV8StringInternalized(
- m_isolate, "scopeChain"),
- v8::Array::New(m_isolate, 0))
- .FromMaybe(false)))
- return Array<CallFrame>::create();
+ if (!details
+ ->Set(debuggerContext,
+ toV8StringInternalized(m_isolate, "scopeChain"),
+ v8::Array::New(m_isolate, 0))
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
v8::Local<v8::Object> remoteObject = v8::Object::New(m_isolate);
- if (hasInternalError(
- errorString,
- !remoteObject
- ->Set(debuggerContext,
- toV8StringInternalized(m_isolate, "type"),
- toV8StringInternalized(m_isolate, "undefined"))
- .FromMaybe(false)))
- return Array<CallFrame>::create();
- if (hasInternalError(errorString,
- !details
- ->Set(debuggerContext,
- toV8StringInternalized(m_isolate, "this"),
- remoteObject)
- .FromMaybe(false)))
- return Array<CallFrame>::create();
- if (hasInternalError(
- errorString,
- !details
- ->Delete(debuggerContext,
- toV8StringInternalized(m_isolate, "returnValue"))
- .FromMaybe(false)))
- return Array<CallFrame>::create();
+ if (!remoteObject
+ ->Set(debuggerContext, toV8StringInternalized(m_isolate, "type"),
+ toV8StringInternalized(m_isolate, "undefined"))
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
+ if (!details
+ ->Set(debuggerContext, toV8StringInternalized(m_isolate, "this"),
+ remoteObject)
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
+ if (!details
+ ->Delete(debuggerContext,
+ toV8StringInternalized(m_isolate, "returnValue"))
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
}
- if (hasInternalError(
- errorString,
- !objects
- ->Set(debuggerContext, static_cast<int>(frameOrdinal), details)
- .FromMaybe(false)))
- return Array<CallFrame>::create();
+ if (!objects->Set(debuggerContext, static_cast<int>(frameOrdinal), details)
+ .FromMaybe(false)) {
+ return Response::InternalError();
+ }
}
- std::unique_ptr<protocol::Value> protocolValue =
- toProtocolValue(errorString, debuggerContext, objects);
- if (!protocolValue) return Array<CallFrame>::create();
+ std::unique_ptr<protocol::Value> protocolValue;
+ Response response = toProtocolValue(debuggerContext, objects, &protocolValue);
+ if (!response.isSuccess()) return response;
protocol::ErrorSupport errorSupport;
- std::unique_ptr<Array<CallFrame>> callFrames =
- Array<CallFrame>::parse(protocolValue.get(), &errorSupport);
- if (hasInternalError(errorString, !callFrames))
- return Array<CallFrame>::create();
- return callFrames;
+ *result = Array<CallFrame>::parse(protocolValue.get(), &errorSupport);
+ if (!*result) return Response::Error(errorSupport.errors());
+ return Response::OK();
}
std::unique_ptr<StackTrace> V8DebuggerAgentImpl::currentAsyncStackTrace() {
@@ -1049,8 +1033,8 @@
String16 scriptId = script->scriptId();
String16 scriptURL = script->sourceURL();
- const Maybe<String16>& sourceMapURLParam = script->sourceMappingURL();
- const Maybe<protocol::DictionaryValue>& executionContextAuxDataParam(
+ Maybe<String16> sourceMapURLParam = script->sourceMappingURL();
+ Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
std::move(executionContextAuxData));
const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
const bool* hasSourceURLParam = hasSourceURL ? &hasSourceURL : nullptr;
@@ -1058,14 +1042,14 @@
m_frontend.scriptParsed(
scriptId, scriptURL, script->startLine(), script->startColumn(),
script->endLine(), script->endColumn(), script->executionContextId(),
- script->hash(), executionContextAuxDataParam, isLiveEditParam,
- sourceMapURLParam, hasSourceURLParam);
+ script->hash(), std::move(executionContextAuxDataParam),
+ isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam);
else
m_frontend.scriptFailedToParse(
scriptId, scriptURL, script->startLine(), script->startColumn(),
script->endLine(), script->endColumn(), script->executionContextId(),
- script->hash(), executionContextAuxDataParam, sourceMapURLParam,
- hasSourceURLParam);
+ script->hash(), std::move(executionContextAuxDataParam),
+ std::move(sourceMapURLParam), hasSourceURLParam);
m_scripts[scriptId] = std::move(script);
@@ -1100,7 +1084,8 @@
V8DebuggerAgentImpl::SkipPauseRequest V8DebuggerAgentImpl::didPause(
v8::Local<v8::Context> context, v8::Local<v8::Value> exception,
- const std::vector<String16>& hitBreakpoints, bool isPromiseRejection) {
+ const std::vector<String16>& hitBreakpoints, bool isPromiseRejection,
+ bool isUncaught) {
JavaScriptCallFrames callFrames = m_debugger->currentCallFrames(1);
JavaScriptCallFrame* topCallFrame =
!callFrames.empty() ? callFrames.begin()->get() : nullptr;
@@ -1131,18 +1116,23 @@
v8::HandleScope handles(m_isolate);
if (!exception.IsEmpty()) {
- ErrorString ignored;
- InjectedScript* injectedScript =
- m_session->findInjectedScript(&ignored, V8Debugger::contextId(context));
+ InjectedScript* injectedScript = nullptr;
+ m_session->findInjectedScript(V8Debugger::contextId(context),
+ injectedScript);
if (injectedScript) {
m_breakReason =
isPromiseRejection
? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
: protocol::Debugger::Paused::ReasonEnum::Exception;
- ErrorString errorString;
- auto obj = injectedScript->wrapObject(&errorString, exception,
- backtraceObjectGroup);
- m_breakAuxData = obj ? obj->serialize() : nullptr;
+ std::unique_ptr<protocol::Runtime::RemoteObject> obj;
+ injectedScript->wrapObject(exception, kBacktraceObjectGroup, false, false,
+ &obj);
+ if (obj) {
+ m_breakAuxData = obj->serialize();
+ m_breakAuxData->setBoolean("uncaught", isUncaught);
+ } else {
+ m_breakAuxData = nullptr;
+ }
// m_breakAuxData might be null after this.
}
}
@@ -1163,8 +1153,10 @@
}
}
- ErrorString errorString;
- m_frontend.paused(currentCallFrames(&errorString), m_breakReason,
+ std::unique_ptr<Array<CallFrame>> protocolCallFrames;
+ Response response = currentCallFrames(&protocolCallFrames);
+ if (!response.isSuccess()) protocolCallFrames = Array<CallFrame>::create();
+ m_frontend.paused(std::move(protocolCallFrames), m_breakReason,
std::move(m_breakAuxData), std::move(hitBreakpointIds),
currentAsyncStackTrace());
m_scheduledDebuggerStep = NoStep;
@@ -1209,19 +1201,11 @@
std::unique_ptr<protocol::DictionaryValue> data) {
if (!enabled() ||
m_debugger->getPauseOnExceptionsState() ==
- V8Debugger::DontPauseOnExceptions)
+ v8::DebugInterface::NoBreakOnException)
return;
breakProgram(breakReason, std::move(data));
}
-bool V8DebuggerAgentImpl::assertPaused(ErrorString* errorString) {
- if (m_pausedContext.IsEmpty()) {
- *errorString = "Can only perform operation while paused.";
- return false;
- }
- return true;
-}
-
void V8DebuggerAgentImpl::clearBreakDetails() {
m_breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
m_breakAuxData = nullptr;
@@ -1240,7 +1224,7 @@
void V8DebuggerAgentImpl::removeBreakpointAt(const String16& scriptId,
int lineNumber, int columnNumber,
BreakpointSource source) {
- removeBreakpoint(
+ removeBreakpointImpl(
generateBreakpointId(scriptId, lineNumber, columnNumber, source));
}