// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_
#define V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_
#include <vector>
#include "src/base/macros.h"
#include "src/inspector/java-script-call-frame.h"
#include "src/inspector/protocol/Debugger.h"
#include "src/inspector/protocol/Forward.h"
namespace v8_inspector {
struct ScriptBreakpoint;
class JavaScriptCallFrame;
class PromiseTracker;
class V8Debugger;
class V8DebuggerScript;
class V8InspectorImpl;
class V8InspectorSessionImpl;
class V8Regex;
class V8StackTraceImpl;
using protocol::Maybe;
using protocol::Response;
class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
public:
enum SkipPauseRequest {
RequestNoSkip,
RequestContinue,
RequestStepInto,
RequestStepOut,
RequestStepFrame
};
enum BreakpointSource {
UserBreakpointSource,
DebugCommandBreakpointSource,
MonitorCommandBreakpointSource
};
V8DebuggerAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*,
protocol::DictionaryValue* state);
~V8DebuggerAgentImpl() override;
void restore();
// Part of the protocol.
Response enable() override;
Response disable() override;
Response setBreakpointsActive(bool active) override;
Response setSkipAllPauses(bool skip) override;
Response setBreakpointByUrl(
int lineNumber, Maybe<String16> optionalURL,
Maybe<String16> optionalURLRegex, Maybe<int> optionalColumnNumber,
Maybe<String16> optionalCondition, String16*,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations)
override;
Response setBreakpoint(
std::unique_ptr<protocol::Debugger::Location>,
Maybe<String16> optionalCondition, String16*,
std::unique_ptr<protocol::Debugger::Location>* actualLocation) override;
Response removeBreakpoint(const String16& breakpointId) override;
Response continueToLocation(
std::unique_ptr<protocol::Debugger::Location>) override;
Response searchInContent(
const String16& scriptId, const String16& query,
Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*)
override;
Response getPossibleBreakpoints(
std::unique_ptr<protocol::Debugger::Location> start,
Maybe<protocol::Debugger::Location> end,
std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations)
override;
Response setScriptSource(
const String16& inScriptId, const String16& inScriptSource,
Maybe<bool> dryRun,
Maybe<protocol::Array<protocol::Debugger::CallFrame>>* optOutCallFrames,
Maybe<bool>* optOutStackChanged,
Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace,
Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override;
Response restartFrame(
const String16& callFrameId,
std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*
newCallFrames,
Maybe<protocol::Runtime::StackTrace>* asyncStackTrace) override;
Response getScriptSource(const String16& scriptId,
String16* scriptSource) override;
Response pause() override;
Response resume() override;
Response stepOver() override;
Response stepInto() override;
Response stepOut() override;
Response setPauseOnExceptions(const String16& pauseState) override;
Response 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<protocol::Runtime::RemoteObject>* result,
Maybe<protocol::Runtime::ExceptionDetails>*) override;
Response setVariableValue(
int scopeNumber, const String16& variableName,
std::unique_ptr<protocol::Runtime::CallArgument> newValue,
const String16& callFrame) override;
Response setAsyncCallStackDepth(int depth) override;
Response setBlackboxPatterns(
std::unique_ptr<protocol::Array<String16>> patterns) override;
Response setBlackboxedRanges(
const String16& scriptId,
std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
positions) override;
bool enabled();
void setBreakpointAt(const String16& scriptId, int lineNumber,
int columnNumber, BreakpointSource,
const String16& condition = String16());
void removeBreakpointAt(const String16& scriptId, int lineNumber,
int columnNumber, BreakpointSource);
void schedulePauseOnNextStatement(
const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void cancelPauseOnNextStatement();
void breakProgram(const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void breakProgramOnException(const String16& breakReason,
std::unique_ptr<protocol::DictionaryValue> data);
void reset();
// Interface for V8InspectorImpl
SkipPauseRequest didPause(v8::Local<v8::Context>,
v8::Local<v8::Value> exception,
const std::vector<String16>& hitBreakpoints,
bool isPromiseRejection, bool isUncaught);
void didContinue();
void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
void willExecuteScript(int scriptId);
void didExecuteScript();
v8::Isolate* isolate() { return m_isolate; }
private:
void enableImpl();
SkipPauseRequest shouldSkipExceptionPause(JavaScriptCallFrame* topCallFrame);
SkipPauseRequest shouldSkipStepPause(JavaScriptCallFrame* topCallFrame);
void schedulePauseOnNextStatementIfSteppingInto();
Response currentCallFrames(
std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*);
std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace();
void changeJavaScriptRecursionLevel(int step);
void setPauseOnExceptionsImpl(int);
std::unique_ptr<protocol::Debugger::Location> resolveBreakpoint(
const String16& breakpointId, const String16& scriptId,
const ScriptBreakpoint&, BreakpointSource);
void removeBreakpointImpl(const String16& breakpointId);
void clearBreakDetails();
bool isCurrentCallStackEmptyOrBlackboxed();
bool isTopPausedCallFrameBlackboxed();
bool isCallFrameWithUnknownScriptOrBlackboxed(JavaScriptCallFrame*);
void internalSetAsyncCallStackDepth(int);
void increaseCachedSkipStackGeneration();
Response setBlackboxPattern(const String16& pattern);
using ScriptsMap =
protocol::HashMap<String16, std::unique_ptr<V8DebuggerScript>>;
using BreakpointIdToDebuggerBreakpointIdsMap =
protocol::HashMap<String16, std::vector<String16>>;
using DebugServerBreakpointToBreakpointIdAndSourceMap =
protocol::HashMap<String16, std::pair<String16, BreakpointSource>>;
using MuteBreakpoins = protocol::HashMap<String16, std::pair<String16, int>>;
enum DebuggerStep { NoStep = 0, StepInto, StepOver, StepOut };
V8InspectorImpl* m_inspector;
V8Debugger* m_debugger;
V8InspectorSessionImpl* m_session;
bool m_enabled;
protocol::DictionaryValue* m_state;
protocol::Debugger::Frontend m_frontend;
v8::Isolate* m_isolate;
v8::Global<v8::Context> m_pausedContext;
JavaScriptCallFrames m_pausedCallFrames;
ScriptsMap m_scripts;
BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
String16 m_continueToLocationBreakpointId;
String16 m_breakReason;
std::unique_ptr<protocol::DictionaryValue> m_breakAuxData;
DebuggerStep m_scheduledDebuggerStep;
bool m_skipNextDebuggerStepOut;
bool m_javaScriptPauseScheduled;
bool m_steppingFromFramework;
bool m_pausingOnNativeEvent;
int m_skippedStepFrameCount;
int m_recursionLevelForStepOut;
int m_recursionLevelForStepFrame;
bool m_skipAllPauses;
std::unique_ptr<V8Regex> m_blackboxPattern;
protocol::HashMap<String16, std::vector<std::pair<int, int>>>
m_blackboxedPositions;
DISALLOW_COPY_AND_ASSIGN(V8DebuggerAgentImpl);
};
} // namespace v8_inspector
#endif // V8_INSPECTOR_V8DEBUGGERAGENTIMPL_H_