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#include "src/inspector/v8-debugger-agent-impl.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include <algorithm>
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ci#include "../../third_party/inspector_protocol/crdtp/json.h"
101cb0ef41Sopenharmony_ci#include "include/v8-context.h"
111cb0ef41Sopenharmony_ci#include "include/v8-function.h"
121cb0ef41Sopenharmony_ci#include "include/v8-inspector.h"
131cb0ef41Sopenharmony_ci#include "include/v8-microtask-queue.h"
141cb0ef41Sopenharmony_ci#include "src/base/safe_conversions.h"
151cb0ef41Sopenharmony_ci#include "src/debug/debug-interface.h"
161cb0ef41Sopenharmony_ci#include "src/inspector/injected-script.h"
171cb0ef41Sopenharmony_ci#include "src/inspector/inspected-context.h"
181cb0ef41Sopenharmony_ci#include "src/inspector/protocol/Debugger.h"
191cb0ef41Sopenharmony_ci#include "src/inspector/protocol/Protocol.h"
201cb0ef41Sopenharmony_ci#include "src/inspector/remote-object-id.h"
211cb0ef41Sopenharmony_ci#include "src/inspector/search-util.h"
221cb0ef41Sopenharmony_ci#include "src/inspector/string-util.h"
231cb0ef41Sopenharmony_ci#include "src/inspector/v8-debugger-script.h"
241cb0ef41Sopenharmony_ci#include "src/inspector/v8-debugger.h"
251cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-impl.h"
261cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-session-impl.h"
271cb0ef41Sopenharmony_ci#include "src/inspector/v8-regex.h"
281cb0ef41Sopenharmony_ci#include "src/inspector/v8-runtime-agent-impl.h"
291cb0ef41Sopenharmony_ci#include "src/inspector/v8-stack-trace-impl.h"
301cb0ef41Sopenharmony_ci#include "src/inspector/v8-value-utils.h"
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_cinamespace v8_inspector {
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciusing protocol::Array;
351cb0ef41Sopenharmony_ciusing protocol::Maybe;
361cb0ef41Sopenharmony_ciusing protocol::Debugger::BreakpointId;
371cb0ef41Sopenharmony_ciusing protocol::Debugger::CallFrame;
381cb0ef41Sopenharmony_ciusing protocol::Debugger::Scope;
391cb0ef41Sopenharmony_ciusing protocol::Runtime::ExceptionDetails;
401cb0ef41Sopenharmony_ciusing protocol::Runtime::RemoteObject;
411cb0ef41Sopenharmony_ciusing protocol::Runtime::ScriptId;
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_cinamespace InstrumentationEnum =
441cb0ef41Sopenharmony_ci    protocol::Debugger::SetInstrumentationBreakpoint::InstrumentationEnum;
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_cinamespace DebuggerAgentState {
471cb0ef41Sopenharmony_cistatic const char pauseOnExceptionsState[] = "pauseOnExceptionsState";
481cb0ef41Sopenharmony_cistatic const char asyncCallStackDepth[] = "asyncCallStackDepth";
491cb0ef41Sopenharmony_cistatic const char blackboxPattern[] = "blackboxPattern";
501cb0ef41Sopenharmony_cistatic const char debuggerEnabled[] = "debuggerEnabled";
511cb0ef41Sopenharmony_cistatic const char skipAllPauses[] = "skipAllPauses";
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_cistatic const char breakpointsByRegex[] = "breakpointsByRegex";
541cb0ef41Sopenharmony_cistatic const char breakpointsByUrl[] = "breakpointsByUrl";
551cb0ef41Sopenharmony_cistatic const char breakpointsByScriptHash[] = "breakpointsByScriptHash";
561cb0ef41Sopenharmony_cistatic const char breakpointHints[] = "breakpointHints";
571cb0ef41Sopenharmony_cistatic const char instrumentationBreakpoints[] = "instrumentationBreakpoints";
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci}  // namespace DebuggerAgentState
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_cistatic const char kBacktraceObjectGroup[] = "backtrace";
621cb0ef41Sopenharmony_cistatic const char kDebuggerNotEnabled[] = "Debugger agent is not enabled";
631cb0ef41Sopenharmony_cistatic const char kDebuggerNotPaused[] =
641cb0ef41Sopenharmony_ci    "Can only perform operation while paused.";
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_cistatic const size_t kBreakpointHintMaxLength = 128;
671cb0ef41Sopenharmony_cistatic const intptr_t kBreakpointHintMaxSearchOffset = 80 * 10;
681cb0ef41Sopenharmony_ci// Limit the number of breakpoints returned, as we otherwise may exceed
691cb0ef41Sopenharmony_ci// the maximum length of a message in mojo (see https://crbug.com/1105172).
701cb0ef41Sopenharmony_cistatic const size_t kMaxNumBreakpoints = 1000;
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
731cb0ef41Sopenharmony_ci// TODO(1099680): getScriptSource and getWasmBytecode return Wasm wire bytes
741cb0ef41Sopenharmony_ci// as protocol::Binary, which is encoded as JSON string in the communication
751cb0ef41Sopenharmony_ci// to the DevTools front-end and hence leads to either crashing the renderer
761cb0ef41Sopenharmony_ci// that is being debugged or the renderer that's running the front-end if we
771cb0ef41Sopenharmony_ci// allow arbitrarily big Wasm byte sequences here. Ideally we would find a
781cb0ef41Sopenharmony_ci// different way to transfer the wire bytes (middle- to long-term), but as a
791cb0ef41Sopenharmony_ci// short-term solution, we should at least not crash.
801cb0ef41Sopenharmony_cistatic constexpr size_t kWasmBytecodeMaxLength =
811cb0ef41Sopenharmony_ci    (v8::String::kMaxLength / 4) * 3;
821cb0ef41Sopenharmony_cistatic constexpr const char kWasmBytecodeExceedsTransferLimit[] =
831cb0ef41Sopenharmony_ci    "WebAssembly bytecode exceeds the transfer limit";
841cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_cinamespace {
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_cienum class BreakpointType {
891cb0ef41Sopenharmony_ci  kByUrl = 1,
901cb0ef41Sopenharmony_ci  kByUrlRegex,
911cb0ef41Sopenharmony_ci  kByScriptHash,
921cb0ef41Sopenharmony_ci  kByScriptId,
931cb0ef41Sopenharmony_ci  kDebugCommand,
941cb0ef41Sopenharmony_ci  kMonitorCommand,
951cb0ef41Sopenharmony_ci  kBreakpointAtEntry,
961cb0ef41Sopenharmony_ci  kInstrumentationBreakpoint
971cb0ef41Sopenharmony_ci};
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ciString16 generateBreakpointId(BreakpointType type,
1001cb0ef41Sopenharmony_ci                              const String16& scriptSelector, int lineNumber,
1011cb0ef41Sopenharmony_ci                              int columnNumber) {
1021cb0ef41Sopenharmony_ci  String16Builder builder;
1031cb0ef41Sopenharmony_ci  builder.appendNumber(static_cast<int>(type));
1041cb0ef41Sopenharmony_ci  builder.append(':');
1051cb0ef41Sopenharmony_ci  builder.appendNumber(lineNumber);
1061cb0ef41Sopenharmony_ci  builder.append(':');
1071cb0ef41Sopenharmony_ci  builder.appendNumber(columnNumber);
1081cb0ef41Sopenharmony_ci  builder.append(':');
1091cb0ef41Sopenharmony_ci  builder.append(scriptSelector);
1101cb0ef41Sopenharmony_ci  return builder.toString();
1111cb0ef41Sopenharmony_ci}
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ciString16 generateBreakpointId(BreakpointType type,
1141cb0ef41Sopenharmony_ci                              v8::Local<v8::Function> function) {
1151cb0ef41Sopenharmony_ci  String16Builder builder;
1161cb0ef41Sopenharmony_ci  builder.appendNumber(static_cast<int>(type));
1171cb0ef41Sopenharmony_ci  builder.append(':');
1181cb0ef41Sopenharmony_ci  builder.appendNumber(v8::debug::GetDebuggingId(function));
1191cb0ef41Sopenharmony_ci  return builder.toString();
1201cb0ef41Sopenharmony_ci}
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ciString16 generateInstrumentationBreakpointId(const String16& instrumentation) {
1231cb0ef41Sopenharmony_ci  String16Builder builder;
1241cb0ef41Sopenharmony_ci  builder.appendNumber(
1251cb0ef41Sopenharmony_ci      static_cast<int>(BreakpointType::kInstrumentationBreakpoint));
1261cb0ef41Sopenharmony_ci  builder.append(':');
1271cb0ef41Sopenharmony_ci  builder.append(instrumentation);
1281cb0ef41Sopenharmony_ci  return builder.toString();
1291cb0ef41Sopenharmony_ci}
1301cb0ef41Sopenharmony_ci
1311cb0ef41Sopenharmony_cibool parseBreakpointId(const String16& breakpointId, BreakpointType* type,
1321cb0ef41Sopenharmony_ci                       String16* scriptSelector = nullptr,
1331cb0ef41Sopenharmony_ci                       int* lineNumber = nullptr, int* columnNumber = nullptr) {
1341cb0ef41Sopenharmony_ci  size_t typeLineSeparator = breakpointId.find(':');
1351cb0ef41Sopenharmony_ci  if (typeLineSeparator == String16::kNotFound) return false;
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  int rawType = breakpointId.substring(0, typeLineSeparator).toInteger();
1381cb0ef41Sopenharmony_ci  if (rawType < static_cast<int>(BreakpointType::kByUrl) ||
1391cb0ef41Sopenharmony_ci      rawType > static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
1401cb0ef41Sopenharmony_ci    return false;
1411cb0ef41Sopenharmony_ci  }
1421cb0ef41Sopenharmony_ci  if (type) *type = static_cast<BreakpointType>(rawType);
1431cb0ef41Sopenharmony_ci  if (rawType == static_cast<int>(BreakpointType::kDebugCommand) ||
1441cb0ef41Sopenharmony_ci      rawType == static_cast<int>(BreakpointType::kMonitorCommand) ||
1451cb0ef41Sopenharmony_ci      rawType == static_cast<int>(BreakpointType::kBreakpointAtEntry) ||
1461cb0ef41Sopenharmony_ci      rawType == static_cast<int>(BreakpointType::kInstrumentationBreakpoint)) {
1471cb0ef41Sopenharmony_ci    // The script and source position are not encoded in this case.
1481cb0ef41Sopenharmony_ci    return true;
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  size_t lineColumnSeparator = breakpointId.find(':', typeLineSeparator + 1);
1521cb0ef41Sopenharmony_ci  if (lineColumnSeparator == String16::kNotFound) return false;
1531cb0ef41Sopenharmony_ci  size_t columnSelectorSeparator =
1541cb0ef41Sopenharmony_ci      breakpointId.find(':', lineColumnSeparator + 1);
1551cb0ef41Sopenharmony_ci  if (columnSelectorSeparator == String16::kNotFound) return false;
1561cb0ef41Sopenharmony_ci  if (scriptSelector) {
1571cb0ef41Sopenharmony_ci    *scriptSelector = breakpointId.substring(columnSelectorSeparator + 1);
1581cb0ef41Sopenharmony_ci  }
1591cb0ef41Sopenharmony_ci  if (lineNumber) {
1601cb0ef41Sopenharmony_ci    *lineNumber = breakpointId
1611cb0ef41Sopenharmony_ci                      .substring(typeLineSeparator + 1,
1621cb0ef41Sopenharmony_ci                                 lineColumnSeparator - typeLineSeparator - 1)
1631cb0ef41Sopenharmony_ci                      .toInteger();
1641cb0ef41Sopenharmony_ci  }
1651cb0ef41Sopenharmony_ci  if (columnNumber) {
1661cb0ef41Sopenharmony_ci    *columnNumber =
1671cb0ef41Sopenharmony_ci        breakpointId
1681cb0ef41Sopenharmony_ci            .substring(lineColumnSeparator + 1,
1691cb0ef41Sopenharmony_ci                       columnSelectorSeparator - lineColumnSeparator - 1)
1701cb0ef41Sopenharmony_ci            .toInteger();
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci  return true;
1731cb0ef41Sopenharmony_ci}
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_cibool positionComparator(const std::pair<int, int>& a,
1761cb0ef41Sopenharmony_ci                        const std::pair<int, int>& b) {
1771cb0ef41Sopenharmony_ci  if (a.first != b.first) return a.first < b.first;
1781cb0ef41Sopenharmony_ci  return a.second < b.second;
1791cb0ef41Sopenharmony_ci}
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ciString16 breakpointHint(const V8DebuggerScript& script, int lineNumber,
1821cb0ef41Sopenharmony_ci                        int columnNumber) {
1831cb0ef41Sopenharmony_ci  int offset = script.offset(lineNumber, columnNumber);
1841cb0ef41Sopenharmony_ci  if (offset == V8DebuggerScript::kNoOffset) return String16();
1851cb0ef41Sopenharmony_ci  String16 hint =
1861cb0ef41Sopenharmony_ci      script.source(offset, kBreakpointHintMaxLength).stripWhiteSpace();
1871cb0ef41Sopenharmony_ci  for (size_t i = 0; i < hint.length(); ++i) {
1881cb0ef41Sopenharmony_ci    if (hint[i] == '\r' || hint[i] == '\n' || hint[i] == ';') {
1891cb0ef41Sopenharmony_ci      return hint.substring(0, i);
1901cb0ef41Sopenharmony_ci    }
1911cb0ef41Sopenharmony_ci  }
1921cb0ef41Sopenharmony_ci  return hint;
1931cb0ef41Sopenharmony_ci}
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_civoid adjustBreakpointLocation(const V8DebuggerScript& script,
1961cb0ef41Sopenharmony_ci                              const String16& hint, int* lineNumber,
1971cb0ef41Sopenharmony_ci                              int* columnNumber) {
1981cb0ef41Sopenharmony_ci  if (*lineNumber < script.startLine() || *lineNumber > script.endLine())
1991cb0ef41Sopenharmony_ci    return;
2001cb0ef41Sopenharmony_ci  if (*lineNumber == script.startLine() &&
2011cb0ef41Sopenharmony_ci      *columnNumber < script.startColumn()) {
2021cb0ef41Sopenharmony_ci    return;
2031cb0ef41Sopenharmony_ci  }
2041cb0ef41Sopenharmony_ci  if (*lineNumber == script.endLine() && script.endColumn() < *columnNumber) {
2051cb0ef41Sopenharmony_ci    return;
2061cb0ef41Sopenharmony_ci  }
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  if (hint.isEmpty()) return;
2091cb0ef41Sopenharmony_ci  intptr_t sourceOffset = script.offset(*lineNumber, *columnNumber);
2101cb0ef41Sopenharmony_ci  if (sourceOffset == V8DebuggerScript::kNoOffset) return;
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  intptr_t searchRegionOffset = std::max(
2131cb0ef41Sopenharmony_ci      sourceOffset - kBreakpointHintMaxSearchOffset, static_cast<intptr_t>(0));
2141cb0ef41Sopenharmony_ci  size_t offset = sourceOffset - searchRegionOffset;
2151cb0ef41Sopenharmony_ci  String16 searchArea = script.source(searchRegionOffset,
2161cb0ef41Sopenharmony_ci                                      offset + kBreakpointHintMaxSearchOffset);
2171cb0ef41Sopenharmony_ci
2181cb0ef41Sopenharmony_ci  size_t nextMatch = searchArea.find(hint, offset);
2191cb0ef41Sopenharmony_ci  size_t prevMatch = searchArea.reverseFind(hint, offset);
2201cb0ef41Sopenharmony_ci  if (nextMatch == String16::kNotFound && prevMatch == String16::kNotFound) {
2211cb0ef41Sopenharmony_ci    return;
2221cb0ef41Sopenharmony_ci  }
2231cb0ef41Sopenharmony_ci  size_t bestMatch;
2241cb0ef41Sopenharmony_ci  if (nextMatch == String16::kNotFound) {
2251cb0ef41Sopenharmony_ci    bestMatch = prevMatch;
2261cb0ef41Sopenharmony_ci  } else if (prevMatch == String16::kNotFound) {
2271cb0ef41Sopenharmony_ci    bestMatch = nextMatch;
2281cb0ef41Sopenharmony_ci  } else {
2291cb0ef41Sopenharmony_ci    bestMatch = nextMatch - offset < offset - prevMatch ? nextMatch : prevMatch;
2301cb0ef41Sopenharmony_ci  }
2311cb0ef41Sopenharmony_ci  bestMatch += searchRegionOffset;
2321cb0ef41Sopenharmony_ci  v8::debug::Location hintPosition =
2331cb0ef41Sopenharmony_ci      script.location(static_cast<int>(bestMatch));
2341cb0ef41Sopenharmony_ci  if (hintPosition.IsEmpty()) return;
2351cb0ef41Sopenharmony_ci  *lineNumber = hintPosition.GetLineNumber();
2361cb0ef41Sopenharmony_ci  *columnNumber = hintPosition.GetColumnNumber();
2371cb0ef41Sopenharmony_ci}
2381cb0ef41Sopenharmony_ci
2391cb0ef41Sopenharmony_ciString16 breakLocationType(v8::debug::BreakLocationType type) {
2401cb0ef41Sopenharmony_ci  switch (type) {
2411cb0ef41Sopenharmony_ci    case v8::debug::kCallBreakLocation:
2421cb0ef41Sopenharmony_ci      return protocol::Debugger::BreakLocation::TypeEnum::Call;
2431cb0ef41Sopenharmony_ci    case v8::debug::kReturnBreakLocation:
2441cb0ef41Sopenharmony_ci      return protocol::Debugger::BreakLocation::TypeEnum::Return;
2451cb0ef41Sopenharmony_ci    case v8::debug::kDebuggerStatementBreakLocation:
2461cb0ef41Sopenharmony_ci      return protocol::Debugger::BreakLocation::TypeEnum::DebuggerStatement;
2471cb0ef41Sopenharmony_ci    case v8::debug::kCommonBreakLocation:
2481cb0ef41Sopenharmony_ci      return String16();
2491cb0ef41Sopenharmony_ci  }
2501cb0ef41Sopenharmony_ci  return String16();
2511cb0ef41Sopenharmony_ci}
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ciString16 scopeType(v8::debug::ScopeIterator::ScopeType type) {
2541cb0ef41Sopenharmony_ci  switch (type) {
2551cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeGlobal:
2561cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Global;
2571cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeLocal:
2581cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Local;
2591cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeWith:
2601cb0ef41Sopenharmony_ci      return Scope::TypeEnum::With;
2611cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeClosure:
2621cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Closure;
2631cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeCatch:
2641cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Catch;
2651cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeBlock:
2661cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Block;
2671cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeScript:
2681cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Script;
2691cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeEval:
2701cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Eval;
2711cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeModule:
2721cb0ef41Sopenharmony_ci      return Scope::TypeEnum::Module;
2731cb0ef41Sopenharmony_ci    case v8::debug::ScopeIterator::ScopeTypeWasmExpressionStack:
2741cb0ef41Sopenharmony_ci      return Scope::TypeEnum::WasmExpressionStack;
2751cb0ef41Sopenharmony_ci  }
2761cb0ef41Sopenharmony_ci  UNREACHABLE();
2771cb0ef41Sopenharmony_ci}
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ciResponse buildScopes(v8::Isolate* isolate, v8::debug::ScopeIterator* iterator,
2801cb0ef41Sopenharmony_ci                     InjectedScript* injectedScript,
2811cb0ef41Sopenharmony_ci                     std::unique_ptr<Array<Scope>>* scopes) {
2821cb0ef41Sopenharmony_ci  *scopes = std::make_unique<Array<Scope>>();
2831cb0ef41Sopenharmony_ci  if (!injectedScript) return Response::Success();
2841cb0ef41Sopenharmony_ci  if (iterator->Done()) return Response::Success();
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ci  String16 scriptId = String16::fromInteger(iterator->GetScriptId());
2871cb0ef41Sopenharmony_ci
2881cb0ef41Sopenharmony_ci  for (; !iterator->Done(); iterator->Advance()) {
2891cb0ef41Sopenharmony_ci    std::unique_ptr<RemoteObject> object;
2901cb0ef41Sopenharmony_ci    Response result =
2911cb0ef41Sopenharmony_ci        injectedScript->wrapObject(iterator->GetObject(), kBacktraceObjectGroup,
2921cb0ef41Sopenharmony_ci                                   WrapMode::kNoPreview, &object);
2931cb0ef41Sopenharmony_ci    if (!result.IsSuccess()) return result;
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci    auto scope = Scope::create()
2961cb0ef41Sopenharmony_ci                     .setType(scopeType(iterator->GetType()))
2971cb0ef41Sopenharmony_ci                     .setObject(std::move(object))
2981cb0ef41Sopenharmony_ci                     .build();
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci    String16 name = toProtocolStringWithTypeCheck(
3011cb0ef41Sopenharmony_ci        isolate, iterator->GetFunctionDebugName());
3021cb0ef41Sopenharmony_ci    if (!name.isEmpty()) scope->setName(name);
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci    if (iterator->HasLocationInfo()) {
3051cb0ef41Sopenharmony_ci      v8::debug::Location start = iterator->GetStartLocation();
3061cb0ef41Sopenharmony_ci      scope->setStartLocation(protocol::Debugger::Location::create()
3071cb0ef41Sopenharmony_ci                                  .setScriptId(scriptId)
3081cb0ef41Sopenharmony_ci                                  .setLineNumber(start.GetLineNumber())
3091cb0ef41Sopenharmony_ci                                  .setColumnNumber(start.GetColumnNumber())
3101cb0ef41Sopenharmony_ci                                  .build());
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci      v8::debug::Location end = iterator->GetEndLocation();
3131cb0ef41Sopenharmony_ci      scope->setEndLocation(protocol::Debugger::Location::create()
3141cb0ef41Sopenharmony_ci                                .setScriptId(scriptId)
3151cb0ef41Sopenharmony_ci                                .setLineNumber(end.GetLineNumber())
3161cb0ef41Sopenharmony_ci                                .setColumnNumber(end.GetColumnNumber())
3171cb0ef41Sopenharmony_ci                                .build());
3181cb0ef41Sopenharmony_ci    }
3191cb0ef41Sopenharmony_ci    (*scopes)->emplace_back(std::move(scope));
3201cb0ef41Sopenharmony_ci  }
3211cb0ef41Sopenharmony_ci  return Response::Success();
3221cb0ef41Sopenharmony_ci}
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ciprotocol::DictionaryValue* getOrCreateObject(protocol::DictionaryValue* object,
3251cb0ef41Sopenharmony_ci                                             const String16& key) {
3261cb0ef41Sopenharmony_ci  protocol::DictionaryValue* value = object->getObject(key);
3271cb0ef41Sopenharmony_ci  if (value) return value;
3281cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::DictionaryValue> newDictionary =
3291cb0ef41Sopenharmony_ci      protocol::DictionaryValue::create();
3301cb0ef41Sopenharmony_ci  value = newDictionary.get();
3311cb0ef41Sopenharmony_ci  object->setObject(key, std::move(newDictionary));
3321cb0ef41Sopenharmony_ci  return value;
3331cb0ef41Sopenharmony_ci}
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ciResponse isValidPosition(protocol::Debugger::ScriptPosition* position) {
3361cb0ef41Sopenharmony_ci  if (position->getLineNumber() < 0)
3371cb0ef41Sopenharmony_ci    return Response::ServerError("Position missing 'line' or 'line' < 0.");
3381cb0ef41Sopenharmony_ci  if (position->getColumnNumber() < 0)
3391cb0ef41Sopenharmony_ci    return Response::ServerError("Position missing 'column' or 'column' < 0.");
3401cb0ef41Sopenharmony_ci  return Response::Success();
3411cb0ef41Sopenharmony_ci}
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ciResponse isValidRangeOfPositions(std::vector<std::pair<int, int>>& positions) {
3441cb0ef41Sopenharmony_ci  for (size_t i = 1; i < positions.size(); ++i) {
3451cb0ef41Sopenharmony_ci    if (positions[i - 1].first < positions[i].first) continue;
3461cb0ef41Sopenharmony_ci    if (positions[i - 1].first == positions[i].first &&
3471cb0ef41Sopenharmony_ci        positions[i - 1].second < positions[i].second)
3481cb0ef41Sopenharmony_ci      continue;
3491cb0ef41Sopenharmony_ci    return Response::ServerError(
3501cb0ef41Sopenharmony_ci        "Input positions array is not sorted or contains duplicate values.");
3511cb0ef41Sopenharmony_ci  }
3521cb0ef41Sopenharmony_ci  return Response::Success();
3531cb0ef41Sopenharmony_ci}
3541cb0ef41Sopenharmony_ci
3551cb0ef41Sopenharmony_cibool hitBreakReasonEncodedAsOther(v8::debug::BreakReasons breakReasons) {
3561cb0ef41Sopenharmony_ci  // The listed break reasons are not explicitly encoded in CDP when
3571cb0ef41Sopenharmony_ci  // reporting the break. They are summarized as 'other'.
3581cb0ef41Sopenharmony_ci  v8::debug::BreakReasons otherBreakReasons(
3591cb0ef41Sopenharmony_ci      {v8::debug::BreakReason::kStep,
3601cb0ef41Sopenharmony_ci       v8::debug::BreakReason::kDebuggerStatement,
3611cb0ef41Sopenharmony_ci       v8::debug::BreakReason::kScheduled, v8::debug::BreakReason::kAsyncStep,
3621cb0ef41Sopenharmony_ci       v8::debug::BreakReason::kAlreadyPaused});
3631cb0ef41Sopenharmony_ci  return breakReasons.contains_any(otherBreakReasons);
3641cb0ef41Sopenharmony_ci}
3651cb0ef41Sopenharmony_ci}  // namespace
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ciV8DebuggerAgentImpl::V8DebuggerAgentImpl(
3681cb0ef41Sopenharmony_ci    V8InspectorSessionImpl* session, protocol::FrontendChannel* frontendChannel,
3691cb0ef41Sopenharmony_ci    protocol::DictionaryValue* state)
3701cb0ef41Sopenharmony_ci    : m_inspector(session->inspector()),
3711cb0ef41Sopenharmony_ci      m_debugger(m_inspector->debugger()),
3721cb0ef41Sopenharmony_ci      m_session(session),
3731cb0ef41Sopenharmony_ci      m_enabled(false),
3741cb0ef41Sopenharmony_ci      m_state(state),
3751cb0ef41Sopenharmony_ci      m_frontend(frontendChannel),
3761cb0ef41Sopenharmony_ci      m_isolate(m_inspector->isolate()) {}
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ciV8DebuggerAgentImpl::~V8DebuggerAgentImpl() = default;
3791cb0ef41Sopenharmony_ci
3801cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::enableImpl() {
3811cb0ef41Sopenharmony_ci  m_enabled = true;
3821cb0ef41Sopenharmony_ci  m_state->setBoolean(DebuggerAgentState::debuggerEnabled, true);
3831cb0ef41Sopenharmony_ci  m_debugger->enable();
3841cb0ef41Sopenharmony_ci
3851cb0ef41Sopenharmony_ci  std::vector<std::unique_ptr<V8DebuggerScript>> compiledScripts =
3861cb0ef41Sopenharmony_ci      m_debugger->getCompiledScripts(m_session->contextGroupId(), this);
3871cb0ef41Sopenharmony_ci  for (auto& script : compiledScripts) {
3881cb0ef41Sopenharmony_ci    didParseSource(std::move(script), true);
3891cb0ef41Sopenharmony_ci  }
3901cb0ef41Sopenharmony_ci
3911cb0ef41Sopenharmony_ci  m_breakpointsActive = true;
3921cb0ef41Sopenharmony_ci  m_debugger->setBreakpointsActive(true);
3931cb0ef41Sopenharmony_ci
3941cb0ef41Sopenharmony_ci  if (isPaused()) {
3951cb0ef41Sopenharmony_ci    didPause(0, v8::Local<v8::Value>(), std::vector<v8::debug::BreakpointId>(),
3961cb0ef41Sopenharmony_ci             v8::debug::kException, false,
3971cb0ef41Sopenharmony_ci             v8::debug::BreakReasons({v8::debug::BreakReason::kAlreadyPaused}));
3981cb0ef41Sopenharmony_ci  }
3991cb0ef41Sopenharmony_ci}
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::enable(Maybe<double> maxScriptsCacheSize,
4021cb0ef41Sopenharmony_ci                                     String16* outDebuggerId) {
4031cb0ef41Sopenharmony_ci  m_maxScriptCacheSize = v8::base::saturated_cast<size_t>(
4041cb0ef41Sopenharmony_ci      maxScriptsCacheSize.fromMaybe(std::numeric_limits<double>::max()));
4051cb0ef41Sopenharmony_ci  *outDebuggerId =
4061cb0ef41Sopenharmony_ci      m_debugger->debuggerIdFor(m_session->contextGroupId()).toString();
4071cb0ef41Sopenharmony_ci  if (enabled()) return Response::Success();
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_ci  if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
4101cb0ef41Sopenharmony_ci    return Response::ServerError("Script execution is prohibited");
4111cb0ef41Sopenharmony_ci
4121cb0ef41Sopenharmony_ci  enableImpl();
4131cb0ef41Sopenharmony_ci  return Response::Success();
4141cb0ef41Sopenharmony_ci}
4151cb0ef41Sopenharmony_ci
4161cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::disable() {
4171cb0ef41Sopenharmony_ci  if (!enabled()) return Response::Success();
4181cb0ef41Sopenharmony_ci
4191cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::breakpointsByRegex);
4201cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::breakpointsByUrl);
4211cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::breakpointsByScriptHash);
4221cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::breakpointHints);
4231cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::instrumentationBreakpoints);
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ci  m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState,
4261cb0ef41Sopenharmony_ci                      v8::debug::NoBreakOnException);
4271cb0ef41Sopenharmony_ci  m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, 0);
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci  if (m_breakpointsActive) {
4301cb0ef41Sopenharmony_ci    m_debugger->setBreakpointsActive(false);
4311cb0ef41Sopenharmony_ci    m_breakpointsActive = false;
4321cb0ef41Sopenharmony_ci  }
4331cb0ef41Sopenharmony_ci  m_blackboxedPositions.clear();
4341cb0ef41Sopenharmony_ci  m_blackboxPattern.reset();
4351cb0ef41Sopenharmony_ci  resetBlackboxedStateCache();
4361cb0ef41Sopenharmony_ci  m_skipList.clear();
4371cb0ef41Sopenharmony_ci  m_scripts.clear();
4381cb0ef41Sopenharmony_ci  m_cachedScripts.clear();
4391cb0ef41Sopenharmony_ci  m_cachedScriptSize = 0;
4401cb0ef41Sopenharmony_ci  for (const auto& it : m_debuggerBreakpointIdToBreakpointId) {
4411cb0ef41Sopenharmony_ci    v8::debug::RemoveBreakpoint(m_isolate, it.first);
4421cb0ef41Sopenharmony_ci  }
4431cb0ef41Sopenharmony_ci  m_breakpointIdToDebuggerBreakpointIds.clear();
4441cb0ef41Sopenharmony_ci  m_debuggerBreakpointIdToBreakpointId.clear();
4451cb0ef41Sopenharmony_ci  m_debugger->setAsyncCallStackDepth(this, 0);
4461cb0ef41Sopenharmony_ci  clearBreakDetails();
4471cb0ef41Sopenharmony_ci  m_skipAllPauses = false;
4481cb0ef41Sopenharmony_ci  m_state->setBoolean(DebuggerAgentState::skipAllPauses, false);
4491cb0ef41Sopenharmony_ci  m_state->remove(DebuggerAgentState::blackboxPattern);
4501cb0ef41Sopenharmony_ci  m_enabled = false;
4511cb0ef41Sopenharmony_ci  m_state->setBoolean(DebuggerAgentState::debuggerEnabled, false);
4521cb0ef41Sopenharmony_ci  m_debugger->disable();
4531cb0ef41Sopenharmony_ci  return Response::Success();
4541cb0ef41Sopenharmony_ci}
4551cb0ef41Sopenharmony_ci
4561cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::restore() {
4571cb0ef41Sopenharmony_ci  DCHECK(!m_enabled);
4581cb0ef41Sopenharmony_ci  if (!m_state->booleanProperty(DebuggerAgentState::debuggerEnabled, false))
4591cb0ef41Sopenharmony_ci    return;
4601cb0ef41Sopenharmony_ci  if (!m_inspector->client()->canExecuteScripts(m_session->contextGroupId()))
4611cb0ef41Sopenharmony_ci    return;
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci  enableImpl();
4641cb0ef41Sopenharmony_ci
4651cb0ef41Sopenharmony_ci  int pauseState = v8::debug::NoBreakOnException;
4661cb0ef41Sopenharmony_ci  m_state->getInteger(DebuggerAgentState::pauseOnExceptionsState, &pauseState);
4671cb0ef41Sopenharmony_ci  setPauseOnExceptionsImpl(pauseState);
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  m_skipAllPauses =
4701cb0ef41Sopenharmony_ci      m_state->booleanProperty(DebuggerAgentState::skipAllPauses, false);
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci  int asyncCallStackDepth = 0;
4731cb0ef41Sopenharmony_ci  m_state->getInteger(DebuggerAgentState::asyncCallStackDepth,
4741cb0ef41Sopenharmony_ci                      &asyncCallStackDepth);
4751cb0ef41Sopenharmony_ci  m_debugger->setAsyncCallStackDepth(this, asyncCallStackDepth);
4761cb0ef41Sopenharmony_ci
4771cb0ef41Sopenharmony_ci  String16 blackboxPattern;
4781cb0ef41Sopenharmony_ci  if (m_state->getString(DebuggerAgentState::blackboxPattern,
4791cb0ef41Sopenharmony_ci                         &blackboxPattern)) {
4801cb0ef41Sopenharmony_ci    setBlackboxPattern(blackboxPattern);
4811cb0ef41Sopenharmony_ci  }
4821cb0ef41Sopenharmony_ci}
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBreakpointsActive(bool active) {
4851cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
4861cb0ef41Sopenharmony_ci  if (m_breakpointsActive == active) return Response::Success();
4871cb0ef41Sopenharmony_ci  m_breakpointsActive = active;
4881cb0ef41Sopenharmony_ci  m_debugger->setBreakpointsActive(active);
4891cb0ef41Sopenharmony_ci  if (!active && !m_breakReason.empty()) {
4901cb0ef41Sopenharmony_ci    clearBreakDetails();
4911cb0ef41Sopenharmony_ci    m_debugger->setPauseOnNextCall(false, m_session->contextGroupId());
4921cb0ef41Sopenharmony_ci  }
4931cb0ef41Sopenharmony_ci  return Response::Success();
4941cb0ef41Sopenharmony_ci}
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setSkipAllPauses(bool skip) {
4971cb0ef41Sopenharmony_ci  m_state->setBoolean(DebuggerAgentState::skipAllPauses, skip);
4981cb0ef41Sopenharmony_ci  m_skipAllPauses = skip;
4991cb0ef41Sopenharmony_ci  return Response::Success();
5001cb0ef41Sopenharmony_ci}
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_cistatic bool matches(V8InspectorImpl* inspector, const V8DebuggerScript& script,
5031cb0ef41Sopenharmony_ci                    BreakpointType type, const String16& selector) {
5041cb0ef41Sopenharmony_ci  switch (type) {
5051cb0ef41Sopenharmony_ci    case BreakpointType::kByUrl:
5061cb0ef41Sopenharmony_ci      return script.sourceURL() == selector;
5071cb0ef41Sopenharmony_ci    case BreakpointType::kByScriptHash:
5081cb0ef41Sopenharmony_ci      return script.hash() == selector;
5091cb0ef41Sopenharmony_ci    case BreakpointType::kByUrlRegex: {
5101cb0ef41Sopenharmony_ci      V8Regex regex(inspector, selector, true);
5111cb0ef41Sopenharmony_ci      return regex.match(script.sourceURL()) != -1;
5121cb0ef41Sopenharmony_ci    }
5131cb0ef41Sopenharmony_ci    case BreakpointType::kByScriptId: {
5141cb0ef41Sopenharmony_ci      return script.scriptId() == selector;
5151cb0ef41Sopenharmony_ci    }
5161cb0ef41Sopenharmony_ci    default:
5171cb0ef41Sopenharmony_ci      return false;
5181cb0ef41Sopenharmony_ci  }
5191cb0ef41Sopenharmony_ci}
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBreakpointByUrl(
5221cb0ef41Sopenharmony_ci    int lineNumber, Maybe<String16> optionalURL,
5231cb0ef41Sopenharmony_ci    Maybe<String16> optionalURLRegex, Maybe<String16> optionalScriptHash,
5241cb0ef41Sopenharmony_ci    Maybe<int> optionalColumnNumber, Maybe<String16> optionalCondition,
5251cb0ef41Sopenharmony_ci    String16* outBreakpointId,
5261cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Array<protocol::Debugger::Location>>* locations) {
5271cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  *locations = std::make_unique<Array<protocol::Debugger::Location>>();
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci  int specified = (optionalURL.isJust() ? 1 : 0) +
5321cb0ef41Sopenharmony_ci                  (optionalURLRegex.isJust() ? 1 : 0) +
5331cb0ef41Sopenharmony_ci                  (optionalScriptHash.isJust() ? 1 : 0);
5341cb0ef41Sopenharmony_ci  if (specified != 1) {
5351cb0ef41Sopenharmony_ci    return Response::ServerError(
5361cb0ef41Sopenharmony_ci        "Either url or urlRegex or scriptHash must be specified.");
5371cb0ef41Sopenharmony_ci  }
5381cb0ef41Sopenharmony_ci  int columnNumber = 0;
5391cb0ef41Sopenharmony_ci  if (optionalColumnNumber.isJust()) {
5401cb0ef41Sopenharmony_ci    columnNumber = optionalColumnNumber.fromJust();
5411cb0ef41Sopenharmony_ci    if (columnNumber < 0)
5421cb0ef41Sopenharmony_ci      return Response::ServerError("Incorrect column number");
5431cb0ef41Sopenharmony_ci  }
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci  BreakpointType type = BreakpointType::kByUrl;
5461cb0ef41Sopenharmony_ci  String16 selector;
5471cb0ef41Sopenharmony_ci  if (optionalURLRegex.isJust()) {
5481cb0ef41Sopenharmony_ci    selector = optionalURLRegex.fromJust();
5491cb0ef41Sopenharmony_ci    type = BreakpointType::kByUrlRegex;
5501cb0ef41Sopenharmony_ci  } else if (optionalURL.isJust()) {
5511cb0ef41Sopenharmony_ci    selector = optionalURL.fromJust();
5521cb0ef41Sopenharmony_ci    type = BreakpointType::kByUrl;
5531cb0ef41Sopenharmony_ci  } else if (optionalScriptHash.isJust()) {
5541cb0ef41Sopenharmony_ci    selector = optionalScriptHash.fromJust();
5551cb0ef41Sopenharmony_ci    type = BreakpointType::kByScriptHash;
5561cb0ef41Sopenharmony_ci  }
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_ci  String16 condition = optionalCondition.fromMaybe(String16());
5591cb0ef41Sopenharmony_ci  String16 breakpointId =
5601cb0ef41Sopenharmony_ci      generateBreakpointId(type, selector, lineNumber, columnNumber);
5611cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpoints;
5621cb0ef41Sopenharmony_ci  switch (type) {
5631cb0ef41Sopenharmony_ci    case BreakpointType::kByUrlRegex:
5641cb0ef41Sopenharmony_ci      breakpoints =
5651cb0ef41Sopenharmony_ci          getOrCreateObject(m_state, DebuggerAgentState::breakpointsByRegex);
5661cb0ef41Sopenharmony_ci      break;
5671cb0ef41Sopenharmony_ci    case BreakpointType::kByUrl:
5681cb0ef41Sopenharmony_ci      breakpoints = getOrCreateObject(
5691cb0ef41Sopenharmony_ci          getOrCreateObject(m_state, DebuggerAgentState::breakpointsByUrl),
5701cb0ef41Sopenharmony_ci          selector);
5711cb0ef41Sopenharmony_ci      break;
5721cb0ef41Sopenharmony_ci    case BreakpointType::kByScriptHash:
5731cb0ef41Sopenharmony_ci      breakpoints = getOrCreateObject(
5741cb0ef41Sopenharmony_ci          getOrCreateObject(m_state,
5751cb0ef41Sopenharmony_ci                            DebuggerAgentState::breakpointsByScriptHash),
5761cb0ef41Sopenharmony_ci          selector);
5771cb0ef41Sopenharmony_ci      break;
5781cb0ef41Sopenharmony_ci    default:
5791cb0ef41Sopenharmony_ci      UNREACHABLE();
5801cb0ef41Sopenharmony_ci  }
5811cb0ef41Sopenharmony_ci  if (breakpoints->get(breakpointId)) {
5821cb0ef41Sopenharmony_ci    return Response::ServerError(
5831cb0ef41Sopenharmony_ci        "Breakpoint at specified location already exists.");
5841cb0ef41Sopenharmony_ci  }
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci  String16 hint;
5871cb0ef41Sopenharmony_ci  for (const auto& script : m_scripts) {
5881cb0ef41Sopenharmony_ci    if (!matches(m_inspector, *script.second, type, selector)) continue;
5891cb0ef41Sopenharmony_ci    if (!hint.isEmpty()) {
5901cb0ef41Sopenharmony_ci      adjustBreakpointLocation(*script.second, hint, &lineNumber,
5911cb0ef41Sopenharmony_ci                               &columnNumber);
5921cb0ef41Sopenharmony_ci    }
5931cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location> location = setBreakpointImpl(
5941cb0ef41Sopenharmony_ci        breakpointId, script.first, condition, lineNumber, columnNumber);
5951cb0ef41Sopenharmony_ci    if (location && type != BreakpointType::kByUrlRegex) {
5961cb0ef41Sopenharmony_ci      hint = breakpointHint(*script.second, location->getLineNumber(),
5971cb0ef41Sopenharmony_ci                            location->getColumnNumber(columnNumber));
5981cb0ef41Sopenharmony_ci    }
5991cb0ef41Sopenharmony_ci    if (location) (*locations)->emplace_back(std::move(location));
6001cb0ef41Sopenharmony_ci  }
6011cb0ef41Sopenharmony_ci  breakpoints->setString(breakpointId, condition);
6021cb0ef41Sopenharmony_ci  if (!hint.isEmpty()) {
6031cb0ef41Sopenharmony_ci    protocol::DictionaryValue* breakpointHints =
6041cb0ef41Sopenharmony_ci        getOrCreateObject(m_state, DebuggerAgentState::breakpointHints);
6051cb0ef41Sopenharmony_ci    breakpointHints->setString(breakpointId, hint);
6061cb0ef41Sopenharmony_ci  }
6071cb0ef41Sopenharmony_ci  *outBreakpointId = breakpointId;
6081cb0ef41Sopenharmony_ci  return Response::Success();
6091cb0ef41Sopenharmony_ci}
6101cb0ef41Sopenharmony_ci
6111cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBreakpoint(
6121cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location> location,
6131cb0ef41Sopenharmony_ci    Maybe<String16> optionalCondition, String16* outBreakpointId,
6141cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location>* actualLocation) {
6151cb0ef41Sopenharmony_ci  String16 breakpointId = generateBreakpointId(
6161cb0ef41Sopenharmony_ci      BreakpointType::kByScriptId, location->getScriptId(),
6171cb0ef41Sopenharmony_ci      location->getLineNumber(), location->getColumnNumber(0));
6181cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci  if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
6211cb0ef41Sopenharmony_ci      m_breakpointIdToDebuggerBreakpointIds.end()) {
6221cb0ef41Sopenharmony_ci    return Response::ServerError(
6231cb0ef41Sopenharmony_ci        "Breakpoint at specified location already exists.");
6241cb0ef41Sopenharmony_ci  }
6251cb0ef41Sopenharmony_ci  *actualLocation = setBreakpointImpl(breakpointId, location->getScriptId(),
6261cb0ef41Sopenharmony_ci                                      optionalCondition.fromMaybe(String16()),
6271cb0ef41Sopenharmony_ci                                      location->getLineNumber(),
6281cb0ef41Sopenharmony_ci                                      location->getColumnNumber(0));
6291cb0ef41Sopenharmony_ci  if (!*actualLocation)
6301cb0ef41Sopenharmony_ci    return Response::ServerError("Could not resolve breakpoint");
6311cb0ef41Sopenharmony_ci  *outBreakpointId = breakpointId;
6321cb0ef41Sopenharmony_ci  return Response::Success();
6331cb0ef41Sopenharmony_ci}
6341cb0ef41Sopenharmony_ci
6351cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBreakpointOnFunctionCall(
6361cb0ef41Sopenharmony_ci    const String16& functionObjectId, Maybe<String16> optionalCondition,
6371cb0ef41Sopenharmony_ci    String16* outBreakpointId) {
6381cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ci  InjectedScript::ObjectScope scope(m_session, functionObjectId);
6411cb0ef41Sopenharmony_ci  Response response = scope.initialize();
6421cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
6431cb0ef41Sopenharmony_ci  if (!scope.object()->IsFunction()) {
6441cb0ef41Sopenharmony_ci    return Response::ServerError("Could not find function with given id");
6451cb0ef41Sopenharmony_ci  }
6461cb0ef41Sopenharmony_ci  v8::Local<v8::Function> function =
6471cb0ef41Sopenharmony_ci      v8::Local<v8::Function>::Cast(scope.object());
6481cb0ef41Sopenharmony_ci  String16 breakpointId =
6491cb0ef41Sopenharmony_ci      generateBreakpointId(BreakpointType::kBreakpointAtEntry, function);
6501cb0ef41Sopenharmony_ci  if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
6511cb0ef41Sopenharmony_ci      m_breakpointIdToDebuggerBreakpointIds.end()) {
6521cb0ef41Sopenharmony_ci    return Response::ServerError(
6531cb0ef41Sopenharmony_ci        "Breakpoint at specified location already exists.");
6541cb0ef41Sopenharmony_ci  }
6551cb0ef41Sopenharmony_ci  v8::Local<v8::String> condition =
6561cb0ef41Sopenharmony_ci      toV8String(m_isolate, optionalCondition.fromMaybe(String16()));
6571cb0ef41Sopenharmony_ci  setBreakpointImpl(breakpointId, function, condition);
6581cb0ef41Sopenharmony_ci  *outBreakpointId = breakpointId;
6591cb0ef41Sopenharmony_ci  return Response::Success();
6601cb0ef41Sopenharmony_ci}
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setInstrumentationBreakpoint(
6631cb0ef41Sopenharmony_ci    const String16& instrumentation, String16* outBreakpointId) {
6641cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
6651cb0ef41Sopenharmony_ci  String16 breakpointId = generateInstrumentationBreakpointId(instrumentation);
6661cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpoints = getOrCreateObject(
6671cb0ef41Sopenharmony_ci      m_state, DebuggerAgentState::instrumentationBreakpoints);
6681cb0ef41Sopenharmony_ci  if (breakpoints->get(breakpointId)) {
6691cb0ef41Sopenharmony_ci    return Response::ServerError(
6701cb0ef41Sopenharmony_ci        "Instrumentation breakpoint is already enabled.");
6711cb0ef41Sopenharmony_ci  }
6721cb0ef41Sopenharmony_ci  breakpoints->setBoolean(breakpointId, true);
6731cb0ef41Sopenharmony_ci  *outBreakpointId = breakpointId;
6741cb0ef41Sopenharmony_ci  return Response::Success();
6751cb0ef41Sopenharmony_ci}
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::removeBreakpoint(const String16& breakpointId) {
6781cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
6791cb0ef41Sopenharmony_ci  BreakpointType type;
6801cb0ef41Sopenharmony_ci  String16 selector;
6811cb0ef41Sopenharmony_ci  if (!parseBreakpointId(breakpointId, &type, &selector)) {
6821cb0ef41Sopenharmony_ci    return Response::Success();
6831cb0ef41Sopenharmony_ci  }
6841cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpoints = nullptr;
6851cb0ef41Sopenharmony_ci  switch (type) {
6861cb0ef41Sopenharmony_ci    case BreakpointType::kByUrl: {
6871cb0ef41Sopenharmony_ci      protocol::DictionaryValue* breakpointsByUrl =
6881cb0ef41Sopenharmony_ci          m_state->getObject(DebuggerAgentState::breakpointsByUrl);
6891cb0ef41Sopenharmony_ci      if (breakpointsByUrl) {
6901cb0ef41Sopenharmony_ci        breakpoints = breakpointsByUrl->getObject(selector);
6911cb0ef41Sopenharmony_ci      }
6921cb0ef41Sopenharmony_ci    } break;
6931cb0ef41Sopenharmony_ci    case BreakpointType::kByScriptHash: {
6941cb0ef41Sopenharmony_ci      protocol::DictionaryValue* breakpointsByScriptHash =
6951cb0ef41Sopenharmony_ci          m_state->getObject(DebuggerAgentState::breakpointsByScriptHash);
6961cb0ef41Sopenharmony_ci      if (breakpointsByScriptHash) {
6971cb0ef41Sopenharmony_ci        breakpoints = breakpointsByScriptHash->getObject(selector);
6981cb0ef41Sopenharmony_ci      }
6991cb0ef41Sopenharmony_ci    } break;
7001cb0ef41Sopenharmony_ci    case BreakpointType::kByUrlRegex:
7011cb0ef41Sopenharmony_ci      breakpoints = m_state->getObject(DebuggerAgentState::breakpointsByRegex);
7021cb0ef41Sopenharmony_ci      break;
7031cb0ef41Sopenharmony_ci    case BreakpointType::kInstrumentationBreakpoint:
7041cb0ef41Sopenharmony_ci      breakpoints =
7051cb0ef41Sopenharmony_ci          m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
7061cb0ef41Sopenharmony_ci      break;
7071cb0ef41Sopenharmony_ci    default:
7081cb0ef41Sopenharmony_ci      break;
7091cb0ef41Sopenharmony_ci  }
7101cb0ef41Sopenharmony_ci  if (breakpoints) breakpoints->remove(breakpointId);
7111cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpointHints =
7121cb0ef41Sopenharmony_ci      m_state->getObject(DebuggerAgentState::breakpointHints);
7131cb0ef41Sopenharmony_ci  if (breakpointHints) breakpointHints->remove(breakpointId);
7141cb0ef41Sopenharmony_ci
7151cb0ef41Sopenharmony_ci  // Get a list of scripts to remove breakpoints.
7161cb0ef41Sopenharmony_ci  // TODO(duongn): we can do better here if from breakpoint id we can tell it is
7171cb0ef41Sopenharmony_ci  // not Wasm breakpoint.
7181cb0ef41Sopenharmony_ci  std::vector<V8DebuggerScript*> scripts;
7191cb0ef41Sopenharmony_ci  for (const auto& scriptIter : m_scripts) {
7201cb0ef41Sopenharmony_ci    const bool scriptSelectorMatch =
7211cb0ef41Sopenharmony_ci        matches(m_inspector, *scriptIter.second, type, selector);
7221cb0ef41Sopenharmony_ci    const bool isInstrumentation =
7231cb0ef41Sopenharmony_ci        type == BreakpointType::kInstrumentationBreakpoint;
7241cb0ef41Sopenharmony_ci    if (!scriptSelectorMatch && !isInstrumentation) continue;
7251cb0ef41Sopenharmony_ci    V8DebuggerScript* script = scriptIter.second.get();
7261cb0ef41Sopenharmony_ci    if (script->getLanguage() == V8DebuggerScript::Language::WebAssembly) {
7271cb0ef41Sopenharmony_ci      scripts.push_back(script);
7281cb0ef41Sopenharmony_ci    }
7291cb0ef41Sopenharmony_ci  }
7301cb0ef41Sopenharmony_ci  removeBreakpointImpl(breakpointId, scripts);
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ci  return Response::Success();
7331cb0ef41Sopenharmony_ci}
7341cb0ef41Sopenharmony_ci
7351cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::removeBreakpointImpl(
7361cb0ef41Sopenharmony_ci    const String16& breakpointId,
7371cb0ef41Sopenharmony_ci    const std::vector<V8DebuggerScript*>& scripts) {
7381cb0ef41Sopenharmony_ci  DCHECK(enabled());
7391cb0ef41Sopenharmony_ci  BreakpointIdToDebuggerBreakpointIdsMap::iterator
7401cb0ef41Sopenharmony_ci      debuggerBreakpointIdsIterator =
7411cb0ef41Sopenharmony_ci          m_breakpointIdToDebuggerBreakpointIds.find(breakpointId);
7421cb0ef41Sopenharmony_ci  if (debuggerBreakpointIdsIterator ==
7431cb0ef41Sopenharmony_ci      m_breakpointIdToDebuggerBreakpointIds.end()) {
7441cb0ef41Sopenharmony_ci    return;
7451cb0ef41Sopenharmony_ci  }
7461cb0ef41Sopenharmony_ci  for (const auto& id : debuggerBreakpointIdsIterator->second) {
7471cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
7481cb0ef41Sopenharmony_ci    for (auto& script : scripts) {
7491cb0ef41Sopenharmony_ci      script->removeWasmBreakpoint(id);
7501cb0ef41Sopenharmony_ci    }
7511cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
7521cb0ef41Sopenharmony_ci    v8::debug::RemoveBreakpoint(m_isolate, id);
7531cb0ef41Sopenharmony_ci    m_debuggerBreakpointIdToBreakpointId.erase(id);
7541cb0ef41Sopenharmony_ci  }
7551cb0ef41Sopenharmony_ci  m_breakpointIdToDebuggerBreakpointIds.erase(breakpointId);
7561cb0ef41Sopenharmony_ci}
7571cb0ef41Sopenharmony_ci
7581cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::getPossibleBreakpoints(
7591cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location> start,
7601cb0ef41Sopenharmony_ci    Maybe<protocol::Debugger::Location> end, Maybe<bool> restrictToFunction,
7611cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Array<protocol::Debugger::BreakLocation>>*
7621cb0ef41Sopenharmony_ci        locations) {
7631cb0ef41Sopenharmony_ci  String16 scriptId = start->getScriptId();
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  if (start->getLineNumber() < 0 || start->getColumnNumber(0) < 0)
7661cb0ef41Sopenharmony_ci    return Response::ServerError(
7671cb0ef41Sopenharmony_ci        "start.lineNumber and start.columnNumber should be >= 0");
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci  v8::debug::Location v8Start(start->getLineNumber(),
7701cb0ef41Sopenharmony_ci                              start->getColumnNumber(0));
7711cb0ef41Sopenharmony_ci  v8::debug::Location v8End;
7721cb0ef41Sopenharmony_ci  if (end.isJust()) {
7731cb0ef41Sopenharmony_ci    if (end.fromJust()->getScriptId() != scriptId)
7741cb0ef41Sopenharmony_ci      return Response::ServerError(
7751cb0ef41Sopenharmony_ci          "Locations should contain the same scriptId");
7761cb0ef41Sopenharmony_ci    int line = end.fromJust()->getLineNumber();
7771cb0ef41Sopenharmony_ci    int column = end.fromJust()->getColumnNumber(0);
7781cb0ef41Sopenharmony_ci    if (line < 0 || column < 0)
7791cb0ef41Sopenharmony_ci      return Response::ServerError(
7801cb0ef41Sopenharmony_ci          "end.lineNumber and end.columnNumber should be >= 0");
7811cb0ef41Sopenharmony_ci    v8End = v8::debug::Location(line, column);
7821cb0ef41Sopenharmony_ci  }
7831cb0ef41Sopenharmony_ci  auto it = m_scripts.find(scriptId);
7841cb0ef41Sopenharmony_ci  if (it == m_scripts.end()) return Response::ServerError("Script not found");
7851cb0ef41Sopenharmony_ci  std::vector<v8::debug::BreakLocation> v8Locations;
7861cb0ef41Sopenharmony_ci  {
7871cb0ef41Sopenharmony_ci    v8::HandleScope handleScope(m_isolate);
7881cb0ef41Sopenharmony_ci    int contextId = it->second->executionContextId();
7891cb0ef41Sopenharmony_ci    InspectedContext* inspected = m_inspector->getContext(contextId);
7901cb0ef41Sopenharmony_ci    if (!inspected) {
7911cb0ef41Sopenharmony_ci      return Response::ServerError("Cannot retrive script context");
7921cb0ef41Sopenharmony_ci    }
7931cb0ef41Sopenharmony_ci    v8::Context::Scope contextScope(inspected->context());
7941cb0ef41Sopenharmony_ci    v8::MicrotasksScope microtasks(m_isolate,
7951cb0ef41Sopenharmony_ci                                   v8::MicrotasksScope::kDoNotRunMicrotasks);
7961cb0ef41Sopenharmony_ci    v8::TryCatch tryCatch(m_isolate);
7971cb0ef41Sopenharmony_ci    it->second->getPossibleBreakpoints(
7981cb0ef41Sopenharmony_ci        v8Start, v8End, restrictToFunction.fromMaybe(false), &v8Locations);
7991cb0ef41Sopenharmony_ci  }
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci  *locations =
8021cb0ef41Sopenharmony_ci      std::make_unique<protocol::Array<protocol::Debugger::BreakLocation>>();
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ci  // TODO(1106269): Return an error instead of capping the number of
8051cb0ef41Sopenharmony_ci  // breakpoints.
8061cb0ef41Sopenharmony_ci  const size_t numBreakpointsToSend =
8071cb0ef41Sopenharmony_ci      std::min(v8Locations.size(), kMaxNumBreakpoints);
8081cb0ef41Sopenharmony_ci  for (size_t i = 0; i < numBreakpointsToSend; ++i) {
8091cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::BreakLocation> breakLocation =
8101cb0ef41Sopenharmony_ci        protocol::Debugger::BreakLocation::create()
8111cb0ef41Sopenharmony_ci            .setScriptId(scriptId)
8121cb0ef41Sopenharmony_ci            .setLineNumber(v8Locations[i].GetLineNumber())
8131cb0ef41Sopenharmony_ci            .setColumnNumber(v8Locations[i].GetColumnNumber())
8141cb0ef41Sopenharmony_ci            .build();
8151cb0ef41Sopenharmony_ci    if (v8Locations[i].type() != v8::debug::kCommonBreakLocation) {
8161cb0ef41Sopenharmony_ci      breakLocation->setType(breakLocationType(v8Locations[i].type()));
8171cb0ef41Sopenharmony_ci    }
8181cb0ef41Sopenharmony_ci    (*locations)->emplace_back(std::move(breakLocation));
8191cb0ef41Sopenharmony_ci  }
8201cb0ef41Sopenharmony_ci  return Response::Success();
8211cb0ef41Sopenharmony_ci}
8221cb0ef41Sopenharmony_ci
8231cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::continueToLocation(
8241cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location> location,
8251cb0ef41Sopenharmony_ci    Maybe<String16> targetCallFrames) {
8261cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
8271cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
8281cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(location->getScriptId());
8291cb0ef41Sopenharmony_ci  if (it == m_scripts.end()) {
8301cb0ef41Sopenharmony_ci    return Response::ServerError("Cannot continue to specified location");
8311cb0ef41Sopenharmony_ci  }
8321cb0ef41Sopenharmony_ci  V8DebuggerScript* script = it->second.get();
8331cb0ef41Sopenharmony_ci  int contextId = script->executionContextId();
8341cb0ef41Sopenharmony_ci  InspectedContext* inspected = m_inspector->getContext(contextId);
8351cb0ef41Sopenharmony_ci  if (!inspected)
8361cb0ef41Sopenharmony_ci    return Response::ServerError("Cannot continue to specified location");
8371cb0ef41Sopenharmony_ci  v8::HandleScope handleScope(m_isolate);
8381cb0ef41Sopenharmony_ci  v8::Context::Scope contextScope(inspected->context());
8391cb0ef41Sopenharmony_ci  return m_debugger->continueToLocation(
8401cb0ef41Sopenharmony_ci      m_session->contextGroupId(), script, std::move(location),
8411cb0ef41Sopenharmony_ci      targetCallFrames.fromMaybe(
8421cb0ef41Sopenharmony_ci          protocol::Debugger::ContinueToLocation::TargetCallFramesEnum::Any));
8431cb0ef41Sopenharmony_ci}
8441cb0ef41Sopenharmony_ci
8451cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::getStackTrace(
8461cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::StackTraceId> inStackTraceId,
8471cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::StackTrace>* outStackTrace) {
8481cb0ef41Sopenharmony_ci  bool isOk = false;
8491cb0ef41Sopenharmony_ci  int64_t id = inStackTraceId->getId().toInteger64(&isOk);
8501cb0ef41Sopenharmony_ci  if (!isOk) return Response::ServerError("Invalid stack trace id");
8511cb0ef41Sopenharmony_ci
8521cb0ef41Sopenharmony_ci  internal::V8DebuggerId debuggerId;
8531cb0ef41Sopenharmony_ci  if (inStackTraceId->hasDebuggerId()) {
8541cb0ef41Sopenharmony_ci    debuggerId =
8551cb0ef41Sopenharmony_ci        internal::V8DebuggerId(inStackTraceId->getDebuggerId(String16()));
8561cb0ef41Sopenharmony_ci  } else {
8571cb0ef41Sopenharmony_ci    debuggerId = m_debugger->debuggerIdFor(m_session->contextGroupId());
8581cb0ef41Sopenharmony_ci  }
8591cb0ef41Sopenharmony_ci  if (!debuggerId.isValid())
8601cb0ef41Sopenharmony_ci    return Response::ServerError("Invalid stack trace id");
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci  V8StackTraceId v8StackTraceId(id, debuggerId.pair());
8631cb0ef41Sopenharmony_ci  if (v8StackTraceId.IsInvalid())
8641cb0ef41Sopenharmony_ci    return Response::ServerError("Invalid stack trace id");
8651cb0ef41Sopenharmony_ci  auto stack =
8661cb0ef41Sopenharmony_ci      m_debugger->stackTraceFor(m_session->contextGroupId(), v8StackTraceId);
8671cb0ef41Sopenharmony_ci  if (!stack) {
8681cb0ef41Sopenharmony_ci    return Response::ServerError("Stack trace with given id is not found");
8691cb0ef41Sopenharmony_ci  }
8701cb0ef41Sopenharmony_ci  *outStackTrace = stack->buildInspectorObject(
8711cb0ef41Sopenharmony_ci      m_debugger, m_debugger->maxAsyncCallChainDepth());
8721cb0ef41Sopenharmony_ci  return Response::Success();
8731cb0ef41Sopenharmony_ci}
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_cibool V8DebuggerAgentImpl::isFunctionBlackboxed(const String16& scriptId,
8761cb0ef41Sopenharmony_ci                                               const v8::debug::Location& start,
8771cb0ef41Sopenharmony_ci                                               const v8::debug::Location& end) {
8781cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(scriptId);
8791cb0ef41Sopenharmony_ci  if (it == m_scripts.end()) {
8801cb0ef41Sopenharmony_ci    // Unknown scripts are blackboxed.
8811cb0ef41Sopenharmony_ci    return true;
8821cb0ef41Sopenharmony_ci  }
8831cb0ef41Sopenharmony_ci  if (m_blackboxPattern) {
8841cb0ef41Sopenharmony_ci    const String16& scriptSourceURL = it->second->sourceURL();
8851cb0ef41Sopenharmony_ci    if (!scriptSourceURL.isEmpty() &&
8861cb0ef41Sopenharmony_ci        m_blackboxPattern->match(scriptSourceURL) != -1)
8871cb0ef41Sopenharmony_ci      return true;
8881cb0ef41Sopenharmony_ci  }
8891cb0ef41Sopenharmony_ci  auto itBlackboxedPositions = m_blackboxedPositions.find(scriptId);
8901cb0ef41Sopenharmony_ci  if (itBlackboxedPositions == m_blackboxedPositions.end()) return false;
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci  const std::vector<std::pair<int, int>>& ranges =
8931cb0ef41Sopenharmony_ci      itBlackboxedPositions->second;
8941cb0ef41Sopenharmony_ci  auto itStartRange = std::lower_bound(
8951cb0ef41Sopenharmony_ci      ranges.begin(), ranges.end(),
8961cb0ef41Sopenharmony_ci      std::make_pair(start.GetLineNumber(), start.GetColumnNumber()),
8971cb0ef41Sopenharmony_ci      positionComparator);
8981cb0ef41Sopenharmony_ci  auto itEndRange = std::lower_bound(
8991cb0ef41Sopenharmony_ci      itStartRange, ranges.end(),
9001cb0ef41Sopenharmony_ci      std::make_pair(end.GetLineNumber(), end.GetColumnNumber()),
9011cb0ef41Sopenharmony_ci      positionComparator);
9021cb0ef41Sopenharmony_ci  // Ranges array contains positions in script where blackbox state is changed.
9031cb0ef41Sopenharmony_ci  // [(0,0) ... ranges[0]) isn't blackboxed, [ranges[0] ... ranges[1]) is
9041cb0ef41Sopenharmony_ci  // blackboxed...
9051cb0ef41Sopenharmony_ci  return itStartRange == itEndRange &&
9061cb0ef41Sopenharmony_ci         std::distance(ranges.begin(), itStartRange) % 2;
9071cb0ef41Sopenharmony_ci}
9081cb0ef41Sopenharmony_ci
9091cb0ef41Sopenharmony_cibool V8DebuggerAgentImpl::shouldBeSkipped(const String16& scriptId, int line,
9101cb0ef41Sopenharmony_ci                                          int column) {
9111cb0ef41Sopenharmony_ci  if (m_skipList.empty()) return false;
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ci  auto it = m_skipList.find(scriptId);
9141cb0ef41Sopenharmony_ci  if (it == m_skipList.end()) return false;
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_ci  const std::vector<std::pair<int, int>>& ranges = it->second;
9171cb0ef41Sopenharmony_ci  DCHECK(!ranges.empty());
9181cb0ef41Sopenharmony_ci  const std::pair<int, int> location = std::make_pair(line, column);
9191cb0ef41Sopenharmony_ci  auto itLowerBound = std::lower_bound(ranges.begin(), ranges.end(), location,
9201cb0ef41Sopenharmony_ci                                       positionComparator);
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci  bool shouldSkip = false;
9231cb0ef41Sopenharmony_ci  if (itLowerBound != ranges.end()) {
9241cb0ef41Sopenharmony_ci    // Skip lists are defined as pairs of locations that specify the
9251cb0ef41Sopenharmony_ci    // start and the end of ranges to skip: [ranges[0], ranges[1], ..], where
9261cb0ef41Sopenharmony_ci    // locations in [ranges[0], ranges[1]) should be skipped, i.e.
9271cb0ef41Sopenharmony_ci    // [(lineStart, columnStart), (lineEnd, columnEnd)).
9281cb0ef41Sopenharmony_ci    const bool isSameAsLowerBound = location == *itLowerBound;
9291cb0ef41Sopenharmony_ci    const bool isUnevenIndex = (itLowerBound - ranges.begin()) % 2;
9301cb0ef41Sopenharmony_ci    shouldSkip = isSameAsLowerBound ^ isUnevenIndex;
9311cb0ef41Sopenharmony_ci  }
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_ci  return shouldSkip;
9341cb0ef41Sopenharmony_ci}
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_cibool V8DebuggerAgentImpl::acceptsPause(bool isOOMBreak) const {
9371cb0ef41Sopenharmony_ci  return enabled() && (isOOMBreak || !m_skipAllPauses);
9381cb0ef41Sopenharmony_ci}
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Debugger::Location>
9411cb0ef41Sopenharmony_ciV8DebuggerAgentImpl::setBreakpointImpl(const String16& breakpointId,
9421cb0ef41Sopenharmony_ci                                       const String16& scriptId,
9431cb0ef41Sopenharmony_ci                                       const String16& condition,
9441cb0ef41Sopenharmony_ci                                       int lineNumber, int columnNumber) {
9451cb0ef41Sopenharmony_ci  v8::HandleScope handles(m_isolate);
9461cb0ef41Sopenharmony_ci  DCHECK(enabled());
9471cb0ef41Sopenharmony_ci
9481cb0ef41Sopenharmony_ci  ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
9491cb0ef41Sopenharmony_ci  if (scriptIterator == m_scripts.end()) return nullptr;
9501cb0ef41Sopenharmony_ci  V8DebuggerScript* script = scriptIterator->second.get();
9511cb0ef41Sopenharmony_ci  if (lineNumber < script->startLine() || script->endLine() < lineNumber) {
9521cb0ef41Sopenharmony_ci    return nullptr;
9531cb0ef41Sopenharmony_ci  }
9541cb0ef41Sopenharmony_ci  if (lineNumber == script->startLine() &&
9551cb0ef41Sopenharmony_ci      columnNumber < script->startColumn()) {
9561cb0ef41Sopenharmony_ci    return nullptr;
9571cb0ef41Sopenharmony_ci  }
9581cb0ef41Sopenharmony_ci  if (lineNumber == script->endLine() && script->endColumn() < columnNumber) {
9591cb0ef41Sopenharmony_ci    return nullptr;
9601cb0ef41Sopenharmony_ci  }
9611cb0ef41Sopenharmony_ci
9621cb0ef41Sopenharmony_ci  v8::debug::BreakpointId debuggerBreakpointId;
9631cb0ef41Sopenharmony_ci  v8::debug::Location location(lineNumber, columnNumber);
9641cb0ef41Sopenharmony_ci  int contextId = script->executionContextId();
9651cb0ef41Sopenharmony_ci  InspectedContext* inspected = m_inspector->getContext(contextId);
9661cb0ef41Sopenharmony_ci  if (!inspected) return nullptr;
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_ci  {
9691cb0ef41Sopenharmony_ci    v8::Context::Scope contextScope(inspected->context());
9701cb0ef41Sopenharmony_ci    if (!script->setBreakpoint(condition, &location, &debuggerBreakpointId)) {
9711cb0ef41Sopenharmony_ci      return nullptr;
9721cb0ef41Sopenharmony_ci    }
9731cb0ef41Sopenharmony_ci  }
9741cb0ef41Sopenharmony_ci
9751cb0ef41Sopenharmony_ci  m_debuggerBreakpointIdToBreakpointId[debuggerBreakpointId] = breakpointId;
9761cb0ef41Sopenharmony_ci  m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
9771cb0ef41Sopenharmony_ci      debuggerBreakpointId);
9781cb0ef41Sopenharmony_ci
9791cb0ef41Sopenharmony_ci  return protocol::Debugger::Location::create()
9801cb0ef41Sopenharmony_ci      .setScriptId(scriptId)
9811cb0ef41Sopenharmony_ci      .setLineNumber(location.GetLineNumber())
9821cb0ef41Sopenharmony_ci      .setColumnNumber(location.GetColumnNumber())
9831cb0ef41Sopenharmony_ci      .build();
9841cb0ef41Sopenharmony_ci}
9851cb0ef41Sopenharmony_ci
9861cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::setBreakpointImpl(const String16& breakpointId,
9871cb0ef41Sopenharmony_ci                                            v8::Local<v8::Function> function,
9881cb0ef41Sopenharmony_ci                                            v8::Local<v8::String> condition) {
9891cb0ef41Sopenharmony_ci  v8::debug::BreakpointId debuggerBreakpointId;
9901cb0ef41Sopenharmony_ci  if (!v8::debug::SetFunctionBreakpoint(function, condition,
9911cb0ef41Sopenharmony_ci                                        &debuggerBreakpointId)) {
9921cb0ef41Sopenharmony_ci    return;
9931cb0ef41Sopenharmony_ci  }
9941cb0ef41Sopenharmony_ci  m_debuggerBreakpointIdToBreakpointId[debuggerBreakpointId] = breakpointId;
9951cb0ef41Sopenharmony_ci  m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
9961cb0ef41Sopenharmony_ci      debuggerBreakpointId);
9971cb0ef41Sopenharmony_ci}
9981cb0ef41Sopenharmony_ci
9991cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::searchInContent(
10001cb0ef41Sopenharmony_ci    const String16& scriptId, const String16& query,
10011cb0ef41Sopenharmony_ci    Maybe<bool> optionalCaseSensitive, Maybe<bool> optionalIsRegex,
10021cb0ef41Sopenharmony_ci    std::unique_ptr<Array<protocol::Debugger::SearchMatch>>* results) {
10031cb0ef41Sopenharmony_ci  v8::HandleScope handles(m_isolate);
10041cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(scriptId);
10051cb0ef41Sopenharmony_ci  if (it == m_scripts.end())
10061cb0ef41Sopenharmony_ci    return Response::ServerError("No script for id: " + scriptId.utf8());
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci  *results = std::make_unique<protocol::Array<protocol::Debugger::SearchMatch>>(
10091cb0ef41Sopenharmony_ci      searchInTextByLinesImpl(m_session, it->second->source(0), query,
10101cb0ef41Sopenharmony_ci                              optionalCaseSensitive.fromMaybe(false),
10111cb0ef41Sopenharmony_ci                              optionalIsRegex.fromMaybe(false)));
10121cb0ef41Sopenharmony_ci  return Response::Success();
10131cb0ef41Sopenharmony_ci}
10141cb0ef41Sopenharmony_ci
10151cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setScriptSource(
10161cb0ef41Sopenharmony_ci    const String16& scriptId, const String16& newContent, Maybe<bool> dryRun,
10171cb0ef41Sopenharmony_ci    Maybe<protocol::Array<protocol::Debugger::CallFrame>>* newCallFrames,
10181cb0ef41Sopenharmony_ci    Maybe<bool>* stackChanged,
10191cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
10201cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId,
10211cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
10221cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
10231cb0ef41Sopenharmony_ci
10241cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(scriptId);
10251cb0ef41Sopenharmony_ci  if (it == m_scripts.end()) {
10261cb0ef41Sopenharmony_ci    return Response::ServerError("No script with given id found");
10271cb0ef41Sopenharmony_ci  }
10281cb0ef41Sopenharmony_ci  int contextId = it->second->executionContextId();
10291cb0ef41Sopenharmony_ci  InspectedContext* inspected = m_inspector->getContext(contextId);
10301cb0ef41Sopenharmony_ci  if (!inspected) {
10311cb0ef41Sopenharmony_ci    return Response::InternalError();
10321cb0ef41Sopenharmony_ci  }
10331cb0ef41Sopenharmony_ci  v8::HandleScope handleScope(m_isolate);
10341cb0ef41Sopenharmony_ci  v8::Local<v8::Context> context = inspected->context();
10351cb0ef41Sopenharmony_ci  v8::Context::Scope contextScope(context);
10361cb0ef41Sopenharmony_ci
10371cb0ef41Sopenharmony_ci  v8::debug::LiveEditResult result;
10381cb0ef41Sopenharmony_ci  it->second->setSource(newContent, dryRun.fromMaybe(false), &result);
10391cb0ef41Sopenharmony_ci  if (result.status != v8::debug::LiveEditResult::OK) {
10401cb0ef41Sopenharmony_ci    *optOutCompileError =
10411cb0ef41Sopenharmony_ci        protocol::Runtime::ExceptionDetails::create()
10421cb0ef41Sopenharmony_ci            .setExceptionId(m_inspector->nextExceptionId())
10431cb0ef41Sopenharmony_ci            .setText(toProtocolString(m_isolate, result.message))
10441cb0ef41Sopenharmony_ci            .setLineNumber(result.line_number != -1 ? result.line_number - 1
10451cb0ef41Sopenharmony_ci                                                    : 0)
10461cb0ef41Sopenharmony_ci            .setColumnNumber(result.column_number != -1 ? result.column_number
10471cb0ef41Sopenharmony_ci                                                        : 0)
10481cb0ef41Sopenharmony_ci            .build();
10491cb0ef41Sopenharmony_ci    return Response::Success();
10501cb0ef41Sopenharmony_ci  } else {
10511cb0ef41Sopenharmony_ci    *stackChanged = result.stack_changed;
10521cb0ef41Sopenharmony_ci  }
10531cb0ef41Sopenharmony_ci  std::unique_ptr<Array<CallFrame>> callFrames;
10541cb0ef41Sopenharmony_ci  Response response = currentCallFrames(&callFrames);
10551cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
10561cb0ef41Sopenharmony_ci  *newCallFrames = std::move(callFrames);
10571cb0ef41Sopenharmony_ci  *asyncStackTrace = currentAsyncStackTrace();
10581cb0ef41Sopenharmony_ci  *asyncStackTraceId = currentExternalStackTrace();
10591cb0ef41Sopenharmony_ci  return Response::Success();
10601cb0ef41Sopenharmony_ci}
10611cb0ef41Sopenharmony_ci
10621cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::restartFrame(
10631cb0ef41Sopenharmony_ci    const String16& callFrameId,
10641cb0ef41Sopenharmony_ci    std::unique_ptr<Array<CallFrame>>* newCallFrames,
10651cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::StackTrace>* asyncStackTrace,
10661cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::StackTraceId>* asyncStackTraceId) {
10671cb0ef41Sopenharmony_ci  return Response::ServerError("Frame restarting not supported");
10681cb0ef41Sopenharmony_ci}
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::getScriptSource(
10711cb0ef41Sopenharmony_ci    const String16& scriptId, String16* scriptSource,
10721cb0ef41Sopenharmony_ci    Maybe<protocol::Binary>* bytecode) {
10731cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
10741cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(scriptId);
10751cb0ef41Sopenharmony_ci  if (it == m_scripts.end()) {
10761cb0ef41Sopenharmony_ci    auto cachedScriptIt =
10771cb0ef41Sopenharmony_ci        std::find_if(m_cachedScripts.begin(), m_cachedScripts.end(),
10781cb0ef41Sopenharmony_ci                     [&scriptId](const CachedScript& cachedScript) {
10791cb0ef41Sopenharmony_ci                       return cachedScript.scriptId == scriptId;
10801cb0ef41Sopenharmony_ci                     });
10811cb0ef41Sopenharmony_ci    if (cachedScriptIt != m_cachedScripts.end()) {
10821cb0ef41Sopenharmony_ci      *scriptSource = cachedScriptIt->source;
10831cb0ef41Sopenharmony_ci      *bytecode = protocol::Binary::fromSpan(cachedScriptIt->bytecode.data(),
10841cb0ef41Sopenharmony_ci                                             cachedScriptIt->bytecode.size());
10851cb0ef41Sopenharmony_ci      return Response::Success();
10861cb0ef41Sopenharmony_ci    }
10871cb0ef41Sopenharmony_ci    return Response::ServerError("No script for id: " + scriptId.utf8());
10881cb0ef41Sopenharmony_ci  }
10891cb0ef41Sopenharmony_ci  *scriptSource = it->second->source(0);
10901cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
10911cb0ef41Sopenharmony_ci  v8::MemorySpan<const uint8_t> span;
10921cb0ef41Sopenharmony_ci  if (it->second->wasmBytecode().To(&span)) {
10931cb0ef41Sopenharmony_ci    if (span.size() > kWasmBytecodeMaxLength) {
10941cb0ef41Sopenharmony_ci      return Response::ServerError(kWasmBytecodeExceedsTransferLimit);
10951cb0ef41Sopenharmony_ci    }
10961cb0ef41Sopenharmony_ci    *bytecode = protocol::Binary::fromSpan(span.data(), span.size());
10971cb0ef41Sopenharmony_ci  }
10981cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
10991cb0ef41Sopenharmony_ci  return Response::Success();
11001cb0ef41Sopenharmony_ci}
11011cb0ef41Sopenharmony_ci
11021cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::getWasmBytecode(const String16& scriptId,
11031cb0ef41Sopenharmony_ci                                              protocol::Binary* bytecode) {
11041cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
11051cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
11061cb0ef41Sopenharmony_ci  ScriptsMap::iterator it = m_scripts.find(scriptId);
11071cb0ef41Sopenharmony_ci  if (it == m_scripts.end())
11081cb0ef41Sopenharmony_ci    return Response::ServerError("No script for id: " + scriptId.utf8());
11091cb0ef41Sopenharmony_ci  v8::MemorySpan<const uint8_t> span;
11101cb0ef41Sopenharmony_ci  if (!it->second->wasmBytecode().To(&span))
11111cb0ef41Sopenharmony_ci    return Response::ServerError("Script with id " + scriptId.utf8() +
11121cb0ef41Sopenharmony_ci                                 " is not WebAssembly");
11131cb0ef41Sopenharmony_ci  if (span.size() > kWasmBytecodeMaxLength) {
11141cb0ef41Sopenharmony_ci    return Response::ServerError(kWasmBytecodeExceedsTransferLimit);
11151cb0ef41Sopenharmony_ci  }
11161cb0ef41Sopenharmony_ci  *bytecode = protocol::Binary::fromSpan(span.data(), span.size());
11171cb0ef41Sopenharmony_ci  return Response::Success();
11181cb0ef41Sopenharmony_ci#else
11191cb0ef41Sopenharmony_ci  return Response::ServerError("WebAssembly is disabled");
11201cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
11211cb0ef41Sopenharmony_ci}
11221cb0ef41Sopenharmony_ci
11231cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::pushBreakDetails(
11241cb0ef41Sopenharmony_ci    const String16& breakReason,
11251cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::DictionaryValue> breakAuxData) {
11261cb0ef41Sopenharmony_ci  m_breakReason.push_back(std::make_pair(breakReason, std::move(breakAuxData)));
11271cb0ef41Sopenharmony_ci}
11281cb0ef41Sopenharmony_ci
11291cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::popBreakDetails() {
11301cb0ef41Sopenharmony_ci  if (m_breakReason.empty()) return;
11311cb0ef41Sopenharmony_ci  m_breakReason.pop_back();
11321cb0ef41Sopenharmony_ci}
11331cb0ef41Sopenharmony_ci
11341cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::clearBreakDetails() {
11351cb0ef41Sopenharmony_ci  std::vector<BreakReason> emptyBreakReason;
11361cb0ef41Sopenharmony_ci  m_breakReason.swap(emptyBreakReason);
11371cb0ef41Sopenharmony_ci}
11381cb0ef41Sopenharmony_ci
11391cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::schedulePauseOnNextStatement(
11401cb0ef41Sopenharmony_ci    const String16& breakReason,
11411cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::DictionaryValue> data) {
11421cb0ef41Sopenharmony_ci  if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return;
11431cb0ef41Sopenharmony_ci  if (m_breakReason.empty()) {
11441cb0ef41Sopenharmony_ci    m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
11451cb0ef41Sopenharmony_ci  }
11461cb0ef41Sopenharmony_ci  pushBreakDetails(breakReason, std::move(data));
11471cb0ef41Sopenharmony_ci}
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::cancelPauseOnNextStatement() {
11501cb0ef41Sopenharmony_ci  if (isPaused() || !acceptsPause(false) || !m_breakpointsActive) return;
11511cb0ef41Sopenharmony_ci  if (m_breakReason.size() == 1) {
11521cb0ef41Sopenharmony_ci    m_debugger->setPauseOnNextCall(false, m_session->contextGroupId());
11531cb0ef41Sopenharmony_ci  }
11541cb0ef41Sopenharmony_ci  popBreakDetails();
11551cb0ef41Sopenharmony_ci}
11561cb0ef41Sopenharmony_ci
11571cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::pause() {
11581cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
11591cb0ef41Sopenharmony_ci  if (isPaused()) return Response::Success();
11601cb0ef41Sopenharmony_ci
11611cb0ef41Sopenharmony_ci  if (m_debugger->canBreakProgram()) {
11621cb0ef41Sopenharmony_ci    m_debugger->interruptAndBreak(m_session->contextGroupId());
11631cb0ef41Sopenharmony_ci  } else {
11641cb0ef41Sopenharmony_ci    pushBreakDetails(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
11651cb0ef41Sopenharmony_ci    m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
11661cb0ef41Sopenharmony_ci  }
11671cb0ef41Sopenharmony_ci
11681cb0ef41Sopenharmony_ci  return Response::Success();
11691cb0ef41Sopenharmony_ci}
11701cb0ef41Sopenharmony_ci
11711cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::resume(Maybe<bool> terminateOnResume) {
11721cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
11731cb0ef41Sopenharmony_ci  m_session->releaseObjectGroup(kBacktraceObjectGroup);
11741cb0ef41Sopenharmony_ci  m_debugger->continueProgram(m_session->contextGroupId(),
11751cb0ef41Sopenharmony_ci                              terminateOnResume.fromMaybe(false));
11761cb0ef41Sopenharmony_ci  return Response::Success();
11771cb0ef41Sopenharmony_ci}
11781cb0ef41Sopenharmony_ci
11791cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::stepOver(
11801cb0ef41Sopenharmony_ci    Maybe<protocol::Array<protocol::Debugger::LocationRange>> inSkipList) {
11811cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
11821cb0ef41Sopenharmony_ci
11831cb0ef41Sopenharmony_ci  if (inSkipList.isJust()) {
11841cb0ef41Sopenharmony_ci    const Response res = processSkipList(inSkipList.fromJust());
11851cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
11861cb0ef41Sopenharmony_ci  } else {
11871cb0ef41Sopenharmony_ci    m_skipList.clear();
11881cb0ef41Sopenharmony_ci  }
11891cb0ef41Sopenharmony_ci
11901cb0ef41Sopenharmony_ci  m_session->releaseObjectGroup(kBacktraceObjectGroup);
11911cb0ef41Sopenharmony_ci  m_debugger->stepOverStatement(m_session->contextGroupId());
11921cb0ef41Sopenharmony_ci  return Response::Success();
11931cb0ef41Sopenharmony_ci}
11941cb0ef41Sopenharmony_ci
11951cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::stepInto(
11961cb0ef41Sopenharmony_ci    Maybe<bool> inBreakOnAsyncCall,
11971cb0ef41Sopenharmony_ci    Maybe<protocol::Array<protocol::Debugger::LocationRange>> inSkipList) {
11981cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
11991cb0ef41Sopenharmony_ci
12001cb0ef41Sopenharmony_ci  if (inSkipList.isJust()) {
12011cb0ef41Sopenharmony_ci    const Response res = processSkipList(inSkipList.fromJust());
12021cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
12031cb0ef41Sopenharmony_ci  } else {
12041cb0ef41Sopenharmony_ci    m_skipList.clear();
12051cb0ef41Sopenharmony_ci  }
12061cb0ef41Sopenharmony_ci
12071cb0ef41Sopenharmony_ci  m_session->releaseObjectGroup(kBacktraceObjectGroup);
12081cb0ef41Sopenharmony_ci  m_debugger->stepIntoStatement(m_session->contextGroupId(),
12091cb0ef41Sopenharmony_ci                                inBreakOnAsyncCall.fromMaybe(false));
12101cb0ef41Sopenharmony_ci  return Response::Success();
12111cb0ef41Sopenharmony_ci}
12121cb0ef41Sopenharmony_ci
12131cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::stepOut() {
12141cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
12151cb0ef41Sopenharmony_ci  m_session->releaseObjectGroup(kBacktraceObjectGroup);
12161cb0ef41Sopenharmony_ci  m_debugger->stepOutOfFunction(m_session->contextGroupId());
12171cb0ef41Sopenharmony_ci  return Response::Success();
12181cb0ef41Sopenharmony_ci}
12191cb0ef41Sopenharmony_ci
12201cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::pauseOnAsyncCall(
12211cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::StackTraceId> inParentStackTraceId) {
12221cb0ef41Sopenharmony_ci  // Deprecated, just return OK.
12231cb0ef41Sopenharmony_ci  return Response::Success();
12241cb0ef41Sopenharmony_ci}
12251cb0ef41Sopenharmony_ci
12261cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setPauseOnExceptions(
12271cb0ef41Sopenharmony_ci    const String16& stringPauseState) {
12281cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
12291cb0ef41Sopenharmony_ci  v8::debug::ExceptionBreakState pauseState;
12301cb0ef41Sopenharmony_ci  if (stringPauseState == "none") {
12311cb0ef41Sopenharmony_ci    pauseState = v8::debug::NoBreakOnException;
12321cb0ef41Sopenharmony_ci  } else if (stringPauseState == "all") {
12331cb0ef41Sopenharmony_ci    pauseState = v8::debug::BreakOnAnyException;
12341cb0ef41Sopenharmony_ci  } else if (stringPauseState == "uncaught") {
12351cb0ef41Sopenharmony_ci    pauseState = v8::debug::BreakOnUncaughtException;
12361cb0ef41Sopenharmony_ci  } else {
12371cb0ef41Sopenharmony_ci    return Response::ServerError("Unknown pause on exceptions mode: " +
12381cb0ef41Sopenharmony_ci                                 stringPauseState.utf8());
12391cb0ef41Sopenharmony_ci  }
12401cb0ef41Sopenharmony_ci  setPauseOnExceptionsImpl(pauseState);
12411cb0ef41Sopenharmony_ci  return Response::Success();
12421cb0ef41Sopenharmony_ci}
12431cb0ef41Sopenharmony_ci
12441cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::setPauseOnExceptionsImpl(int pauseState) {
12451cb0ef41Sopenharmony_ci  // TODO(dgozman): this changes the global state and forces all context groups
12461cb0ef41Sopenharmony_ci  // to pause. We should make this flag be per-context-group.
12471cb0ef41Sopenharmony_ci  m_debugger->setPauseOnExceptionsState(
12481cb0ef41Sopenharmony_ci      static_cast<v8::debug::ExceptionBreakState>(pauseState));
12491cb0ef41Sopenharmony_ci  m_state->setInteger(DebuggerAgentState::pauseOnExceptionsState, pauseState);
12501cb0ef41Sopenharmony_ci}
12511cb0ef41Sopenharmony_ci
12521cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::evaluateOnCallFrame(
12531cb0ef41Sopenharmony_ci    const String16& callFrameId, const String16& expression,
12541cb0ef41Sopenharmony_ci    Maybe<String16> objectGroup, Maybe<bool> includeCommandLineAPI,
12551cb0ef41Sopenharmony_ci    Maybe<bool> silent, Maybe<bool> returnByValue, Maybe<bool> generatePreview,
12561cb0ef41Sopenharmony_ci    Maybe<bool> throwOnSideEffect, Maybe<double> timeout,
12571cb0ef41Sopenharmony_ci    std::unique_ptr<RemoteObject>* result,
12581cb0ef41Sopenharmony_ci    Maybe<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
12591cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
12601cb0ef41Sopenharmony_ci  InjectedScript::CallFrameScope scope(m_session, callFrameId);
12611cb0ef41Sopenharmony_ci  Response response = scope.initialize();
12621cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
12631cb0ef41Sopenharmony_ci  if (includeCommandLineAPI.fromMaybe(false)) scope.installCommandLineAPI();
12641cb0ef41Sopenharmony_ci  if (silent.fromMaybe(false)) scope.ignoreExceptionsAndMuteConsole();
12651cb0ef41Sopenharmony_ci
12661cb0ef41Sopenharmony_ci  int frameOrdinal = static_cast<int>(scope.frameOrdinal());
12671cb0ef41Sopenharmony_ci  auto it = v8::debug::StackTraceIterator::Create(m_isolate, frameOrdinal);
12681cb0ef41Sopenharmony_ci  if (it->Done()) {
12691cb0ef41Sopenharmony_ci    return Response::ServerError("Could not find call frame with given id");
12701cb0ef41Sopenharmony_ci  }
12711cb0ef41Sopenharmony_ci
12721cb0ef41Sopenharmony_ci  v8::MaybeLocal<v8::Value> maybeResultValue;
12731cb0ef41Sopenharmony_ci  {
12741cb0ef41Sopenharmony_ci    V8InspectorImpl::EvaluateScope evaluateScope(scope);
12751cb0ef41Sopenharmony_ci    if (timeout.isJust()) {
12761cb0ef41Sopenharmony_ci      response = evaluateScope.setTimeout(timeout.fromJust() / 1000.0);
12771cb0ef41Sopenharmony_ci      if (!response.IsSuccess()) return response;
12781cb0ef41Sopenharmony_ci    }
12791cb0ef41Sopenharmony_ci    maybeResultValue = it->Evaluate(toV8String(m_isolate, expression),
12801cb0ef41Sopenharmony_ci                                    throwOnSideEffect.fromMaybe(false));
12811cb0ef41Sopenharmony_ci  }
12821cb0ef41Sopenharmony_ci  // Re-initialize after running client's code, as it could have destroyed
12831cb0ef41Sopenharmony_ci  // context or session.
12841cb0ef41Sopenharmony_ci  response = scope.initialize();
12851cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
12861cb0ef41Sopenharmony_ci  WrapMode mode = generatePreview.fromMaybe(false) ? WrapMode::kWithPreview
12871cb0ef41Sopenharmony_ci                                                   : WrapMode::kNoPreview;
12881cb0ef41Sopenharmony_ci  if (returnByValue.fromMaybe(false)) mode = WrapMode::kForceValue;
12891cb0ef41Sopenharmony_ci  return scope.injectedScript()->wrapEvaluateResult(
12901cb0ef41Sopenharmony_ci      maybeResultValue, scope.tryCatch(), objectGroup.fromMaybe(""), mode,
12911cb0ef41Sopenharmony_ci      result, exceptionDetails);
12921cb0ef41Sopenharmony_ci}
12931cb0ef41Sopenharmony_ci
12941cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setVariableValue(
12951cb0ef41Sopenharmony_ci    int scopeNumber, const String16& variableName,
12961cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::CallArgument> newValueArgument,
12971cb0ef41Sopenharmony_ci    const String16& callFrameId) {
12981cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
12991cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
13001cb0ef41Sopenharmony_ci  InjectedScript::CallFrameScope scope(m_session, callFrameId);
13011cb0ef41Sopenharmony_ci  Response response = scope.initialize();
13021cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
13031cb0ef41Sopenharmony_ci  v8::Local<v8::Value> newValue;
13041cb0ef41Sopenharmony_ci  response = scope.injectedScript()->resolveCallArgument(newValueArgument.get(),
13051cb0ef41Sopenharmony_ci                                                         &newValue);
13061cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
13071cb0ef41Sopenharmony_ci
13081cb0ef41Sopenharmony_ci  int frameOrdinal = static_cast<int>(scope.frameOrdinal());
13091cb0ef41Sopenharmony_ci  auto it = v8::debug::StackTraceIterator::Create(m_isolate, frameOrdinal);
13101cb0ef41Sopenharmony_ci  if (it->Done()) {
13111cb0ef41Sopenharmony_ci    return Response::ServerError("Could not find call frame with given id");
13121cb0ef41Sopenharmony_ci  }
13131cb0ef41Sopenharmony_ci  auto scopeIterator = it->GetScopeIterator();
13141cb0ef41Sopenharmony_ci  while (!scopeIterator->Done() && scopeNumber > 0) {
13151cb0ef41Sopenharmony_ci    --scopeNumber;
13161cb0ef41Sopenharmony_ci    scopeIterator->Advance();
13171cb0ef41Sopenharmony_ci  }
13181cb0ef41Sopenharmony_ci  if (scopeNumber != 0) {
13191cb0ef41Sopenharmony_ci    return Response::ServerError("Could not find scope with given number");
13201cb0ef41Sopenharmony_ci  }
13211cb0ef41Sopenharmony_ci
13221cb0ef41Sopenharmony_ci  if (!scopeIterator->SetVariableValue(toV8String(m_isolate, variableName),
13231cb0ef41Sopenharmony_ci                                       newValue) ||
13241cb0ef41Sopenharmony_ci      scope.tryCatch().HasCaught()) {
13251cb0ef41Sopenharmony_ci    return Response::InternalError();
13261cb0ef41Sopenharmony_ci  }
13271cb0ef41Sopenharmony_ci  return Response::Success();
13281cb0ef41Sopenharmony_ci}
13291cb0ef41Sopenharmony_ci
13301cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setReturnValue(
13311cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Runtime::CallArgument> protocolNewValue) {
13321cb0ef41Sopenharmony_ci  if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
13331cb0ef41Sopenharmony_ci  if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
13341cb0ef41Sopenharmony_ci  v8::HandleScope handleScope(m_isolate);
13351cb0ef41Sopenharmony_ci  auto iterator = v8::debug::StackTraceIterator::Create(m_isolate);
13361cb0ef41Sopenharmony_ci  if (iterator->Done()) {
13371cb0ef41Sopenharmony_ci    return Response::ServerError("Could not find top call frame");
13381cb0ef41Sopenharmony_ci  }
13391cb0ef41Sopenharmony_ci  if (iterator->GetReturnValue().IsEmpty()) {
13401cb0ef41Sopenharmony_ci    return Response::ServerError(
13411cb0ef41Sopenharmony_ci        "Could not update return value at non-return position");
13421cb0ef41Sopenharmony_ci  }
13431cb0ef41Sopenharmony_ci  InjectedScript::ContextScope scope(m_session, iterator->GetContextId());
13441cb0ef41Sopenharmony_ci  Response response = scope.initialize();
13451cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
13461cb0ef41Sopenharmony_ci  v8::Local<v8::Value> newValue;
13471cb0ef41Sopenharmony_ci  response = scope.injectedScript()->resolveCallArgument(protocolNewValue.get(),
13481cb0ef41Sopenharmony_ci                                                         &newValue);
13491cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
13501cb0ef41Sopenharmony_ci  v8::debug::SetReturnValue(m_isolate, newValue);
13511cb0ef41Sopenharmony_ci  return Response::Success();
13521cb0ef41Sopenharmony_ci}
13531cb0ef41Sopenharmony_ci
13541cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setAsyncCallStackDepth(int depth) {
13551cb0ef41Sopenharmony_ci  if (!enabled() && !m_session->runtimeAgent()->enabled()) {
13561cb0ef41Sopenharmony_ci    return Response::ServerError(kDebuggerNotEnabled);
13571cb0ef41Sopenharmony_ci  }
13581cb0ef41Sopenharmony_ci  m_state->setInteger(DebuggerAgentState::asyncCallStackDepth, depth);
13591cb0ef41Sopenharmony_ci  m_debugger->setAsyncCallStackDepth(this, depth);
13601cb0ef41Sopenharmony_ci  return Response::Success();
13611cb0ef41Sopenharmony_ci}
13621cb0ef41Sopenharmony_ci
13631cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBlackboxPatterns(
13641cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Array<String16>> patterns) {
13651cb0ef41Sopenharmony_ci  if (patterns->empty()) {
13661cb0ef41Sopenharmony_ci    m_blackboxPattern = nullptr;
13671cb0ef41Sopenharmony_ci    resetBlackboxedStateCache();
13681cb0ef41Sopenharmony_ci    m_state->remove(DebuggerAgentState::blackboxPattern);
13691cb0ef41Sopenharmony_ci    return Response::Success();
13701cb0ef41Sopenharmony_ci  }
13711cb0ef41Sopenharmony_ci
13721cb0ef41Sopenharmony_ci  String16Builder patternBuilder;
13731cb0ef41Sopenharmony_ci  patternBuilder.append('(');
13741cb0ef41Sopenharmony_ci  for (size_t i = 0; i < patterns->size() - 1; ++i) {
13751cb0ef41Sopenharmony_ci    patternBuilder.append((*patterns)[i]);
13761cb0ef41Sopenharmony_ci    patternBuilder.append("|");
13771cb0ef41Sopenharmony_ci  }
13781cb0ef41Sopenharmony_ci  patternBuilder.append(patterns->back());
13791cb0ef41Sopenharmony_ci  patternBuilder.append(')');
13801cb0ef41Sopenharmony_ci  String16 pattern = patternBuilder.toString();
13811cb0ef41Sopenharmony_ci  Response response = setBlackboxPattern(pattern);
13821cb0ef41Sopenharmony_ci  if (!response.IsSuccess()) return response;
13831cb0ef41Sopenharmony_ci  resetBlackboxedStateCache();
13841cb0ef41Sopenharmony_ci  m_state->setString(DebuggerAgentState::blackboxPattern, pattern);
13851cb0ef41Sopenharmony_ci  return Response::Success();
13861cb0ef41Sopenharmony_ci}
13871cb0ef41Sopenharmony_ci
13881cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBlackboxPattern(const String16& pattern) {
13891cb0ef41Sopenharmony_ci  std::unique_ptr<V8Regex> regex(new V8Regex(
13901cb0ef41Sopenharmony_ci      m_inspector, pattern, true /** caseSensitive */, false /** multiline */));
13911cb0ef41Sopenharmony_ci  if (!regex->isValid())
13921cb0ef41Sopenharmony_ci    return Response::ServerError("Pattern parser error: " +
13931cb0ef41Sopenharmony_ci                                 regex->errorMessage().utf8());
13941cb0ef41Sopenharmony_ci  m_blackboxPattern = std::move(regex);
13951cb0ef41Sopenharmony_ci  return Response::Success();
13961cb0ef41Sopenharmony_ci}
13971cb0ef41Sopenharmony_ci
13981cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::resetBlackboxedStateCache() {
13991cb0ef41Sopenharmony_ci  for (const auto& it : m_scripts) {
14001cb0ef41Sopenharmony_ci    it.second->resetBlackboxedStateCache();
14011cb0ef41Sopenharmony_ci  }
14021cb0ef41Sopenharmony_ci}
14031cb0ef41Sopenharmony_ci
14041cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::setBlackboxedRanges(
14051cb0ef41Sopenharmony_ci    const String16& scriptId,
14061cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Array<protocol::Debugger::ScriptPosition>>
14071cb0ef41Sopenharmony_ci        inPositions) {
14081cb0ef41Sopenharmony_ci  auto it = m_scripts.find(scriptId);
14091cb0ef41Sopenharmony_ci  if (it == m_scripts.end())
14101cb0ef41Sopenharmony_ci    return Response::ServerError("No script with passed id.");
14111cb0ef41Sopenharmony_ci
14121cb0ef41Sopenharmony_ci  if (inPositions->empty()) {
14131cb0ef41Sopenharmony_ci    m_blackboxedPositions.erase(scriptId);
14141cb0ef41Sopenharmony_ci    it->second->resetBlackboxedStateCache();
14151cb0ef41Sopenharmony_ci    return Response::Success();
14161cb0ef41Sopenharmony_ci  }
14171cb0ef41Sopenharmony_ci
14181cb0ef41Sopenharmony_ci  std::vector<std::pair<int, int>> positions;
14191cb0ef41Sopenharmony_ci  positions.reserve(inPositions->size());
14201cb0ef41Sopenharmony_ci  for (const std::unique_ptr<protocol::Debugger::ScriptPosition>& position :
14211cb0ef41Sopenharmony_ci       *inPositions) {
14221cb0ef41Sopenharmony_ci    Response res = isValidPosition(position.get());
14231cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
14241cb0ef41Sopenharmony_ci
14251cb0ef41Sopenharmony_ci    positions.push_back(
14261cb0ef41Sopenharmony_ci        std::make_pair(position->getLineNumber(), position->getColumnNumber()));
14271cb0ef41Sopenharmony_ci  }
14281cb0ef41Sopenharmony_ci  Response res = isValidRangeOfPositions(positions);
14291cb0ef41Sopenharmony_ci  if (res.IsError()) return res;
14301cb0ef41Sopenharmony_ci
14311cb0ef41Sopenharmony_ci  m_blackboxedPositions[scriptId] = positions;
14321cb0ef41Sopenharmony_ci  it->second->resetBlackboxedStateCache();
14331cb0ef41Sopenharmony_ci  return Response::Success();
14341cb0ef41Sopenharmony_ci}
14351cb0ef41Sopenharmony_ci
14361cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::currentCallFrames(
14371cb0ef41Sopenharmony_ci    std::unique_ptr<Array<CallFrame>>* result) {
14381cb0ef41Sopenharmony_ci  if (!isPaused()) {
14391cb0ef41Sopenharmony_ci    *result = std::make_unique<Array<CallFrame>>();
14401cb0ef41Sopenharmony_ci    return Response::Success();
14411cb0ef41Sopenharmony_ci  }
14421cb0ef41Sopenharmony_ci  v8::HandleScope handles(m_isolate);
14431cb0ef41Sopenharmony_ci  *result = std::make_unique<Array<CallFrame>>();
14441cb0ef41Sopenharmony_ci  auto iterator = v8::debug::StackTraceIterator::Create(m_isolate);
14451cb0ef41Sopenharmony_ci  int frameOrdinal = 0;
14461cb0ef41Sopenharmony_ci  for (; !iterator->Done(); iterator->Advance(), frameOrdinal++) {
14471cb0ef41Sopenharmony_ci    int contextId = iterator->GetContextId();
14481cb0ef41Sopenharmony_ci    InjectedScript* injectedScript = nullptr;
14491cb0ef41Sopenharmony_ci    if (contextId) m_session->findInjectedScript(contextId, injectedScript);
14501cb0ef41Sopenharmony_ci    String16 callFrameId = RemoteCallFrameId::serialize(
14511cb0ef41Sopenharmony_ci        m_inspector->isolateId(), contextId, frameOrdinal);
14521cb0ef41Sopenharmony_ci
14531cb0ef41Sopenharmony_ci    v8::debug::Location loc = iterator->GetSourceLocation();
14541cb0ef41Sopenharmony_ci
14551cb0ef41Sopenharmony_ci    std::unique_ptr<Array<Scope>> scopes;
14561cb0ef41Sopenharmony_ci    auto scopeIterator = iterator->GetScopeIterator();
14571cb0ef41Sopenharmony_ci    Response res =
14581cb0ef41Sopenharmony_ci        buildScopes(m_isolate, scopeIterator.get(), injectedScript, &scopes);
14591cb0ef41Sopenharmony_ci    if (!res.IsSuccess()) return res;
14601cb0ef41Sopenharmony_ci
14611cb0ef41Sopenharmony_ci    std::unique_ptr<RemoteObject> protocolReceiver;
14621cb0ef41Sopenharmony_ci    if (injectedScript) {
14631cb0ef41Sopenharmony_ci      v8::Local<v8::Value> receiver;
14641cb0ef41Sopenharmony_ci      if (iterator->GetReceiver().ToLocal(&receiver)) {
14651cb0ef41Sopenharmony_ci        res =
14661cb0ef41Sopenharmony_ci            injectedScript->wrapObject(receiver, kBacktraceObjectGroup,
14671cb0ef41Sopenharmony_ci                                       WrapMode::kNoPreview, &protocolReceiver);
14681cb0ef41Sopenharmony_ci        if (!res.IsSuccess()) return res;
14691cb0ef41Sopenharmony_ci      }
14701cb0ef41Sopenharmony_ci    }
14711cb0ef41Sopenharmony_ci    if (!protocolReceiver) {
14721cb0ef41Sopenharmony_ci      protocolReceiver = RemoteObject::create()
14731cb0ef41Sopenharmony_ci                             .setType(RemoteObject::TypeEnum::Undefined)
14741cb0ef41Sopenharmony_ci                             .build();
14751cb0ef41Sopenharmony_ci    }
14761cb0ef41Sopenharmony_ci
14771cb0ef41Sopenharmony_ci    v8::Local<v8::debug::Script> script = iterator->GetScript();
14781cb0ef41Sopenharmony_ci    DCHECK(!script.IsEmpty());
14791cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::Debugger::Location> location =
14801cb0ef41Sopenharmony_ci        protocol::Debugger::Location::create()
14811cb0ef41Sopenharmony_ci            .setScriptId(String16::fromInteger(script->Id()))
14821cb0ef41Sopenharmony_ci            .setLineNumber(loc.GetLineNumber())
14831cb0ef41Sopenharmony_ci            .setColumnNumber(loc.GetColumnNumber())
14841cb0ef41Sopenharmony_ci            .build();
14851cb0ef41Sopenharmony_ci
14861cb0ef41Sopenharmony_ci    auto frame = CallFrame::create()
14871cb0ef41Sopenharmony_ci                     .setCallFrameId(callFrameId)
14881cb0ef41Sopenharmony_ci                     .setFunctionName(toProtocolString(
14891cb0ef41Sopenharmony_ci                         m_isolate, iterator->GetFunctionDebugName()))
14901cb0ef41Sopenharmony_ci                     .setLocation(std::move(location))
14911cb0ef41Sopenharmony_ci                     .setUrl(String16())
14921cb0ef41Sopenharmony_ci                     .setScopeChain(std::move(scopes))
14931cb0ef41Sopenharmony_ci                     .setThis(std::move(protocolReceiver))
14941cb0ef41Sopenharmony_ci                     .build();
14951cb0ef41Sopenharmony_ci
14961cb0ef41Sopenharmony_ci    v8::Local<v8::Function> func = iterator->GetFunction();
14971cb0ef41Sopenharmony_ci    if (!func.IsEmpty()) {
14981cb0ef41Sopenharmony_ci      frame->setFunctionLocation(
14991cb0ef41Sopenharmony_ci          protocol::Debugger::Location::create()
15001cb0ef41Sopenharmony_ci              .setScriptId(String16::fromInteger(func->ScriptId()))
15011cb0ef41Sopenharmony_ci              .setLineNumber(func->GetScriptLineNumber())
15021cb0ef41Sopenharmony_ci              .setColumnNumber(func->GetScriptColumnNumber())
15031cb0ef41Sopenharmony_ci              .build());
15041cb0ef41Sopenharmony_ci    }
15051cb0ef41Sopenharmony_ci
15061cb0ef41Sopenharmony_ci    v8::Local<v8::Value> returnValue = iterator->GetReturnValue();
15071cb0ef41Sopenharmony_ci    if (!returnValue.IsEmpty() && injectedScript) {
15081cb0ef41Sopenharmony_ci      std::unique_ptr<RemoteObject> value;
15091cb0ef41Sopenharmony_ci      res = injectedScript->wrapObject(returnValue, kBacktraceObjectGroup,
15101cb0ef41Sopenharmony_ci                                       WrapMode::kNoPreview, &value);
15111cb0ef41Sopenharmony_ci      if (!res.IsSuccess()) return res;
15121cb0ef41Sopenharmony_ci      frame->setReturnValue(std::move(value));
15131cb0ef41Sopenharmony_ci    }
15141cb0ef41Sopenharmony_ci    (*result)->emplace_back(std::move(frame));
15151cb0ef41Sopenharmony_ci  }
15161cb0ef41Sopenharmony_ci  return Response::Success();
15171cb0ef41Sopenharmony_ci}
15181cb0ef41Sopenharmony_ci
15191cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTrace>
15201cb0ef41Sopenharmony_ciV8DebuggerAgentImpl::currentAsyncStackTrace() {
15211cb0ef41Sopenharmony_ci  std::shared_ptr<AsyncStackTrace> asyncParent =
15221cb0ef41Sopenharmony_ci      m_debugger->currentAsyncParent();
15231cb0ef41Sopenharmony_ci  if (!asyncParent) return nullptr;
15241cb0ef41Sopenharmony_ci  return asyncParent->buildInspectorObject(
15251cb0ef41Sopenharmony_ci      m_debugger, m_debugger->maxAsyncCallChainDepth() - 1);
15261cb0ef41Sopenharmony_ci}
15271cb0ef41Sopenharmony_ci
15281cb0ef41Sopenharmony_cistd::unique_ptr<protocol::Runtime::StackTraceId>
15291cb0ef41Sopenharmony_ciV8DebuggerAgentImpl::currentExternalStackTrace() {
15301cb0ef41Sopenharmony_ci  V8StackTraceId externalParent = m_debugger->currentExternalParent();
15311cb0ef41Sopenharmony_ci  if (externalParent.IsInvalid()) return nullptr;
15321cb0ef41Sopenharmony_ci  return protocol::Runtime::StackTraceId::create()
15331cb0ef41Sopenharmony_ci      .setId(stackTraceIdToString(externalParent.id))
15341cb0ef41Sopenharmony_ci      .setDebuggerId(
15351cb0ef41Sopenharmony_ci          internal::V8DebuggerId(externalParent.debugger_id).toString())
15361cb0ef41Sopenharmony_ci      .build();
15371cb0ef41Sopenharmony_ci}
15381cb0ef41Sopenharmony_ci
15391cb0ef41Sopenharmony_cibool V8DebuggerAgentImpl::isPaused() const {
15401cb0ef41Sopenharmony_ci  return m_debugger->isPausedInContextGroup(m_session->contextGroupId());
15411cb0ef41Sopenharmony_ci}
15421cb0ef41Sopenharmony_ci
15431cb0ef41Sopenharmony_cistatic String16 getScriptLanguage(const V8DebuggerScript& script) {
15441cb0ef41Sopenharmony_ci  switch (script.getLanguage()) {
15451cb0ef41Sopenharmony_ci    case V8DebuggerScript::Language::WebAssembly:
15461cb0ef41Sopenharmony_ci      return protocol::Debugger::ScriptLanguageEnum::WebAssembly;
15471cb0ef41Sopenharmony_ci    case V8DebuggerScript::Language::JavaScript:
15481cb0ef41Sopenharmony_ci      return protocol::Debugger::ScriptLanguageEnum::JavaScript;
15491cb0ef41Sopenharmony_ci  }
15501cb0ef41Sopenharmony_ci}
15511cb0ef41Sopenharmony_ci
15521cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
15531cb0ef41Sopenharmony_cistatic const char* getDebugSymbolTypeName(
15541cb0ef41Sopenharmony_ci    v8::debug::WasmScript::DebugSymbolsType type) {
15551cb0ef41Sopenharmony_ci  switch (type) {
15561cb0ef41Sopenharmony_ci    case v8::debug::WasmScript::DebugSymbolsType::None:
15571cb0ef41Sopenharmony_ci      return v8_inspector::protocol::Debugger::DebugSymbols::TypeEnum::None;
15581cb0ef41Sopenharmony_ci    case v8::debug::WasmScript::DebugSymbolsType::SourceMap:
15591cb0ef41Sopenharmony_ci      return v8_inspector::protocol::Debugger::DebugSymbols::TypeEnum::
15601cb0ef41Sopenharmony_ci          SourceMap;
15611cb0ef41Sopenharmony_ci    case v8::debug::WasmScript::DebugSymbolsType::EmbeddedDWARF:
15621cb0ef41Sopenharmony_ci      return v8_inspector::protocol::Debugger::DebugSymbols::TypeEnum::
15631cb0ef41Sopenharmony_ci          EmbeddedDWARF;
15641cb0ef41Sopenharmony_ci    case v8::debug::WasmScript::DebugSymbolsType::ExternalDWARF:
15651cb0ef41Sopenharmony_ci      return v8_inspector::protocol::Debugger::DebugSymbols::TypeEnum::
15661cb0ef41Sopenharmony_ci          ExternalDWARF;
15671cb0ef41Sopenharmony_ci  }
15681cb0ef41Sopenharmony_ci}
15691cb0ef41Sopenharmony_ci
15701cb0ef41Sopenharmony_cistatic std::unique_ptr<protocol::Debugger::DebugSymbols> getDebugSymbols(
15711cb0ef41Sopenharmony_ci    const V8DebuggerScript& script) {
15721cb0ef41Sopenharmony_ci  v8::debug::WasmScript::DebugSymbolsType type;
15731cb0ef41Sopenharmony_ci  if (!script.getDebugSymbolsType().To(&type)) return {};
15741cb0ef41Sopenharmony_ci
15751cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Debugger::DebugSymbols> debugSymbols =
15761cb0ef41Sopenharmony_ci      v8_inspector::protocol::Debugger::DebugSymbols::create()
15771cb0ef41Sopenharmony_ci          .setType(getDebugSymbolTypeName(type))
15781cb0ef41Sopenharmony_ci          .build();
15791cb0ef41Sopenharmony_ci  String16 externalUrl;
15801cb0ef41Sopenharmony_ci  if (script.getExternalDebugSymbolsURL().To(&externalUrl)) {
15811cb0ef41Sopenharmony_ci    debugSymbols->setExternalURL(externalUrl);
15821cb0ef41Sopenharmony_ci  }
15831cb0ef41Sopenharmony_ci  return debugSymbols;
15841cb0ef41Sopenharmony_ci}
15851cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
15861cb0ef41Sopenharmony_ci
15871cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::didParseSource(
15881cb0ef41Sopenharmony_ci    std::unique_ptr<V8DebuggerScript> script, bool success) {
15891cb0ef41Sopenharmony_ci  v8::HandleScope handles(m_isolate);
15901cb0ef41Sopenharmony_ci  if (!success) {
15911cb0ef41Sopenharmony_ci    String16 scriptSource = script->source(0);
15921cb0ef41Sopenharmony_ci    script->setSourceURL(findSourceURL(scriptSource, false));
15931cb0ef41Sopenharmony_ci    script->setSourceMappingURL(findSourceMapURL(scriptSource, false));
15941cb0ef41Sopenharmony_ci  }
15951cb0ef41Sopenharmony_ci
15961cb0ef41Sopenharmony_ci  int contextId = script->executionContextId();
15971cb0ef41Sopenharmony_ci  int contextGroupId = m_inspector->contextGroupId(contextId);
15981cb0ef41Sopenharmony_ci  InspectedContext* inspected =
15991cb0ef41Sopenharmony_ci      m_inspector->getContext(contextGroupId, contextId);
16001cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::DictionaryValue> executionContextAuxData;
16011cb0ef41Sopenharmony_ci  if (inspected) {
16021cb0ef41Sopenharmony_ci    // Script reused between different groups/sessions can have a stale
16031cb0ef41Sopenharmony_ci    // execution context id.
16041cb0ef41Sopenharmony_ci    const String16& aux = inspected->auxData();
16051cb0ef41Sopenharmony_ci    std::vector<uint8_t> cbor;
16061cb0ef41Sopenharmony_ci    v8_crdtp::json::ConvertJSONToCBOR(
16071cb0ef41Sopenharmony_ci        v8_crdtp::span<uint16_t>(aux.characters16(), aux.length()), &cbor);
16081cb0ef41Sopenharmony_ci    executionContextAuxData = protocol::DictionaryValue::cast(
16091cb0ef41Sopenharmony_ci        protocol::Value::parseBinary(cbor.data(), cbor.size()));
16101cb0ef41Sopenharmony_ci  }
16111cb0ef41Sopenharmony_ci  bool isLiveEdit = script->isLiveEdit();
16121cb0ef41Sopenharmony_ci  bool hasSourceURLComment = script->hasSourceURLComment();
16131cb0ef41Sopenharmony_ci  bool isModule = script->isModule();
16141cb0ef41Sopenharmony_ci  String16 scriptId = script->scriptId();
16151cb0ef41Sopenharmony_ci  String16 scriptURL = script->sourceURL();
16161cb0ef41Sopenharmony_ci  String16 embedderName = script->embedderName();
16171cb0ef41Sopenharmony_ci  String16 scriptLanguage = getScriptLanguage(*script);
16181cb0ef41Sopenharmony_ci  Maybe<int> codeOffset;
16191cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Debugger::DebugSymbols> debugSymbols;
16201cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
16211cb0ef41Sopenharmony_ci  if (script->getLanguage() == V8DebuggerScript::Language::WebAssembly)
16221cb0ef41Sopenharmony_ci    codeOffset = script->codeOffset();
16231cb0ef41Sopenharmony_ci  debugSymbols = getDebugSymbols(*script);
16241cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
16251cb0ef41Sopenharmony_ci
16261cb0ef41Sopenharmony_ci  m_scripts[scriptId] = std::move(script);
16271cb0ef41Sopenharmony_ci  // Release the strong reference to get notified when debugger is the only
16281cb0ef41Sopenharmony_ci  // one that holds the script. Has to be done after script added to m_scripts.
16291cb0ef41Sopenharmony_ci  m_scripts[scriptId]->MakeWeak();
16301cb0ef41Sopenharmony_ci
16311cb0ef41Sopenharmony_ci  ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
16321cb0ef41Sopenharmony_ci  DCHECK(scriptIterator != m_scripts.end());
16331cb0ef41Sopenharmony_ci  V8DebuggerScript* scriptRef = scriptIterator->second.get();
16341cb0ef41Sopenharmony_ci  // V8 could create functions for parsed scripts before reporting and asks
16351cb0ef41Sopenharmony_ci  // inspector about blackboxed state, we should reset state each time when we
16361cb0ef41Sopenharmony_ci  // make any change that change isFunctionBlackboxed output - adding parsed
16371cb0ef41Sopenharmony_ci  // script is changing.
16381cb0ef41Sopenharmony_ci  scriptRef->resetBlackboxedStateCache();
16391cb0ef41Sopenharmony_ci
16401cb0ef41Sopenharmony_ci  Maybe<String16> sourceMapURLParam = scriptRef->sourceMappingURL();
16411cb0ef41Sopenharmony_ci  Maybe<protocol::DictionaryValue> executionContextAuxDataParam(
16421cb0ef41Sopenharmony_ci      std::move(executionContextAuxData));
16431cb0ef41Sopenharmony_ci  const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
16441cb0ef41Sopenharmony_ci  const bool* hasSourceURLParam =
16451cb0ef41Sopenharmony_ci      hasSourceURLComment ? &hasSourceURLComment : nullptr;
16461cb0ef41Sopenharmony_ci  const bool* isModuleParam = isModule ? &isModule : nullptr;
16471cb0ef41Sopenharmony_ci  std::unique_ptr<V8StackTraceImpl> stack =
16481cb0ef41Sopenharmony_ci      V8StackTraceImpl::capture(m_inspector->debugger(), 1);
16491cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::Runtime::StackTrace> stackTrace =
16501cb0ef41Sopenharmony_ci      stack && !stack->isEmpty()
16511cb0ef41Sopenharmony_ci          ? stack->buildInspectorObjectImpl(m_debugger, 0)
16521cb0ef41Sopenharmony_ci          : nullptr;
16531cb0ef41Sopenharmony_ci
16541cb0ef41Sopenharmony_ci  if (!success) {
16551cb0ef41Sopenharmony_ci    m_frontend.scriptFailedToParse(
16561cb0ef41Sopenharmony_ci        scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(),
16571cb0ef41Sopenharmony_ci        scriptRef->endLine(), scriptRef->endColumn(), contextId,
16581cb0ef41Sopenharmony_ci        scriptRef->hash(), std::move(executionContextAuxDataParam),
16591cb0ef41Sopenharmony_ci        std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam,
16601cb0ef41Sopenharmony_ci        scriptRef->length(), std::move(stackTrace), std::move(codeOffset),
16611cb0ef41Sopenharmony_ci        std::move(scriptLanguage), embedderName);
16621cb0ef41Sopenharmony_ci    return;
16631cb0ef41Sopenharmony_ci  }
16641cb0ef41Sopenharmony_ci
16651cb0ef41Sopenharmony_ci  m_frontend.scriptParsed(
16661cb0ef41Sopenharmony_ci      scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(),
16671cb0ef41Sopenharmony_ci      scriptRef->endLine(), scriptRef->endColumn(), contextId,
16681cb0ef41Sopenharmony_ci      scriptRef->hash(), std::move(executionContextAuxDataParam),
16691cb0ef41Sopenharmony_ci      isLiveEditParam, std::move(sourceMapURLParam), hasSourceURLParam,
16701cb0ef41Sopenharmony_ci      isModuleParam, scriptRef->length(), std::move(stackTrace),
16711cb0ef41Sopenharmony_ci      std::move(codeOffset), std::move(scriptLanguage), std::move(debugSymbols),
16721cb0ef41Sopenharmony_ci      embedderName);
16731cb0ef41Sopenharmony_ci
16741cb0ef41Sopenharmony_ci  std::vector<protocol::DictionaryValue*> potentialBreakpoints;
16751cb0ef41Sopenharmony_ci  if (!scriptURL.isEmpty()) {
16761cb0ef41Sopenharmony_ci    protocol::DictionaryValue* breakpointsByUrl =
16771cb0ef41Sopenharmony_ci        m_state->getObject(DebuggerAgentState::breakpointsByUrl);
16781cb0ef41Sopenharmony_ci    if (breakpointsByUrl) {
16791cb0ef41Sopenharmony_ci      potentialBreakpoints.push_back(breakpointsByUrl->getObject(scriptURL));
16801cb0ef41Sopenharmony_ci    }
16811cb0ef41Sopenharmony_ci    potentialBreakpoints.push_back(
16821cb0ef41Sopenharmony_ci        m_state->getObject(DebuggerAgentState::breakpointsByRegex));
16831cb0ef41Sopenharmony_ci  }
16841cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpointsByScriptHash =
16851cb0ef41Sopenharmony_ci      m_state->getObject(DebuggerAgentState::breakpointsByScriptHash);
16861cb0ef41Sopenharmony_ci  if (breakpointsByScriptHash) {
16871cb0ef41Sopenharmony_ci    potentialBreakpoints.push_back(
16881cb0ef41Sopenharmony_ci        breakpointsByScriptHash->getObject(scriptRef->hash()));
16891cb0ef41Sopenharmony_ci  }
16901cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpointHints =
16911cb0ef41Sopenharmony_ci      m_state->getObject(DebuggerAgentState::breakpointHints);
16921cb0ef41Sopenharmony_ci  for (auto breakpoints : potentialBreakpoints) {
16931cb0ef41Sopenharmony_ci    if (!breakpoints) continue;
16941cb0ef41Sopenharmony_ci    for (size_t i = 0; i < breakpoints->size(); ++i) {
16951cb0ef41Sopenharmony_ci      auto breakpointWithCondition = breakpoints->at(i);
16961cb0ef41Sopenharmony_ci      String16 breakpointId = breakpointWithCondition.first;
16971cb0ef41Sopenharmony_ci
16981cb0ef41Sopenharmony_ci      BreakpointType type;
16991cb0ef41Sopenharmony_ci      String16 selector;
17001cb0ef41Sopenharmony_ci      int lineNumber = 0;
17011cb0ef41Sopenharmony_ci      int columnNumber = 0;
17021cb0ef41Sopenharmony_ci      parseBreakpointId(breakpointId, &type, &selector, &lineNumber,
17031cb0ef41Sopenharmony_ci                        &columnNumber);
17041cb0ef41Sopenharmony_ci
17051cb0ef41Sopenharmony_ci      if (!matches(m_inspector, *scriptRef, type, selector)) continue;
17061cb0ef41Sopenharmony_ci      String16 condition;
17071cb0ef41Sopenharmony_ci      breakpointWithCondition.second->asString(&condition);
17081cb0ef41Sopenharmony_ci      String16 hint;
17091cb0ef41Sopenharmony_ci      bool hasHint =
17101cb0ef41Sopenharmony_ci          breakpointHints && breakpointHints->getString(breakpointId, &hint);
17111cb0ef41Sopenharmony_ci      if (hasHint) {
17121cb0ef41Sopenharmony_ci        adjustBreakpointLocation(*scriptRef, hint, &lineNumber, &columnNumber);
17131cb0ef41Sopenharmony_ci      }
17141cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Debugger::Location> location =
17151cb0ef41Sopenharmony_ci          setBreakpointImpl(breakpointId, scriptId, condition, lineNumber,
17161cb0ef41Sopenharmony_ci                            columnNumber);
17171cb0ef41Sopenharmony_ci      if (location)
17181cb0ef41Sopenharmony_ci        m_frontend.breakpointResolved(breakpointId, std::move(location));
17191cb0ef41Sopenharmony_ci    }
17201cb0ef41Sopenharmony_ci  }
17211cb0ef41Sopenharmony_ci  setScriptInstrumentationBreakpointIfNeeded(scriptRef);
17221cb0ef41Sopenharmony_ci}
17231cb0ef41Sopenharmony_ci
17241cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::setScriptInstrumentationBreakpointIfNeeded(
17251cb0ef41Sopenharmony_ci    V8DebuggerScript* scriptRef) {
17261cb0ef41Sopenharmony_ci  protocol::DictionaryValue* breakpoints =
17271cb0ef41Sopenharmony_ci      m_state->getObject(DebuggerAgentState::instrumentationBreakpoints);
17281cb0ef41Sopenharmony_ci  if (!breakpoints) return;
17291cb0ef41Sopenharmony_ci  bool isBlackboxed = isFunctionBlackboxed(
17301cb0ef41Sopenharmony_ci      scriptRef->scriptId(), v8::debug::Location(0, 0),
17311cb0ef41Sopenharmony_ci      v8::debug::Location(scriptRef->endLine(), scriptRef->endColumn()));
17321cb0ef41Sopenharmony_ci  if (isBlackboxed) return;
17331cb0ef41Sopenharmony_ci
17341cb0ef41Sopenharmony_ci  String16 sourceMapURL = scriptRef->sourceMappingURL();
17351cb0ef41Sopenharmony_ci  String16 breakpointId = generateInstrumentationBreakpointId(
17361cb0ef41Sopenharmony_ci      InstrumentationEnum::BeforeScriptExecution);
17371cb0ef41Sopenharmony_ci  if (!breakpoints->get(breakpointId)) {
17381cb0ef41Sopenharmony_ci    if (sourceMapURL.isEmpty()) return;
17391cb0ef41Sopenharmony_ci    breakpointId = generateInstrumentationBreakpointId(
17401cb0ef41Sopenharmony_ci        InstrumentationEnum::BeforeScriptWithSourceMapExecution);
17411cb0ef41Sopenharmony_ci    if (!breakpoints->get(breakpointId)) return;
17421cb0ef41Sopenharmony_ci  }
17431cb0ef41Sopenharmony_ci  v8::debug::BreakpointId debuggerBreakpointId;
17441cb0ef41Sopenharmony_ci  if (!scriptRef->setInstrumentationBreakpoint(&debuggerBreakpointId)) return;
17451cb0ef41Sopenharmony_ci
17461cb0ef41Sopenharmony_ci  m_debuggerBreakpointIdToBreakpointId[debuggerBreakpointId] = breakpointId;
17471cb0ef41Sopenharmony_ci  m_breakpointIdToDebuggerBreakpointIds[breakpointId].push_back(
17481cb0ef41Sopenharmony_ci      debuggerBreakpointId);
17491cb0ef41Sopenharmony_ci}
17501cb0ef41Sopenharmony_ci
17511cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::didPauseOnInstrumentation(
17521cb0ef41Sopenharmony_ci    v8::debug::BreakpointId instrumentationId) {
17531cb0ef41Sopenharmony_ci  String16 breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
17541cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::DictionaryValue> breakAuxData;
17551cb0ef41Sopenharmony_ci
17561cb0ef41Sopenharmony_ci  std::unique_ptr<Array<CallFrame>> protocolCallFrames;
17571cb0ef41Sopenharmony_ci  Response response = currentCallFrames(&protocolCallFrames);
17581cb0ef41Sopenharmony_ci  if (!response.IsSuccess())
17591cb0ef41Sopenharmony_ci    protocolCallFrames = std::make_unique<Array<CallFrame>>();
17601cb0ef41Sopenharmony_ci
17611cb0ef41Sopenharmony_ci  if (m_debuggerBreakpointIdToBreakpointId.find(instrumentationId) !=
17621cb0ef41Sopenharmony_ci      m_debuggerBreakpointIdToBreakpointId.end()) {
17631cb0ef41Sopenharmony_ci    DCHECK_GT(protocolCallFrames->size(), 0);
17641cb0ef41Sopenharmony_ci    if (protocolCallFrames->size() > 0) {
17651cb0ef41Sopenharmony_ci      breakReason = protocol::Debugger::Paused::ReasonEnum::Instrumentation;
17661cb0ef41Sopenharmony_ci      const String16 scriptId =
17671cb0ef41Sopenharmony_ci          protocolCallFrames->at(0)->getLocation()->getScriptId();
17681cb0ef41Sopenharmony_ci      DCHECK_NE(m_scripts.find(scriptId), m_scripts.end());
17691cb0ef41Sopenharmony_ci      const auto& script = m_scripts[scriptId];
17701cb0ef41Sopenharmony_ci
17711cb0ef41Sopenharmony_ci      breakAuxData = protocol::DictionaryValue::create();
17721cb0ef41Sopenharmony_ci      breakAuxData->setString("scriptId", script->scriptId());
17731cb0ef41Sopenharmony_ci      breakAuxData->setString("url", script->sourceURL());
17741cb0ef41Sopenharmony_ci      if (!script->sourceMappingURL().isEmpty()) {
17751cb0ef41Sopenharmony_ci        breakAuxData->setString("sourceMapURL", (script->sourceMappingURL()));
17761cb0ef41Sopenharmony_ci      }
17771cb0ef41Sopenharmony_ci    }
17781cb0ef41Sopenharmony_ci  }
17791cb0ef41Sopenharmony_ci
17801cb0ef41Sopenharmony_ci  m_frontend.paused(std::move(protocolCallFrames), breakReason,
17811cb0ef41Sopenharmony_ci                    std::move(breakAuxData),
17821cb0ef41Sopenharmony_ci                    std::make_unique<Array<String16>>(),
17831cb0ef41Sopenharmony_ci                    currentAsyncStackTrace(), currentExternalStackTrace());
17841cb0ef41Sopenharmony_ci}
17851cb0ef41Sopenharmony_ci
17861cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::didPause(
17871cb0ef41Sopenharmony_ci    int contextId, v8::Local<v8::Value> exception,
17881cb0ef41Sopenharmony_ci    const std::vector<v8::debug::BreakpointId>& hitBreakpoints,
17891cb0ef41Sopenharmony_ci    v8::debug::ExceptionType exceptionType, bool isUncaught,
17901cb0ef41Sopenharmony_ci    v8::debug::BreakReasons breakReasons) {
17911cb0ef41Sopenharmony_ci  v8::HandleScope handles(m_isolate);
17921cb0ef41Sopenharmony_ci
17931cb0ef41Sopenharmony_ci  std::vector<BreakReason> hitReasons;
17941cb0ef41Sopenharmony_ci
17951cb0ef41Sopenharmony_ci  if (breakReasons.contains(v8::debug::BreakReason::kOOM)) {
17961cb0ef41Sopenharmony_ci    hitReasons.push_back(
17971cb0ef41Sopenharmony_ci        std::make_pair(protocol::Debugger::Paused::ReasonEnum::OOM, nullptr));
17981cb0ef41Sopenharmony_ci  } else if (breakReasons.contains(v8::debug::BreakReason::kAssert)) {
17991cb0ef41Sopenharmony_ci    hitReasons.push_back(std::make_pair(
18001cb0ef41Sopenharmony_ci        protocol::Debugger::Paused::ReasonEnum::Assert, nullptr));
18011cb0ef41Sopenharmony_ci  } else if (breakReasons.contains(v8::debug::BreakReason::kException)) {
18021cb0ef41Sopenharmony_ci    InjectedScript* injectedScript = nullptr;
18031cb0ef41Sopenharmony_ci    m_session->findInjectedScript(contextId, injectedScript);
18041cb0ef41Sopenharmony_ci    if (injectedScript) {
18051cb0ef41Sopenharmony_ci      String16 breakReason =
18061cb0ef41Sopenharmony_ci          exceptionType == v8::debug::kPromiseRejection
18071cb0ef41Sopenharmony_ci              ? protocol::Debugger::Paused::ReasonEnum::PromiseRejection
18081cb0ef41Sopenharmony_ci              : protocol::Debugger::Paused::ReasonEnum::Exception;
18091cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::Runtime::RemoteObject> obj;
18101cb0ef41Sopenharmony_ci      injectedScript->wrapObject(exception, kBacktraceObjectGroup,
18111cb0ef41Sopenharmony_ci                                 WrapMode::kNoPreview, &obj);
18121cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::DictionaryValue> breakAuxData;
18131cb0ef41Sopenharmony_ci      if (obj) {
18141cb0ef41Sopenharmony_ci        std::vector<uint8_t> serialized;
18151cb0ef41Sopenharmony_ci        obj->AppendSerialized(&serialized);
18161cb0ef41Sopenharmony_ci        breakAuxData = protocol::DictionaryValue::cast(
18171cb0ef41Sopenharmony_ci            protocol::Value::parseBinary(serialized.data(), serialized.size()));
18181cb0ef41Sopenharmony_ci        breakAuxData->setBoolean("uncaught", isUncaught);
18191cb0ef41Sopenharmony_ci      }
18201cb0ef41Sopenharmony_ci      hitReasons.push_back(
18211cb0ef41Sopenharmony_ci          std::make_pair(breakReason, std::move(breakAuxData)));
18221cb0ef41Sopenharmony_ci    }
18231cb0ef41Sopenharmony_ci  }
18241cb0ef41Sopenharmony_ci
18251cb0ef41Sopenharmony_ci  auto hitBreakpointIds = std::make_unique<Array<String16>>();
18261cb0ef41Sopenharmony_ci  bool hitRegularBreakpoint = false;
18271cb0ef41Sopenharmony_ci  for (const auto& id : hitBreakpoints) {
18281cb0ef41Sopenharmony_ci    auto breakpointIterator = m_debuggerBreakpointIdToBreakpointId.find(id);
18291cb0ef41Sopenharmony_ci    if (breakpointIterator == m_debuggerBreakpointIdToBreakpointId.end()) {
18301cb0ef41Sopenharmony_ci      continue;
18311cb0ef41Sopenharmony_ci    }
18321cb0ef41Sopenharmony_ci    const String16& breakpointId = breakpointIterator->second;
18331cb0ef41Sopenharmony_ci    hitBreakpointIds->emplace_back(breakpointId);
18341cb0ef41Sopenharmony_ci    BreakpointType type;
18351cb0ef41Sopenharmony_ci    parseBreakpointId(breakpointId, &type);
18361cb0ef41Sopenharmony_ci    if (type == BreakpointType::kDebugCommand) {
18371cb0ef41Sopenharmony_ci      hitReasons.push_back(std::make_pair(
18381cb0ef41Sopenharmony_ci          protocol::Debugger::Paused::ReasonEnum::DebugCommand, nullptr));
18391cb0ef41Sopenharmony_ci    } else {
18401cb0ef41Sopenharmony_ci      hitRegularBreakpoint = true;
18411cb0ef41Sopenharmony_ci    }
18421cb0ef41Sopenharmony_ci  }
18431cb0ef41Sopenharmony_ci
18441cb0ef41Sopenharmony_ci  for (size_t i = 0; i < m_breakReason.size(); ++i) {
18451cb0ef41Sopenharmony_ci    hitReasons.push_back(std::move(m_breakReason[i]));
18461cb0ef41Sopenharmony_ci  }
18471cb0ef41Sopenharmony_ci  clearBreakDetails();
18481cb0ef41Sopenharmony_ci
18491cb0ef41Sopenharmony_ci  // Make sure that we only include (other: nullptr) once.
18501cb0ef41Sopenharmony_ci  const BreakReason otherHitReason =
18511cb0ef41Sopenharmony_ci      std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr);
18521cb0ef41Sopenharmony_ci  const bool otherBreakReasons =
18531cb0ef41Sopenharmony_ci      hitRegularBreakpoint || hitBreakReasonEncodedAsOther(breakReasons);
18541cb0ef41Sopenharmony_ci  if (otherBreakReasons && std::find(hitReasons.begin(), hitReasons.end(),
18551cb0ef41Sopenharmony_ci                                     otherHitReason) == hitReasons.end()) {
18561cb0ef41Sopenharmony_ci    hitReasons.push_back(
18571cb0ef41Sopenharmony_ci        std::make_pair(protocol::Debugger::Paused::ReasonEnum::Other, nullptr));
18581cb0ef41Sopenharmony_ci  }
18591cb0ef41Sopenharmony_ci
18601cb0ef41Sopenharmony_ci  // We should always know why we pause: either the pause relates to this agent
18611cb0ef41Sopenharmony_ci  // (`hitReason` is non empty), or it relates to another agent (hit a
18621cb0ef41Sopenharmony_ci  // breakpoint there, or a triggered pause was scheduled by other agent).
18631cb0ef41Sopenharmony_ci  DCHECK(hitReasons.size() > 0 || !hitBreakpoints.empty() ||
18641cb0ef41Sopenharmony_ci         breakReasons.contains(v8::debug::BreakReason::kAgent));
18651cb0ef41Sopenharmony_ci  String16 breakReason = protocol::Debugger::Paused::ReasonEnum::Other;
18661cb0ef41Sopenharmony_ci  std::unique_ptr<protocol::DictionaryValue> breakAuxData;
18671cb0ef41Sopenharmony_ci  if (hitReasons.size() == 1) {
18681cb0ef41Sopenharmony_ci    breakReason = hitReasons[0].first;
18691cb0ef41Sopenharmony_ci    breakAuxData = std::move(hitReasons[0].second);
18701cb0ef41Sopenharmony_ci  } else if (hitReasons.size() > 1) {
18711cb0ef41Sopenharmony_ci    breakReason = protocol::Debugger::Paused::ReasonEnum::Ambiguous;
18721cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::ListValue> reasons =
18731cb0ef41Sopenharmony_ci        protocol::ListValue::create();
18741cb0ef41Sopenharmony_ci    for (size_t i = 0; i < hitReasons.size(); ++i) {
18751cb0ef41Sopenharmony_ci      std::unique_ptr<protocol::DictionaryValue> reason =
18761cb0ef41Sopenharmony_ci          protocol::DictionaryValue::create();
18771cb0ef41Sopenharmony_ci      reason->setString("reason", hitReasons[i].first);
18781cb0ef41Sopenharmony_ci      if (hitReasons[i].second)
18791cb0ef41Sopenharmony_ci        reason->setObject("auxData", std::move(hitReasons[i].second));
18801cb0ef41Sopenharmony_ci      reasons->pushValue(std::move(reason));
18811cb0ef41Sopenharmony_ci    }
18821cb0ef41Sopenharmony_ci    breakAuxData = protocol::DictionaryValue::create();
18831cb0ef41Sopenharmony_ci    breakAuxData->setArray("reasons", std::move(reasons));
18841cb0ef41Sopenharmony_ci  }
18851cb0ef41Sopenharmony_ci
18861cb0ef41Sopenharmony_ci  std::unique_ptr<Array<CallFrame>> protocolCallFrames;
18871cb0ef41Sopenharmony_ci  Response response = currentCallFrames(&protocolCallFrames);
18881cb0ef41Sopenharmony_ci  if (!response.IsSuccess())
18891cb0ef41Sopenharmony_ci    protocolCallFrames = std::make_unique<Array<CallFrame>>();
18901cb0ef41Sopenharmony_ci
18911cb0ef41Sopenharmony_ci  m_frontend.paused(std::move(protocolCallFrames), breakReason,
18921cb0ef41Sopenharmony_ci                    std::move(breakAuxData), std::move(hitBreakpointIds),
18931cb0ef41Sopenharmony_ci                    currentAsyncStackTrace(), currentExternalStackTrace());
18941cb0ef41Sopenharmony_ci}
18951cb0ef41Sopenharmony_ci
18961cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::didContinue() {
18971cb0ef41Sopenharmony_ci  m_frontend.resumed();
18981cb0ef41Sopenharmony_ci  m_frontend.flush();
18991cb0ef41Sopenharmony_ci}
19001cb0ef41Sopenharmony_ci
19011cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::breakProgram(
19021cb0ef41Sopenharmony_ci    const String16& breakReason,
19031cb0ef41Sopenharmony_ci    std::unique_ptr<protocol::DictionaryValue> data) {
19041cb0ef41Sopenharmony_ci  if (!enabled() || m_skipAllPauses || !m_debugger->canBreakProgram()) return;
19051cb0ef41Sopenharmony_ci  std::vector<BreakReason> currentScheduledReason;
19061cb0ef41Sopenharmony_ci  currentScheduledReason.swap(m_breakReason);
19071cb0ef41Sopenharmony_ci  pushBreakDetails(breakReason, std::move(data));
19081cb0ef41Sopenharmony_ci
19091cb0ef41Sopenharmony_ci  int contextGroupId = m_session->contextGroupId();
19101cb0ef41Sopenharmony_ci  int sessionId = m_session->sessionId();
19111cb0ef41Sopenharmony_ci  V8InspectorImpl* inspector = m_inspector;
19121cb0ef41Sopenharmony_ci  m_debugger->breakProgram(contextGroupId);
19131cb0ef41Sopenharmony_ci  // Check that session and |this| are still around.
19141cb0ef41Sopenharmony_ci  if (!inspector->sessionById(contextGroupId, sessionId)) return;
19151cb0ef41Sopenharmony_ci  if (!enabled()) return;
19161cb0ef41Sopenharmony_ci
19171cb0ef41Sopenharmony_ci  popBreakDetails();
19181cb0ef41Sopenharmony_ci  m_breakReason.swap(currentScheduledReason);
19191cb0ef41Sopenharmony_ci  if (!m_breakReason.empty()) {
19201cb0ef41Sopenharmony_ci    m_debugger->setPauseOnNextCall(true, m_session->contextGroupId());
19211cb0ef41Sopenharmony_ci  }
19221cb0ef41Sopenharmony_ci}
19231cb0ef41Sopenharmony_ci
19241cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::setBreakpointFor(v8::Local<v8::Function> function,
19251cb0ef41Sopenharmony_ci                                           v8::Local<v8::String> condition,
19261cb0ef41Sopenharmony_ci                                           BreakpointSource source) {
19271cb0ef41Sopenharmony_ci  String16 breakpointId = generateBreakpointId(
19281cb0ef41Sopenharmony_ci      source == DebugCommandBreakpointSource ? BreakpointType::kDebugCommand
19291cb0ef41Sopenharmony_ci                                             : BreakpointType::kMonitorCommand,
19301cb0ef41Sopenharmony_ci      function);
19311cb0ef41Sopenharmony_ci  if (m_breakpointIdToDebuggerBreakpointIds.find(breakpointId) !=
19321cb0ef41Sopenharmony_ci      m_breakpointIdToDebuggerBreakpointIds.end()) {
19331cb0ef41Sopenharmony_ci    return;
19341cb0ef41Sopenharmony_ci  }
19351cb0ef41Sopenharmony_ci  setBreakpointImpl(breakpointId, function, condition);
19361cb0ef41Sopenharmony_ci}
19371cb0ef41Sopenharmony_ci
19381cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::removeBreakpointFor(v8::Local<v8::Function> function,
19391cb0ef41Sopenharmony_ci                                              BreakpointSource source) {
19401cb0ef41Sopenharmony_ci  String16 breakpointId = generateBreakpointId(
19411cb0ef41Sopenharmony_ci      source == DebugCommandBreakpointSource ? BreakpointType::kDebugCommand
19421cb0ef41Sopenharmony_ci                                             : BreakpointType::kMonitorCommand,
19431cb0ef41Sopenharmony_ci      function);
19441cb0ef41Sopenharmony_ci  std::vector<V8DebuggerScript*> scripts;
19451cb0ef41Sopenharmony_ci  removeBreakpointImpl(breakpointId, scripts);
19461cb0ef41Sopenharmony_ci}
19471cb0ef41Sopenharmony_ci
19481cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::reset() {
19491cb0ef41Sopenharmony_ci  if (!enabled()) return;
19501cb0ef41Sopenharmony_ci  m_blackboxedPositions.clear();
19511cb0ef41Sopenharmony_ci  resetBlackboxedStateCache();
19521cb0ef41Sopenharmony_ci  m_skipList.clear();
19531cb0ef41Sopenharmony_ci  m_scripts.clear();
19541cb0ef41Sopenharmony_ci  m_cachedScripts.clear();
19551cb0ef41Sopenharmony_ci  m_cachedScriptSize = 0;
19561cb0ef41Sopenharmony_ci}
19571cb0ef41Sopenharmony_ci
19581cb0ef41Sopenharmony_civoid V8DebuggerAgentImpl::ScriptCollected(const V8DebuggerScript* script) {
19591cb0ef41Sopenharmony_ci  DCHECK_NE(m_scripts.find(script->scriptId()), m_scripts.end());
19601cb0ef41Sopenharmony_ci  std::vector<uint8_t> bytecode;
19611cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
19621cb0ef41Sopenharmony_ci  v8::MemorySpan<const uint8_t> span;
19631cb0ef41Sopenharmony_ci  if (script->wasmBytecode().To(&span)) {
19641cb0ef41Sopenharmony_ci    bytecode.reserve(span.size());
19651cb0ef41Sopenharmony_ci    bytecode.insert(bytecode.begin(), span.data(), span.data() + span.size());
19661cb0ef41Sopenharmony_ci  }
19671cb0ef41Sopenharmony_ci#endif
19681cb0ef41Sopenharmony_ci  CachedScript cachedScript{script->scriptId(), script->source(0),
19691cb0ef41Sopenharmony_ci                            std::move(bytecode)};
19701cb0ef41Sopenharmony_ci  m_cachedScriptSize += cachedScript.size();
19711cb0ef41Sopenharmony_ci  m_cachedScripts.push_back(std::move(cachedScript));
19721cb0ef41Sopenharmony_ci  m_scripts.erase(script->scriptId());
19731cb0ef41Sopenharmony_ci
19741cb0ef41Sopenharmony_ci  while (m_cachedScriptSize > m_maxScriptCacheSize) {
19751cb0ef41Sopenharmony_ci    const CachedScript& cachedScript = m_cachedScripts.front();
19761cb0ef41Sopenharmony_ci    DCHECK_GE(m_cachedScriptSize, cachedScript.size());
19771cb0ef41Sopenharmony_ci    m_cachedScriptSize -= cachedScript.size();
19781cb0ef41Sopenharmony_ci    m_cachedScripts.pop_front();
19791cb0ef41Sopenharmony_ci  }
19801cb0ef41Sopenharmony_ci}
19811cb0ef41Sopenharmony_ci
19821cb0ef41Sopenharmony_ciResponse V8DebuggerAgentImpl::processSkipList(
19831cb0ef41Sopenharmony_ci    protocol::Array<protocol::Debugger::LocationRange>* skipList) {
19841cb0ef41Sopenharmony_ci  std::unordered_map<String16, std::vector<std::pair<int, int>>> skipListInit;
19851cb0ef41Sopenharmony_ci  for (std::unique_ptr<protocol::Debugger::LocationRange>& range : *skipList) {
19861cb0ef41Sopenharmony_ci    protocol::Debugger::ScriptPosition* start = range->getStart();
19871cb0ef41Sopenharmony_ci    protocol::Debugger::ScriptPosition* end = range->getEnd();
19881cb0ef41Sopenharmony_ci    String16 scriptId = range->getScriptId();
19891cb0ef41Sopenharmony_ci
19901cb0ef41Sopenharmony_ci    auto it = m_scripts.find(scriptId);
19911cb0ef41Sopenharmony_ci    if (it == m_scripts.end())
19921cb0ef41Sopenharmony_ci      return Response::ServerError("No script with passed id.");
19931cb0ef41Sopenharmony_ci
19941cb0ef41Sopenharmony_ci    Response res = isValidPosition(start);
19951cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
19961cb0ef41Sopenharmony_ci
19971cb0ef41Sopenharmony_ci    res = isValidPosition(end);
19981cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
19991cb0ef41Sopenharmony_ci
20001cb0ef41Sopenharmony_ci    skipListInit[scriptId].emplace_back(start->getLineNumber(),
20011cb0ef41Sopenharmony_ci                                        start->getColumnNumber());
20021cb0ef41Sopenharmony_ci    skipListInit[scriptId].emplace_back(end->getLineNumber(),
20031cb0ef41Sopenharmony_ci                                        end->getColumnNumber());
20041cb0ef41Sopenharmony_ci  }
20051cb0ef41Sopenharmony_ci
20061cb0ef41Sopenharmony_ci  // Verify that the skipList is sorted, and that all ranges
20071cb0ef41Sopenharmony_ci  // are properly defined (start comes before end).
20081cb0ef41Sopenharmony_ci  for (auto skipListPair : skipListInit) {
20091cb0ef41Sopenharmony_ci    Response res = isValidRangeOfPositions(skipListPair.second);
20101cb0ef41Sopenharmony_ci    if (res.IsError()) return res;
20111cb0ef41Sopenharmony_ci  }
20121cb0ef41Sopenharmony_ci
20131cb0ef41Sopenharmony_ci  m_skipList = std::move(skipListInit);
20141cb0ef41Sopenharmony_ci  return Response::Success();
20151cb0ef41Sopenharmony_ci}
20161cb0ef41Sopenharmony_ci}  // namespace v8_inspector
2017