11cb0ef41Sopenharmony_ci// Copyright 2014 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-script.h"
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci#include "src/base/memory.h"
81cb0ef41Sopenharmony_ci#include "src/inspector/inspected-context.h"
91cb0ef41Sopenharmony_ci#include "src/inspector/protocol/Debugger.h"
101cb0ef41Sopenharmony_ci#include "src/inspector/string-util.h"
111cb0ef41Sopenharmony_ci#include "src/inspector/v8-debugger-agent-impl.h"
121cb0ef41Sopenharmony_ci#include "src/inspector/v8-inspector-impl.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8_inspector {
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cinamespace {
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ciconst char kGlobalDebuggerScriptHandleLabel[] = "DevTools debugger";
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci// Hash algorithm for substrings is described in "Über die Komplexität der
211cb0ef41Sopenharmony_ci// Multiplikation in
221cb0ef41Sopenharmony_ci// eingeschränkten Branchingprogrammmodellen" by Woelfe.
231cb0ef41Sopenharmony_ci// http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
241cb0ef41Sopenharmony_ciString16 calculateHash(v8::Isolate* isolate, v8::Local<v8::String> source) {
251cb0ef41Sopenharmony_ci  static uint64_t prime[] = {0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35,
261cb0ef41Sopenharmony_ci                             0x81ABE279};
271cb0ef41Sopenharmony_ci  static uint64_t random[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
281cb0ef41Sopenharmony_ci                              0xC3D2E1F0};
291cb0ef41Sopenharmony_ci  static uint32_t randomOdd[] = {0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D,
301cb0ef41Sopenharmony_ci                                 0x8F462907};
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  uint64_t hashes[] = {0, 0, 0, 0, 0};
331cb0ef41Sopenharmony_ci  uint64_t zi[] = {1, 1, 1, 1, 1};
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  const size_t hashesSize = arraysize(hashes);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ci  size_t current = 0;
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  std::unique_ptr<UChar[]> buffer(new UChar[source->Length()]);
401cb0ef41Sopenharmony_ci  int written = source->Write(
411cb0ef41Sopenharmony_ci      isolate, reinterpret_cast<uint16_t*>(buffer.get()), 0, source->Length());
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  const uint32_t* data = nullptr;
441cb0ef41Sopenharmony_ci  size_t sizeInBytes = sizeof(UChar) * written;
451cb0ef41Sopenharmony_ci  data = reinterpret_cast<const uint32_t*>(buffer.get());
461cb0ef41Sopenharmony_ci  for (size_t i = 0; i < sizeInBytes / 4; ++i) {
471cb0ef41Sopenharmony_ci    uint32_t d = v8::base::ReadUnalignedValue<uint32_t>(
481cb0ef41Sopenharmony_ci        reinterpret_cast<v8::internal::Address>(data + i));
491cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
501cb0ef41Sopenharmony_ci    uint32_t v = d;
511cb0ef41Sopenharmony_ci#else
521cb0ef41Sopenharmony_ci    uint32_t v = (d << 16) | (d >> 16);
531cb0ef41Sopenharmony_ci#endif
541cb0ef41Sopenharmony_ci    uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
551cb0ef41Sopenharmony_ci    hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
561cb0ef41Sopenharmony_ci    zi[current] = (zi[current] * random[current]) % prime[current];
571cb0ef41Sopenharmony_ci    current = current == hashesSize - 1 ? 0 : current + 1;
581cb0ef41Sopenharmony_ci  }
591cb0ef41Sopenharmony_ci  if (sizeInBytes % 4) {
601cb0ef41Sopenharmony_ci    uint32_t v = 0;
611cb0ef41Sopenharmony_ci    const uint8_t* data_8b = reinterpret_cast<const uint8_t*>(data);
621cb0ef41Sopenharmony_ci    for (size_t i = sizeInBytes - sizeInBytes % 4; i < sizeInBytes; ++i) {
631cb0ef41Sopenharmony_ci      v <<= 8;
641cb0ef41Sopenharmony_ci#if V8_TARGET_LITTLE_ENDIAN
651cb0ef41Sopenharmony_ci      v |= data_8b[i];
661cb0ef41Sopenharmony_ci#else
671cb0ef41Sopenharmony_ci      if (i % 2) {
681cb0ef41Sopenharmony_ci        v |= data_8b[i - 1];
691cb0ef41Sopenharmony_ci      } else {
701cb0ef41Sopenharmony_ci        v |= data_8b[i + 1];
711cb0ef41Sopenharmony_ci      }
721cb0ef41Sopenharmony_ci#endif
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci    uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
751cb0ef41Sopenharmony_ci    hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
761cb0ef41Sopenharmony_ci    zi[current] = (zi[current] * random[current]) % prime[current];
771cb0ef41Sopenharmony_ci    current = current == hashesSize - 1 ? 0 : current + 1;
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  for (size_t i = 0; i < hashesSize; ++i)
811cb0ef41Sopenharmony_ci    hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i];
821cb0ef41Sopenharmony_ci
831cb0ef41Sopenharmony_ci  String16Builder hash;
841cb0ef41Sopenharmony_ci  for (size_t i = 0; i < hashesSize; ++i)
851cb0ef41Sopenharmony_ci    hash.appendUnsignedAsHex(static_cast<uint32_t>(hashes[i]));
861cb0ef41Sopenharmony_ci  return hash.toString();
871cb0ef41Sopenharmony_ci}
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ciclass ActualScript : public V8DebuggerScript {
901cb0ef41Sopenharmony_ci  friend class V8DebuggerScript;
911cb0ef41Sopenharmony_ci
921cb0ef41Sopenharmony_ci public:
931cb0ef41Sopenharmony_ci  ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
941cb0ef41Sopenharmony_ci               bool isLiveEdit, V8DebuggerAgentImpl* agent,
951cb0ef41Sopenharmony_ci               V8InspectorClient* client)
961cb0ef41Sopenharmony_ci      : V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
971cb0ef41Sopenharmony_ci                         GetScriptURL(isolate, script, client),
981cb0ef41Sopenharmony_ci                         GetScriptName(isolate, script, client)),
991cb0ef41Sopenharmony_ci        m_agent(agent),
1001cb0ef41Sopenharmony_ci        m_isLiveEdit(isLiveEdit) {
1011cb0ef41Sopenharmony_ci    Initialize(script);
1021cb0ef41Sopenharmony_ci  }
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci  bool isLiveEdit() const override { return m_isLiveEdit; }
1051cb0ef41Sopenharmony_ci  bool isModule() const override { return m_isModule; }
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_ci  String16 source(size_t pos, size_t len) const override {
1081cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
1091cb0ef41Sopenharmony_ci    v8::Local<v8::String> v8Source;
1101cb0ef41Sopenharmony_ci    if (!m_scriptSource.Get(m_isolate)->JavaScriptCode().ToLocal(&v8Source)) {
1111cb0ef41Sopenharmony_ci      return String16();
1121cb0ef41Sopenharmony_ci    }
1131cb0ef41Sopenharmony_ci    if (pos >= static_cast<size_t>(v8Source->Length())) return String16();
1141cb0ef41Sopenharmony_ci    size_t substringLength =
1151cb0ef41Sopenharmony_ci        std::min(len, static_cast<size_t>(v8Source->Length()) - pos);
1161cb0ef41Sopenharmony_ci    std::unique_ptr<UChar[]> buffer(new UChar[substringLength]);
1171cb0ef41Sopenharmony_ci    v8Source->Write(m_isolate, reinterpret_cast<uint16_t*>(buffer.get()),
1181cb0ef41Sopenharmony_ci                    static_cast<int>(pos), static_cast<int>(substringLength));
1191cb0ef41Sopenharmony_ci    return String16(buffer.get(), substringLength);
1201cb0ef41Sopenharmony_ci  }
1211cb0ef41Sopenharmony_ci  Language getLanguage() const override { return m_language; }
1221cb0ef41Sopenharmony_ci
1231cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1241cb0ef41Sopenharmony_ci  v8::Maybe<v8::MemorySpan<const uint8_t>> wasmBytecode() const override {
1251cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
1261cb0ef41Sopenharmony_ci    v8::MemorySpan<const uint8_t> bytecode;
1271cb0ef41Sopenharmony_ci    if (m_scriptSource.Get(m_isolate)->WasmBytecode().To(&bytecode)) {
1281cb0ef41Sopenharmony_ci      return v8::Just(bytecode);
1291cb0ef41Sopenharmony_ci    }
1301cb0ef41Sopenharmony_ci    return v8::Nothing<v8::MemorySpan<const uint8_t>>();
1311cb0ef41Sopenharmony_ci  }
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_ci  v8::Maybe<v8::debug::WasmScript::DebugSymbolsType> getDebugSymbolsType()
1341cb0ef41Sopenharmony_ci      const override {
1351cb0ef41Sopenharmony_ci    auto script = this->script();
1361cb0ef41Sopenharmony_ci    if (!script->IsWasm())
1371cb0ef41Sopenharmony_ci      return v8::Nothing<v8::debug::WasmScript::DebugSymbolsType>();
1381cb0ef41Sopenharmony_ci    return v8::Just(v8::debug::WasmScript::Cast(*script)->GetDebugSymbolType());
1391cb0ef41Sopenharmony_ci  }
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  v8::Maybe<String16> getExternalDebugSymbolsURL() const override {
1421cb0ef41Sopenharmony_ci    auto script = this->script();
1431cb0ef41Sopenharmony_ci    if (!script->IsWasm()) return v8::Nothing<String16>();
1441cb0ef41Sopenharmony_ci    v8::MemorySpan<const char> external_url =
1451cb0ef41Sopenharmony_ci        v8::debug::WasmScript::Cast(*script)->ExternalSymbolsURL();
1461cb0ef41Sopenharmony_ci    if (external_url.size() == 0) return v8::Nothing<String16>();
1471cb0ef41Sopenharmony_ci    return v8::Just(String16(external_url.data(), external_url.size()));
1481cb0ef41Sopenharmony_ci  }
1491cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1501cb0ef41Sopenharmony_ci
1511cb0ef41Sopenharmony_ci  int startLine() const override { return m_startLine; }
1521cb0ef41Sopenharmony_ci  int startColumn() const override { return m_startColumn; }
1531cb0ef41Sopenharmony_ci  int endLine() const override { return m_endLine; }
1541cb0ef41Sopenharmony_ci  int endColumn() const override { return m_endColumn; }
1551cb0ef41Sopenharmony_ci  int codeOffset() const override {
1561cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1571cb0ef41Sopenharmony_ci    if (script()->IsWasm()) {
1581cb0ef41Sopenharmony_ci      return v8::debug::WasmScript::Cast(*script())->CodeOffset();
1591cb0ef41Sopenharmony_ci    }
1601cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1611cb0ef41Sopenharmony_ci    return 0;
1621cb0ef41Sopenharmony_ci  }
1631cb0ef41Sopenharmony_ci  int length() const override {
1641cb0ef41Sopenharmony_ci    return static_cast<int>(m_scriptSource.Get(m_isolate)->Length());
1651cb0ef41Sopenharmony_ci  }
1661cb0ef41Sopenharmony_ci
1671cb0ef41Sopenharmony_ci  const String16& sourceMappingURL() const override {
1681cb0ef41Sopenharmony_ci    return m_sourceMappingURL;
1691cb0ef41Sopenharmony_ci  }
1701cb0ef41Sopenharmony_ci
1711cb0ef41Sopenharmony_ci  void setSourceMappingURL(const String16& sourceMappingURL) override {
1721cb0ef41Sopenharmony_ci    m_sourceMappingURL = sourceMappingURL;
1731cb0ef41Sopenharmony_ci  }
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci  void setSource(const String16& newSource, bool preview,
1761cb0ef41Sopenharmony_ci                 v8::debug::LiveEditResult* result) override {
1771cb0ef41Sopenharmony_ci    v8::EscapableHandleScope scope(m_isolate);
1781cb0ef41Sopenharmony_ci    v8::Local<v8::String> v8Source = toV8String(m_isolate, newSource);
1791cb0ef41Sopenharmony_ci    if (!m_script.Get(m_isolate)->SetScriptSource(v8Source, preview, result)) {
1801cb0ef41Sopenharmony_ci      result->message = scope.Escape(result->message);
1811cb0ef41Sopenharmony_ci      return;
1821cb0ef41Sopenharmony_ci    }
1831cb0ef41Sopenharmony_ci    // NOP if preview or unchanged source (diffs.empty() in PatchScript)
1841cb0ef41Sopenharmony_ci    if (preview || result->script.IsEmpty()) return;
1851cb0ef41Sopenharmony_ci
1861cb0ef41Sopenharmony_ci    m_hash = String16();
1871cb0ef41Sopenharmony_ci    Initialize(scope.Escape(result->script));
1881cb0ef41Sopenharmony_ci  }
1891cb0ef41Sopenharmony_ci
1901cb0ef41Sopenharmony_ci  bool getPossibleBreakpoints(
1911cb0ef41Sopenharmony_ci      const v8::debug::Location& start, const v8::debug::Location& end,
1921cb0ef41Sopenharmony_ci      bool restrictToFunction,
1931cb0ef41Sopenharmony_ci      std::vector<v8::debug::BreakLocation>* locations) override {
1941cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
1951cb0ef41Sopenharmony_ci    v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
1961cb0ef41Sopenharmony_ci    std::vector<v8::debug::BreakLocation> allLocations;
1971cb0ef41Sopenharmony_ci    if (!script->GetPossibleBreakpoints(start, end, restrictToFunction,
1981cb0ef41Sopenharmony_ci                                        &allLocations)) {
1991cb0ef41Sopenharmony_ci      return false;
2001cb0ef41Sopenharmony_ci    }
2011cb0ef41Sopenharmony_ci    if (!allLocations.size()) return true;
2021cb0ef41Sopenharmony_ci    v8::debug::BreakLocation current = allLocations[0];
2031cb0ef41Sopenharmony_ci    for (size_t i = 1; i < allLocations.size(); ++i) {
2041cb0ef41Sopenharmony_ci      if (allLocations[i].GetLineNumber() == current.GetLineNumber() &&
2051cb0ef41Sopenharmony_ci          allLocations[i].GetColumnNumber() == current.GetColumnNumber()) {
2061cb0ef41Sopenharmony_ci        if (allLocations[i].type() != v8::debug::kCommonBreakLocation) {
2071cb0ef41Sopenharmony_ci          DCHECK(allLocations[i].type() == v8::debug::kCallBreakLocation ||
2081cb0ef41Sopenharmony_ci                 allLocations[i].type() == v8::debug::kReturnBreakLocation);
2091cb0ef41Sopenharmony_ci          // debugger can returns more then one break location at the same
2101cb0ef41Sopenharmony_ci          // source location, e.g. foo() - in this case there are two break
2111cb0ef41Sopenharmony_ci          // locations before foo: for statement and for function call, we can
2121cb0ef41Sopenharmony_ci          // merge them for inspector and report only one with call type.
2131cb0ef41Sopenharmony_ci          current = allLocations[i];
2141cb0ef41Sopenharmony_ci        }
2151cb0ef41Sopenharmony_ci      } else {
2161cb0ef41Sopenharmony_ci        // we assume that returned break locations are sorted.
2171cb0ef41Sopenharmony_ci        DCHECK(
2181cb0ef41Sopenharmony_ci            allLocations[i].GetLineNumber() > current.GetLineNumber() ||
2191cb0ef41Sopenharmony_ci            (allLocations[i].GetColumnNumber() >= current.GetColumnNumber() &&
2201cb0ef41Sopenharmony_ci             allLocations[i].GetLineNumber() == current.GetLineNumber()));
2211cb0ef41Sopenharmony_ci        locations->push_back(current);
2221cb0ef41Sopenharmony_ci        current = allLocations[i];
2231cb0ef41Sopenharmony_ci      }
2241cb0ef41Sopenharmony_ci    }
2251cb0ef41Sopenharmony_ci    locations->push_back(current);
2261cb0ef41Sopenharmony_ci    return true;
2271cb0ef41Sopenharmony_ci  }
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci  void resetBlackboxedStateCache() override {
2301cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2311cb0ef41Sopenharmony_ci    v8::debug::ResetBlackboxedStateCache(m_isolate, m_script.Get(m_isolate));
2321cb0ef41Sopenharmony_ci  }
2331cb0ef41Sopenharmony_ci
2341cb0ef41Sopenharmony_ci  int offset(int lineNumber, int columnNumber) const override {
2351cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2361cb0ef41Sopenharmony_ci    return m_script.Get(m_isolate)->GetSourceOffset(
2371cb0ef41Sopenharmony_ci        v8::debug::Location(lineNumber, columnNumber));
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci  v8::debug::Location location(int offset) const override {
2411cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2421cb0ef41Sopenharmony_ci    return m_script.Get(m_isolate)->GetSourceLocation(offset);
2431cb0ef41Sopenharmony_ci  }
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  bool setBreakpoint(const String16& condition, v8::debug::Location* location,
2461cb0ef41Sopenharmony_ci                     int* id) const override {
2471cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2481cb0ef41Sopenharmony_ci    return script()->SetBreakpoint(toV8String(m_isolate, condition), location,
2491cb0ef41Sopenharmony_ci                                   id);
2501cb0ef41Sopenharmony_ci  }
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  bool setInstrumentationBreakpoint(int* id) const override {
2531cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2541cb0ef41Sopenharmony_ci    return script()->SetInstrumentationBreakpoint(id);
2551cb0ef41Sopenharmony_ci  }
2561cb0ef41Sopenharmony_ci
2571cb0ef41Sopenharmony_ci  const String16& hash() const override {
2581cb0ef41Sopenharmony_ci    if (!m_hash.isEmpty()) return m_hash;
2591cb0ef41Sopenharmony_ci    v8::HandleScope scope(m_isolate);
2601cb0ef41Sopenharmony_ci    v8::Local<v8::String> v8Source;
2611cb0ef41Sopenharmony_ci    if (!m_scriptSource.Get(m_isolate)->JavaScriptCode().ToLocal(&v8Source)) {
2621cb0ef41Sopenharmony_ci      v8Source = v8::String::Empty(m_isolate);
2631cb0ef41Sopenharmony_ci    }
2641cb0ef41Sopenharmony_ci    m_hash = calculateHash(m_isolate, v8Source);
2651cb0ef41Sopenharmony_ci    DCHECK(!m_hash.isEmpty());
2661cb0ef41Sopenharmony_ci    return m_hash;
2671cb0ef41Sopenharmony_ci  }
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci private:
2701cb0ef41Sopenharmony_ci  static String16 GetScriptURL(v8::Isolate* isolate,
2711cb0ef41Sopenharmony_ci                               v8::Local<v8::debug::Script> script,
2721cb0ef41Sopenharmony_ci                               V8InspectorClient* client) {
2731cb0ef41Sopenharmony_ci    v8::Local<v8::String> sourceURL;
2741cb0ef41Sopenharmony_ci    if (script->SourceURL().ToLocal(&sourceURL) && sourceURL->Length() > 0)
2751cb0ef41Sopenharmony_ci      return toProtocolString(isolate, sourceURL);
2761cb0ef41Sopenharmony_ci    return GetScriptName(isolate, script, client);
2771cb0ef41Sopenharmony_ci  }
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  static String16 GetScriptName(v8::Isolate* isolate,
2801cb0ef41Sopenharmony_ci                                v8::Local<v8::debug::Script> script,
2811cb0ef41Sopenharmony_ci                                V8InspectorClient* client) {
2821cb0ef41Sopenharmony_ci    v8::Local<v8::String> v8Name;
2831cb0ef41Sopenharmony_ci    if (script->Name().ToLocal(&v8Name) && v8Name->Length() > 0) {
2841cb0ef41Sopenharmony_ci      String16 name = toProtocolString(isolate, v8Name);
2851cb0ef41Sopenharmony_ci      std::unique_ptr<StringBuffer> url =
2861cb0ef41Sopenharmony_ci          client->resourceNameToUrl(toStringView(name));
2871cb0ef41Sopenharmony_ci      return url ? toString16(url->string()) : name;
2881cb0ef41Sopenharmony_ci    }
2891cb0ef41Sopenharmony_ci    return String16();
2901cb0ef41Sopenharmony_ci  }
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci  v8::Local<v8::debug::Script> script() const override {
2931cb0ef41Sopenharmony_ci    return m_script.Get(m_isolate);
2941cb0ef41Sopenharmony_ci  }
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci  void Initialize(v8::Local<v8::debug::Script> script) {
2971cb0ef41Sopenharmony_ci    v8::Local<v8::String> tmp;
2981cb0ef41Sopenharmony_ci    m_hasSourceURLComment =
2991cb0ef41Sopenharmony_ci        script->SourceURL().ToLocal(&tmp) && tmp->Length() > 0;
3001cb0ef41Sopenharmony_ci    if (script->SourceMappingURL().ToLocal(&tmp))
3011cb0ef41Sopenharmony_ci      m_sourceMappingURL = toProtocolString(m_isolate, tmp);
3021cb0ef41Sopenharmony_ci    m_startLine = script->StartLine();
3031cb0ef41Sopenharmony_ci    m_startColumn = script->StartColumn();
3041cb0ef41Sopenharmony_ci    m_endLine = script->EndLine();
3051cb0ef41Sopenharmony_ci    m_endColumn = script->EndColumn();
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci    USE(script->ContextId().To(&m_executionContextId));
3081cb0ef41Sopenharmony_ci    m_language = V8DebuggerScript::Language::JavaScript;
3091cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3101cb0ef41Sopenharmony_ci    if (script->IsWasm()) {
3111cb0ef41Sopenharmony_ci      m_language = V8DebuggerScript::Language::WebAssembly;
3121cb0ef41Sopenharmony_ci    }
3131cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci    m_isModule = script->IsModule();
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci    m_script.Reset(m_isolate, script);
3181cb0ef41Sopenharmony_ci    m_script.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel);
3191cb0ef41Sopenharmony_ci    m_scriptSource.Reset(m_isolate, script->Source());
3201cb0ef41Sopenharmony_ci    m_scriptSource.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel);
3211cb0ef41Sopenharmony_ci  }
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  void MakeWeak() override {
3241cb0ef41Sopenharmony_ci    m_script.SetWeak(
3251cb0ef41Sopenharmony_ci        this,
3261cb0ef41Sopenharmony_ci        [](const v8::WeakCallbackInfo<ActualScript>& data) {
3271cb0ef41Sopenharmony_ci          data.GetParameter()->WeakCallback();
3281cb0ef41Sopenharmony_ci        },
3291cb0ef41Sopenharmony_ci        v8::WeakCallbackType::kParameter);
3301cb0ef41Sopenharmony_ci  }
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci  void WeakCallback() {
3331cb0ef41Sopenharmony_ci    m_script.Reset();
3341cb0ef41Sopenharmony_ci    m_agent->ScriptCollected(this);
3351cb0ef41Sopenharmony_ci  }
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  V8DebuggerAgentImpl* m_agent;
3381cb0ef41Sopenharmony_ci  String16 m_sourceMappingURL;
3391cb0ef41Sopenharmony_ci  Language m_language;
3401cb0ef41Sopenharmony_ci  bool m_isLiveEdit = false;
3411cb0ef41Sopenharmony_ci  bool m_isModule = false;
3421cb0ef41Sopenharmony_ci  mutable String16 m_hash;
3431cb0ef41Sopenharmony_ci  int m_startLine = 0;
3441cb0ef41Sopenharmony_ci  int m_startColumn = 0;
3451cb0ef41Sopenharmony_ci  int m_endLine = 0;
3461cb0ef41Sopenharmony_ci  int m_endColumn = 0;
3471cb0ef41Sopenharmony_ci  v8::Global<v8::debug::Script> m_script;
3481cb0ef41Sopenharmony_ci  v8::Global<v8::debug::ScriptSource> m_scriptSource;
3491cb0ef41Sopenharmony_ci};
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ci}  // namespace
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_cistd::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
3541cb0ef41Sopenharmony_ci    v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
3551cb0ef41Sopenharmony_ci    bool isLiveEdit, V8DebuggerAgentImpl* agent, V8InspectorClient* client) {
3561cb0ef41Sopenharmony_ci  return std::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit, agent,
3571cb0ef41Sopenharmony_ci                                        client);
3581cb0ef41Sopenharmony_ci}
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ciV8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
3611cb0ef41Sopenharmony_ci                                   String16 url, String16 embedderName)
3621cb0ef41Sopenharmony_ci    : m_id(std::move(id)),
3631cb0ef41Sopenharmony_ci      m_url(std::move(url)),
3641cb0ef41Sopenharmony_ci      m_isolate(isolate),
3651cb0ef41Sopenharmony_ci      m_embedderName(embedderName) {}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ciV8DebuggerScript::~V8DebuggerScript() = default;
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_civoid V8DebuggerScript::setSourceURL(const String16& sourceURL) {
3701cb0ef41Sopenharmony_ci  if (sourceURL.length() > 0) {
3711cb0ef41Sopenharmony_ci    m_hasSourceURLComment = true;
3721cb0ef41Sopenharmony_ci    m_url = sourceURL;
3731cb0ef41Sopenharmony_ci  }
3741cb0ef41Sopenharmony_ci}
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
3771cb0ef41Sopenharmony_civoid V8DebuggerScript::removeWasmBreakpoint(int id) {
3781cb0ef41Sopenharmony_ci  v8::HandleScope scope(m_isolate);
3791cb0ef41Sopenharmony_ci  script()->RemoveWasmBreakpoint(id);
3801cb0ef41Sopenharmony_ci}
3811cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci}  // namespace v8_inspector
384