11cb0ef41Sopenharmony_ci// Copyright 2015 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_
61cb0ef41Sopenharmony_ci#define V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <deque>
91cb0ef41Sopenharmony_ci#include <memory>
101cb0ef41Sopenharmony_ci#include <unordered_map>
111cb0ef41Sopenharmony_ci#include <vector>
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "src/base/enum-set.h"
141cb0ef41Sopenharmony_ci#include "src/base/macros.h"
151cb0ef41Sopenharmony_ci#include "src/debug/debug-interface.h"
161cb0ef41Sopenharmony_ci#include "src/inspector/protocol/Debugger.h"
171cb0ef41Sopenharmony_ci#include "src/inspector/protocol/Forward.h"
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cinamespace v8_inspector {
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_cistruct ScriptBreakpoint;
221cb0ef41Sopenharmony_ciclass V8Debugger;
231cb0ef41Sopenharmony_ciclass V8DebuggerScript;
241cb0ef41Sopenharmony_ciclass V8InspectorImpl;
251cb0ef41Sopenharmony_ciclass V8InspectorSessionImpl;
261cb0ef41Sopenharmony_ciclass V8Regex;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciusing protocol::Maybe;
291cb0ef41Sopenharmony_ciusing protocol::Response;
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ciclass V8DebuggerAgentImpl : public protocol::Debugger::Backend {
321cb0ef41Sopenharmony_ci public:
331cb0ef41Sopenharmony_ci  enum BreakpointSource {
341cb0ef41Sopenharmony_ci    UserBreakpointSource,
351cb0ef41Sopenharmony_ci    DebugCommandBreakpointSource,
361cb0ef41Sopenharmony_ci    MonitorCommandBreakpointSource
371cb0ef41Sopenharmony_ci  };
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  V8DebuggerAgentImpl(V8InspectorSessionImpl*, protocol::FrontendChannel*,
401cb0ef41Sopenharmony_ci                      protocol::DictionaryValue* state);
411cb0ef41Sopenharmony_ci  ~V8DebuggerAgentImpl() override;
421cb0ef41Sopenharmony_ci  V8DebuggerAgentImpl(const V8DebuggerAgentImpl&) = delete;
431cb0ef41Sopenharmony_ci  V8DebuggerAgentImpl& operator=(const V8DebuggerAgentImpl&) = delete;
441cb0ef41Sopenharmony_ci  void restore();
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  // Part of the protocol.
471cb0ef41Sopenharmony_ci  Response enable(Maybe<double> maxScriptsCacheSize,
481cb0ef41Sopenharmony_ci                  String16* outDebuggerId) override;
491cb0ef41Sopenharmony_ci  Response disable() override;
501cb0ef41Sopenharmony_ci  Response setBreakpointsActive(bool active) override;
511cb0ef41Sopenharmony_ci  Response setSkipAllPauses(bool skip) override;
521cb0ef41Sopenharmony_ci  Response setBreakpointByUrl(
531cb0ef41Sopenharmony_ci      int lineNumber, Maybe<String16> optionalURL,
541cb0ef41Sopenharmony_ci      Maybe<String16> optionalURLRegex, Maybe<String16> optionalScriptHash,
551cb0ef41Sopenharmony_ci      Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition,
561cb0ef41Sopenharmony_ci      String16*,
571cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations)
581cb0ef41Sopenharmony_ci      override;
591cb0ef41Sopenharmony_ci  Response setBreakpoint(
601cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Debugger::Location>,
611cb0ef41Sopenharmony_ci      Maybe<String16> optionalCondition, String16*,
621cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Debugger::Location>* actualLocation) override;
631cb0ef41Sopenharmony_ci  Response setBreakpointOnFunctionCall(const String16& functionObjectId,
641cb0ef41Sopenharmony_ci                                       Maybe<String16> optionalCondition,
651cb0ef41Sopenharmony_ci                                       String16* outBreakpointId) override;
661cb0ef41Sopenharmony_ci  Response setInstrumentationBreakpoint(const String16& instrumentation,
671cb0ef41Sopenharmony_ci                                        String16* outBreakpointId) override;
681cb0ef41Sopenharmony_ci  Response removeBreakpoint(const String16& breakpointId) override;
691cb0ef41Sopenharmony_ci  Response continueToLocation(std::unique_ptr<protocol::Debugger::Location>,
701cb0ef41Sopenharmony_ci                              Maybe<String16> targetCallFrames) override;
711cb0ef41Sopenharmony_ci  Response getStackTrace(
721cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::StackTraceId> inStackTraceId,
731cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) override;
741cb0ef41Sopenharmony_ci  Response searchInContent(
751cb0ef41Sopenharmony_ci      const String16& scriptId, const String16& query,
761cb0ef41Sopenharmony_ci      Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
771cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::SearchMatch>>*)
781cb0ef41Sopenharmony_ci      override;
791cb0ef41Sopenharmony_ci  Response getPossibleBreakpoints(
801cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Debugger::Location> start,
811cb0ef41Sopenharmony_ci      Maybe<protocol::Debugger::Location> end, Maybe<bool> restrictToFunction,
821cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::BreakLocation>>*
831cb0ef41Sopenharmony_ci          locations) override;
841cb0ef41Sopenharmony_ci  Response setScriptSource(
851cb0ef41Sopenharmony_ci      const String16& inScriptId, const String16& inScriptSource,
861cb0ef41Sopenharmony_ci      Maybe<bool> dryRun,
871cb0ef41Sopenharmony_ci      Maybe<protocol::Array<protocol::Debugger::CallFrame>>* optOutCallFrames,
881cb0ef41Sopenharmony_ci      Maybe<bool>* optOutStackChanged,
891cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::StackTrace>* optOutAsyncStackTrace,
901cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::StackTraceId>* optOutAsyncStackTraceId,
911cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) override;
921cb0ef41Sopenharmony_ci  Response restartFrame(
931cb0ef41Sopenharmony_ci      const String16& callFrameId,
941cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*
951cb0ef41Sopenharmony_ci          newCallFrames,
961cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
971cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) override;
981cb0ef41Sopenharmony_ci  Response getScriptSource(const String16& scriptId, String16* scriptSource,
991cb0ef41Sopenharmony_ci                           Maybe<protocol::Binary>* bytecode) override;
1001cb0ef41Sopenharmony_ci  Response getWasmBytecode(const String16& scriptId,
1011cb0ef41Sopenharmony_ci                           protocol::Binary* bytecode) override;
1021cb0ef41Sopenharmony_ci  Response pause() override;
1031cb0ef41Sopenharmony_ci  Response resume(Maybe<bool> terminateOnResume) override;
1041cb0ef41Sopenharmony_ci  Response stepOver(Maybe<protocol::Array<protocol::Debugger::LocationRange>>
1051cb0ef41Sopenharmony_ci                        inSkipList) override;
1061cb0ef41Sopenharmony_ci  Response stepInto(Maybe<bool> inBreakOnAsyncCall,
1071cb0ef41Sopenharmony_ci                    Maybe<protocol::Array<protocol::Debugger::LocationRange>>
1081cb0ef41Sopenharmony_ci                        inSkipList) override;
1091cb0ef41Sopenharmony_ci  Response stepOut() override;
1101cb0ef41Sopenharmony_ci  Response pauseOnAsyncCall(std::unique_ptr<protocol::Runtime::StackTraceId>
1111cb0ef41Sopenharmony_ci                                inParentStackTraceId) override;
1121cb0ef41Sopenharmony_ci  Response setPauseOnExceptions(const String16& pauseState) override;
1131cb0ef41Sopenharmony_ci  Response evaluateOnCallFrame(
1141cb0ef41Sopenharmony_ci      const String16& callFrameId, const String16& expression,
1151cb0ef41Sopenharmony_ci      Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
1161cb0ef41Sopenharmony_ci      Maybe<bool> silent, Maybe<bool> returnByValue,
1171cb0ef41Sopenharmony_ci      Maybe<bool> generatePreview, Maybe<bool> throwOnSideEffect,
1181cb0ef41Sopenharmony_ci      Maybe<double> timeout,
1191cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::RemoteObject>* result,
1201cb0ef41Sopenharmony_ci      Maybe<protocol::Runtime::ExceptionDetails>*) override;
1211cb0ef41Sopenharmony_ci  Response setVariableValue(
1221cb0ef41Sopenharmony_ci      int scopeNumber, const String16& variableName,
1231cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::CallArgument> newValue,
1241cb0ef41Sopenharmony_ci      const String16& callFrame) override;
1251cb0ef41Sopenharmony_ci  Response setReturnValue(
1261cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::CallArgument> newValue) override;
1271cb0ef41Sopenharmony_ci  Response setAsyncCallStackDepth(int depth) override;
1281cb0ef41Sopenharmony_ci  Response setBlackboxPatterns(
1291cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<String16>> patterns) override;
1301cb0ef41Sopenharmony_ci  Response setBlackboxedRanges(
1311cb0ef41Sopenharmony_ci      const String16& scriptId,
1321cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
1331cb0ef41Sopenharmony_ci          positions) override;
1341cb0ef41Sopenharmony_ci
1351cb0ef41Sopenharmony_ci  bool enabled() const { return m_enabled; }
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  void setBreakpointFor(v8::Local<v8::Function> function,
1381cb0ef41Sopenharmony_ci                        v8::Local<v8::String> condition,
1391cb0ef41Sopenharmony_ci                        BreakpointSource source);
1401cb0ef41Sopenharmony_ci  void removeBreakpointFor(v8::Local<v8::Function> function,
1411cb0ef41Sopenharmony_ci                           BreakpointSource source);
1421cb0ef41Sopenharmony_ci  void schedulePauseOnNextStatement(
1431cb0ef41Sopenharmony_ci      const String16& breakReason,
1441cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::DictionaryValue> data);
1451cb0ef41Sopenharmony_ci  void cancelPauseOnNextStatement();
1461cb0ef41Sopenharmony_ci  void breakProgram(const String16& breakReason,
1471cb0ef41Sopenharmony_ci                    std::unique_ptr<protocol::DictionaryValue> data);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  void reset();
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  // Interface for V8InspectorImpl
1521cb0ef41Sopenharmony_ci  void didPauseOnInstrumentation(v8::debug::BreakpointId instrumentationId);
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci  void didPause(int contextId, v8::Local<v8::Value> exception,
1551cb0ef41Sopenharmony_ci                const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
1561cb0ef41Sopenharmony_ci                v8::debug::ExceptionType exceptionType, bool isUncaught,
1571cb0ef41Sopenharmony_ci                v8::debug::BreakReasons breakReasons);
1581cb0ef41Sopenharmony_ci  void didContinue();
1591cb0ef41Sopenharmony_ci  void didParseSource(std::unique_ptr<V8DebuggerScript>, bool success);
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci  bool isFunctionBlackboxed(const String16& scriptId,
1621cb0ef41Sopenharmony_ci                            const v8::debug::Location& start,
1631cb0ef41Sopenharmony_ci                            const v8::debug::Location& end);
1641cb0ef41Sopenharmony_ci  bool shouldBeSkipped(const String16& scriptId, int line, int column);
1651cb0ef41Sopenharmony_ci
1661cb0ef41Sopenharmony_ci  bool acceptsPause(bool isOOMBreak) const;
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci  void ScriptCollected(const V8DebuggerScript* script);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci  v8::Isolate* isolate() { return m_isolate; }
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci  void clearBreakDetails();
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ci private:
1751cb0ef41Sopenharmony_ci  void enableImpl();
1761cb0ef41Sopenharmony_ci
1771cb0ef41Sopenharmony_ci  Response currentCallFrames(
1781cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Array<protocol::Debugger::CallFrame>>*);
1791cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Runtime::StackTrace> currentAsyncStackTrace();
1801cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Runtime::StackTraceId> currentExternalStackTrace();
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  void setPauseOnExceptionsImpl(int);
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Debugger::Location> setBreakpointImpl(
1851cb0ef41Sopenharmony_ci      const String16& breakpointId, const String16& scriptId,
1861cb0ef41Sopenharmony_ci      const String16& condition, int lineNumber, int columnNumber);
1871cb0ef41Sopenharmony_ci  void setBreakpointImpl(const String16& breakpointId,
1881cb0ef41Sopenharmony_ci                         v8::Local<v8::Function> function,
1891cb0ef41Sopenharmony_ci                         v8::Local<v8::String> condition);
1901cb0ef41Sopenharmony_ci  void removeBreakpointImpl(const String16& breakpointId,
1911cb0ef41Sopenharmony_ci                            const std::vector<V8DebuggerScript*>& scripts);
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci  void internalSetAsyncCallStackDepth(int);
1941cb0ef41Sopenharmony_ci  void increaseCachedSkipStackGeneration();
1951cb0ef41Sopenharmony_ci
1961cb0ef41Sopenharmony_ci  Response setBlackboxPattern(const String16& pattern);
1971cb0ef41Sopenharmony_ci  void resetBlackboxedStateCache();
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci  bool isPaused() const;
2001cb0ef41Sopenharmony_ci
2011cb0ef41Sopenharmony_ci  void setScriptInstrumentationBreakpointIfNeeded(V8DebuggerScript* script);
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  Response processSkipList(
2041cb0ef41Sopenharmony_ci      protocol::Array<protocol::Debugger::LocationRange>* skipList);
2051cb0ef41Sopenharmony_ci
2061cb0ef41Sopenharmony_ci  using ScriptsMap =
2071cb0ef41Sopenharmony_ci      std::unordered_map<String16, std::unique_ptr<V8DebuggerScript>>;
2081cb0ef41Sopenharmony_ci  using BreakpointIdToDebuggerBreakpointIdsMap =
2091cb0ef41Sopenharmony_ci      std::unordered_map<String16, std::vector<v8::debug::BreakpointId>>;
2101cb0ef41Sopenharmony_ci  using DebuggerBreakpointIdToBreakpointIdMap =
2111cb0ef41Sopenharmony_ci      std::unordered_map<v8::debug::BreakpointId, String16>;
2121cb0ef41Sopenharmony_ci
2131cb0ef41Sopenharmony_ci  V8InspectorImpl* m_inspector;
2141cb0ef41Sopenharmony_ci  V8Debugger* m_debugger;
2151cb0ef41Sopenharmony_ci  V8InspectorSessionImpl* m_session;
2161cb0ef41Sopenharmony_ci  bool m_enabled;
2171cb0ef41Sopenharmony_ci  protocol::DictionaryValue* m_state;
2181cb0ef41Sopenharmony_ci  protocol::Debugger::Frontend m_frontend;
2191cb0ef41Sopenharmony_ci  v8::Isolate* m_isolate;
2201cb0ef41Sopenharmony_ci  ScriptsMap m_scripts;
2211cb0ef41Sopenharmony_ci  BreakpointIdToDebuggerBreakpointIdsMap m_breakpointIdToDebuggerBreakpointIds;
2221cb0ef41Sopenharmony_ci  DebuggerBreakpointIdToBreakpointIdMap m_debuggerBreakpointIdToBreakpointId;
2231cb0ef41Sopenharmony_ci  std::unordered_map<v8::debug::BreakpointId,
2241cb0ef41Sopenharmony_ci                     std::unique_ptr<protocol::DictionaryValue>>
2251cb0ef41Sopenharmony_ci      m_breakpointsOnScriptRun;
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci  size_t m_maxScriptCacheSize = 0;
2281cb0ef41Sopenharmony_ci  size_t m_cachedScriptSize = 0;
2291cb0ef41Sopenharmony_ci  struct CachedScript {
2301cb0ef41Sopenharmony_ci    String16 scriptId;
2311cb0ef41Sopenharmony_ci    String16 source;
2321cb0ef41Sopenharmony_ci    std::vector<uint8_t> bytecode;
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci    size_t size() const {
2351cb0ef41Sopenharmony_ci      return source.length() * sizeof(UChar) + bytecode.size();
2361cb0ef41Sopenharmony_ci    }
2371cb0ef41Sopenharmony_ci  };
2381cb0ef41Sopenharmony_ci  std::deque<CachedScript> m_cachedScripts;
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  using BreakReason =
2411cb0ef41Sopenharmony_ci      std::pair<String16, std::unique_ptr<protocol::DictionaryValue>>;
2421cb0ef41Sopenharmony_ci  std::vector<BreakReason> m_breakReason;
2431cb0ef41Sopenharmony_ci
2441cb0ef41Sopenharmony_ci  void pushBreakDetails(
2451cb0ef41Sopenharmony_ci      const String16& breakReason,
2461cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::DictionaryValue> breakAuxData);
2471cb0ef41Sopenharmony_ci  void popBreakDetails();
2481cb0ef41Sopenharmony_ci
2491cb0ef41Sopenharmony_ci  bool m_skipAllPauses = false;
2501cb0ef41Sopenharmony_ci  bool m_breakpointsActive = false;
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  std::unique_ptr<V8Regex> m_blackboxPattern;
2531cb0ef41Sopenharmony_ci  std::unordered_map<String16, std::vector<std::pair<int, int>>>
2541cb0ef41Sopenharmony_ci      m_blackboxedPositions;
2551cb0ef41Sopenharmony_ci  std::unordered_map<String16, std::vector<std::pair<int, int>>> m_skipList;
2561cb0ef41Sopenharmony_ci};
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci}  // namespace v8_inspector
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci#endif  // V8_INSPECTOR_V8_DEBUGGER_AGENT_IMPL_H_
261