LCOV - code coverage report
Current view: top level - src/inspector - v8-debugger-script.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 213 232 91.8 %
Date: 2019-04-17 Functions: 49 58 84.5 %

          Line data    Source code
       1             : // Copyright 2014 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/inspector/v8-debugger-script.h"
       6             : 
       7             : #include "src/inspector/inspected-context.h"
       8             : #include "src/inspector/string-util.h"
       9             : #include "src/inspector/v8-debugger-agent-impl.h"
      10             : #include "src/inspector/v8-inspector-impl.h"
      11             : #include "src/inspector/wasm-translation.h"
      12             : #include "src/v8memory.h"
      13             : 
      14             : namespace v8_inspector {
      15             : 
      16             : namespace {
      17             : 
      18             : const char kGlobalDebuggerScriptHandleLabel[] = "DevTools debugger";
      19             : 
      20             : // Hash algorithm for substrings is described in "Über die Komplexität der
      21             : // Multiplikation in
      22             : // eingeschränkten Branchingprogrammmodellen" by Woelfe.
      23             : // http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
      24       56002 : String16 calculateHash(v8::Isolate* isolate, v8::Local<v8::String> source) {
      25             :   static uint64_t prime[] = {0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35,
      26             :                              0x81ABE279};
      27             :   static uint64_t random[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
      28             :                               0xC3D2E1F0};
      29             :   static uint32_t randomOdd[] = {0xB4663807, 0xCC322BF5, 0xD4F91BBD, 0xA7BEA11D,
      30             :                                  0x8F462907};
      31             : 
      32       56002 :   uint64_t hashes[] = {0, 0, 0, 0, 0};
      33       56002 :   uint64_t zi[] = {1, 1, 1, 1, 1};
      34             : 
      35             :   const size_t hashesSize = arraysize(hashes);
      36             : 
      37             :   size_t current = 0;
      38             : 
      39       56002 :   std::unique_ptr<UChar[]> buffer(new UChar[source->Length()]);
      40       56002 :   int written = source->Write(
      41       56002 :       isolate, reinterpret_cast<uint16_t*>(buffer.get()), 0, source->Length());
      42             : 
      43             :   const uint32_t* data = nullptr;
      44       56002 :   size_t sizeInBytes = sizeof(UChar) * written;
      45             :   data = reinterpret_cast<const uint32_t*>(buffer.get());
      46   297140452 :   for (size_t i = 0; i < sizeInBytes / 4; ++i) {
      47             :     uint32_t d = v8::internal::ReadUnalignedUInt32(
      48   148542225 :         reinterpret_cast<v8::internal::Address>(data + i));
      49             : #if V8_TARGET_LITTLE_ENDIAN
      50             :     uint32_t v = d;
      51             : #else
      52             :     uint32_t v = (d << 16) | (d >> 16);
      53             : #endif
      54   148542225 :     uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
      55   148542225 :     hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
      56   148542225 :     zi[current] = (zi[current] * random[current]) % prime[current];
      57   148542225 :     current = current == hashesSize - 1 ? 0 : current + 1;
      58             :   }
      59       56002 :   if (sizeInBytes % 4) {
      60             :     uint32_t v = 0;
      61             :     const uint8_t* data_8b = reinterpret_cast<const uint8_t*>(data);
      62       82077 :     for (size_t i = sizeInBytes - sizeInBytes % 4; i < sizeInBytes; ++i) {
      63       54718 :       v <<= 8;
      64             : #if V8_TARGET_LITTLE_ENDIAN
      65       54718 :       v |= data_8b[i];
      66             : #else
      67             :       if (i % 2) {
      68             :         v |= data_8b[i - 1];
      69             :       } else {
      70             :         v |= data_8b[i + 1];
      71             :       }
      72             : #endif
      73             :     }
      74       27359 :     uint64_t xi = v * randomOdd[current] & 0x7FFFFFFF;
      75       27359 :     hashes[current] = (hashes[current] + zi[current] * xi) % prime[current];
      76       27359 :     zi[current] = (zi[current] * random[current]) % prime[current];
      77             :     current = current == hashesSize - 1 ? 0 : current + 1;
      78             :   }
      79             : 
      80      616022 :   for (size_t i = 0; i < hashesSize; ++i)
      81      280010 :     hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i];
      82             : 
      83       56002 :   String16Builder hash;
      84      616022 :   for (size_t i = 0; i < hashesSize; ++i)
      85      280010 :     hash.appendUnsignedAsHex(static_cast<uint32_t>(hashes[i]));
      86      112004 :   return hash.toString();
      87             : }
      88             : 
      89         120 : void TranslateProtocolLocationToV8Location(WasmTranslation* wasmTranslation,
      90             :                                            v8::debug::Location* loc,
      91             :                                            const String16& scriptId,
      92             :                                            const String16& expectedV8ScriptId) {
      93         120 :   if (loc->IsEmpty()) return;
      94         120 :   int lineNumber = loc->GetLineNumber();
      95         120 :   int columnNumber = loc->GetColumnNumber();
      96             :   String16 translatedScriptId = scriptId;
      97             :   wasmTranslation->TranslateProtocolLocationToWasmScriptLocation(
      98         120 :       &translatedScriptId, &lineNumber, &columnNumber);
      99             :   DCHECK_EQ(expectedV8ScriptId.utf8(), translatedScriptId.utf8());
     100         120 :   *loc = v8::debug::Location(lineNumber, columnNumber);
     101             : }
     102             : 
     103         152 : void TranslateV8LocationToProtocolLocation(
     104             :     WasmTranslation* wasmTranslation, v8::debug::Location* loc,
     105             :     const String16& scriptId, const String16& expectedProtocolScriptId) {
     106         152 :   int lineNumber = loc->GetLineNumber();
     107         152 :   int columnNumber = loc->GetColumnNumber();
     108             :   String16 translatedScriptId = scriptId;
     109             :   wasmTranslation->TranslateWasmScriptLocationToProtocolLocation(
     110         152 :       &translatedScriptId, &lineNumber, &columnNumber);
     111             :   DCHECK_EQ(expectedProtocolScriptId.utf8(), translatedScriptId.utf8());
     112         152 :   *loc = v8::debug::Location(lineNumber, columnNumber);
     113         152 : }
     114             : 
     115      168006 : class ActualScript : public V8DebuggerScript {
     116             :   friend class V8DebuggerScript;
     117             : 
     118             :  public:
     119       56002 :   ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
     120             :                bool isLiveEdit, V8DebuggerAgentImpl* agent,
     121             :                V8InspectorClient* client)
     122      112004 :       : V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
     123      112004 :                          GetScriptURL(isolate, script, client)),
     124             :         m_agent(agent),
     125      224008 :         m_isLiveEdit(isLiveEdit) {
     126       56002 :     Initialize(script);
     127       56002 :   }
     128             : 
     129       56002 :   bool isLiveEdit() const override { return m_isLiveEdit; }
     130       56002 :   bool isModule() const override { return m_isModule; }
     131             : 
     132        1534 :   String16 source(size_t pos, size_t len) const override {
     133        3068 :     v8::HandleScope scope(m_isolate);
     134             :     v8::Local<v8::String> v8Source;
     135        3068 :     if (!script()->Source().ToLocal(&v8Source)) return String16();
     136        1534 :     if (pos >= static_cast<size_t>(v8Source->Length())) return String16();
     137             :     size_t substringLength =
     138        3040 :         std::min(len, static_cast<size_t>(v8Source->Length()) - pos);
     139        1520 :     std::unique_ptr<UChar[]> buffer(new UChar[substringLength]);
     140        1520 :     v8Source->Write(m_isolate, reinterpret_cast<uint16_t*>(buffer.get()),
     141        1520 :                     static_cast<int>(pos), static_cast<int>(substringLength));
     142        1520 :     return String16(buffer.get(), substringLength);
     143             :   }
     144       58238 :   int startLine() const override { return m_startLine; }
     145       56002 :   int startColumn() const override { return m_startColumn; }
     146       58228 :   int endLine() const override { return m_endLine; }
     147       56002 :   int endColumn() const override { return m_endColumn; }
     148       55816 :   bool isSourceLoadedLazily() const override { return false; }
     149       77215 :   int length() const override {
     150      154430 :     v8::HandleScope scope(m_isolate);
     151             :     v8::Local<v8::String> v8Source;
     152      231645 :     return script()->Source().ToLocal(&v8Source) ? v8Source->Length() : 0;
     153             :   }
     154             : 
     155       56002 :   const String16& sourceMappingURL() const override {
     156       56002 :     return m_sourceMappingURL;
     157             :   }
     158             : 
     159         186 :   void setSourceMappingURL(const String16& sourceMappingURL) override {
     160             :     m_sourceMappingURL = sourceMappingURL;
     161         186 :   }
     162             : 
     163          50 :   void setSource(const String16& newSource, bool preview,
     164             :                  v8::debug::LiveEditResult* result) override {
     165          50 :     v8::EscapableHandleScope scope(m_isolate);
     166          50 :     v8::Local<v8::String> v8Source = toV8String(m_isolate, newSource);
     167         100 :     if (!m_script.Get(m_isolate)->SetScriptSource(v8Source, preview, result)) {
     168          10 :       result->message = scope.Escape(result->message);
     169          10 :       return;
     170             :     }
     171          40 :     if (preview) return;
     172          80 :     m_hash = String16();
     173          40 :     Initialize(scope.Escape(result->script));
     174             :   }
     175             : 
     176         235 :   bool getPossibleBreakpoints(
     177             :       const v8::debug::Location& start, const v8::debug::Location& end,
     178             :       bool restrictToFunction,
     179             :       std::vector<v8::debug::BreakLocation>* locations) override {
     180         470 :     v8::HandleScope scope(m_isolate);
     181         235 :     v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
     182             :     std::vector<v8::debug::BreakLocation> allLocations;
     183         235 :     if (!script->GetPossibleBreakpoints(start, end, restrictToFunction,
     184             :                                         &allLocations)) {
     185             :       return false;
     186             :     }
     187         230 :     if (!allLocations.size()) return true;
     188         205 :     v8::debug::BreakLocation current = allLocations[0];
     189        9635 :     for (size_t i = 1; i < allLocations.size(); ++i) {
     190        7545 :       if (allLocations[i].GetLineNumber() == current.GetLineNumber() &&
     191        2830 :           allLocations[i].GetColumnNumber() == current.GetColumnNumber()) {
     192         740 :         if (allLocations[i].type() != v8::debug::kCommonBreakLocation) {
     193             :           DCHECK(allLocations[i].type() == v8::debug::kCallBreakLocation ||
     194             :                  allLocations[i].type() == v8::debug::kReturnBreakLocation);
     195             :           // debugger can returns more then one break location at the same
     196             :           // source location, e.g. foo() - in this case there are two break
     197             :           // locations before foo: for statement and for function call, we can
     198             :           // merge them for inspector and report only one with call type.
     199         435 :           current = allLocations[i];
     200             :         }
     201             :       } else {
     202             :         // we assume that returned break locations are sorted.
     203             :         DCHECK(
     204             :             allLocations[i].GetLineNumber() > current.GetLineNumber() ||
     205             :             (allLocations[i].GetColumnNumber() >= current.GetColumnNumber() &&
     206             :              allLocations[i].GetLineNumber() == current.GetLineNumber()));
     207        3975 :         locations->push_back(current);
     208        3975 :         current = allLocations[i];
     209             :       }
     210             :     }
     211         205 :     locations->push_back(current);
     212         205 :     return true;
     213             :   }
     214             : 
     215      112250 :   void resetBlackboxedStateCache() override {
     216      224500 :     v8::HandleScope scope(m_isolate);
     217      224500 :     v8::debug::ResetBlackboxedStateCache(m_isolate, m_script.Get(m_isolate));
     218      112250 :   }
     219             : 
     220         310 :   int offset(int lineNumber, int columnNumber) const override {
     221         620 :     v8::HandleScope scope(m_isolate);
     222         620 :     return m_script.Get(m_isolate)->GetSourceOffset(
     223         620 :         v8::debug::Location(lineNumber, columnNumber));
     224             :   }
     225             : 
     226          60 :   v8::debug::Location location(int offset) const override {
     227         120 :     v8::HandleScope scope(m_isolate);
     228         180 :     return m_script.Get(m_isolate)->GetSourceLocation(offset);
     229             :   }
     230             : 
     231        2071 :   bool setBreakpoint(const String16& condition, v8::debug::Location* location,
     232             :                      int* id) const override {
     233        4142 :     v8::HandleScope scope(m_isolate);
     234        2071 :     return script()->SetBreakpoint(toV8String(m_isolate, condition), location,
     235        4142 :                                    id);
     236             :   }
     237             : 
     238       56067 :   const String16& hash() const override {
     239       56067 :     if (!m_hash.isEmpty()) return m_hash;
     240      112004 :     v8::HandleScope scope(m_isolate);
     241             :     v8::Local<v8::String> v8Source;
     242      112004 :     if (script()->Source().ToLocal(&v8Source)) {
     243      112004 :       m_hash = calculateHash(m_isolate, v8Source);
     244             :     }
     245             :     DCHECK(!m_hash.isEmpty());
     246       56002 :     return m_hash;
     247             :   }
     248             : 
     249             :  private:
     250       56002 :   static String16 GetScriptURL(v8::Isolate* isolate,
     251             :                                v8::Local<v8::debug::Script> script,
     252             :                                V8InspectorClient* client) {
     253             :     v8::Local<v8::String> sourceURL;
     254      112004 :     if (script->SourceURL().ToLocal(&sourceURL) && sourceURL->Length() > 0)
     255        2215 :       return toProtocolString(isolate, sourceURL);
     256             :     v8::Local<v8::String> v8Name;
     257      107574 :     if (script->Name().ToLocal(&v8Name) && v8Name->Length() > 0) {
     258       16079 :       String16 name = toProtocolString(isolate, v8Name);
     259             :       std::unique_ptr<StringBuffer> url =
     260       16079 :           client->resourceNameToUrl(toStringView(name));
     261       16079 :       return url ? toString16(url->string()) : name;
     262             :     }
     263       37708 :     return String16();
     264             :   }
     265             : 
     266           0 :   v8::Local<v8::debug::Script> script() const override {
     267      136822 :     return m_script.Get(m_isolate);
     268             :   }
     269             : 
     270       56042 :   void Initialize(v8::Local<v8::debug::Script> script) {
     271             :     v8::Local<v8::String> tmp;
     272             :     m_hasSourceURLComment =
     273      112084 :         script->SourceURL().ToLocal(&tmp) && tmp->Length() > 0;
     274      112084 :     if (script->SourceMappingURL().ToLocal(&tmp))
     275        1052 :       m_sourceMappingURL = toProtocolString(m_isolate, tmp);
     276       56042 :     m_startLine = script->LineOffset();
     277       56042 :     m_startColumn = script->ColumnOffset();
     278       56042 :     std::vector<int> lineEnds = script->LineEnds();
     279       56042 :     CHECK(lineEnds.size());
     280      112084 :     int source_length = lineEnds[lineEnds.size() - 1];
     281       56042 :     if (lineEnds.size()) {
     282       56042 :       m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1;
     283       56042 :       if (lineEnds.size() > 1) {
     284       43052 :         m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1;
     285             :       } else {
     286       34516 :         m_endColumn = source_length + m_startColumn;
     287             :       }
     288             :     } else {
     289           0 :       m_endLine = m_startLine;
     290           0 :       m_endColumn = m_startColumn;
     291             :     }
     292             : 
     293      112084 :     USE(script->ContextId().To(&m_executionContextId));
     294             : 
     295       56042 :     m_isModule = script->IsModule();
     296             : 
     297       56042 :     m_script.Reset(m_isolate, script);
     298             :     m_script.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel);
     299       56042 :   }
     300             : 
     301       56002 :   void MakeWeak() override {
     302             :     m_script.SetWeak(
     303             :         this,
     304       21084 :         [](const v8::WeakCallbackInfo<ActualScript>& data) {
     305             :           data.GetParameter()->WeakCallback();
     306       21084 :         },
     307             :         v8::WeakCallbackType::kFinalizer);
     308       56002 :   }
     309             : 
     310             :   void WeakCallback() {
     311             :     m_script.ClearWeak();
     312       21084 :     m_agent->ScriptCollected(this);
     313             :   }
     314             : 
     315             :   V8DebuggerAgentImpl* m_agent;
     316             :   String16 m_sourceMappingURL;
     317             :   bool m_isLiveEdit = false;
     318             :   bool m_isModule = false;
     319             :   mutable String16 m_hash;
     320             :   int m_startLine = 0;
     321             :   int m_startColumn = 0;
     322             :   int m_endLine = 0;
     323             :   int m_endColumn = 0;
     324             :   v8::Global<v8::debug::Script> m_script;
     325             : };
     326             : 
     327         276 : class WasmVirtualScript : public V8DebuggerScript {
     328             :   friend class V8DebuggerScript;
     329             : 
     330             :  public:
     331          92 :   WasmVirtualScript(v8::Isolate* isolate, WasmTranslation* wasmTranslation,
     332             :                     v8::Local<v8::debug::WasmScript> script, String16 id,
     333             :                     String16 url, int functionIndex)
     334             :       : V8DebuggerScript(isolate, std::move(id), std::move(url)),
     335             :         m_script(isolate, script),
     336             :         m_wasmTranslation(wasmTranslation),
     337         368 :         m_functionIndex(functionIndex) {
     338             :     m_script.AnnotateStrongRetainer(kGlobalDebuggerScriptHandleLabel);
     339         184 :     m_executionContextId = script->ContextId().ToChecked();
     340          92 :   }
     341             : 
     342          92 :   const String16& sourceMappingURL() const override { return emptyString(); }
     343          92 :   bool isLiveEdit() const override { return false; }
     344          92 :   bool isModule() const override { return false; }
     345           0 :   void setSourceMappingURL(const String16&) override {}
     346           0 :   void setSource(const String16&, bool, v8::debug::LiveEditResult*) override {
     347           0 :     UNREACHABLE();
     348             :   }
     349          92 :   bool isSourceLoadedLazily() const override { return true; }
     350          56 :   String16 source(size_t pos, size_t len) const override {
     351          56 :     return m_wasmTranslation->GetSource(m_id, m_functionIndex)
     352          56 :         .substring(pos, len);
     353             :   }
     354          80 :   int startLine() const override {
     355          80 :     return m_wasmTranslation->GetStartLine(m_id, m_functionIndex);
     356             :   }
     357           0 :   int startColumn() const override {
     358           0 :     return m_wasmTranslation->GetStartColumn(m_id, m_functionIndex);
     359             :   }
     360          80 :   int endLine() const override {
     361          80 :     return m_wasmTranslation->GetEndLine(m_id, m_functionIndex);
     362             :   }
     363           0 :   int endColumn() const override {
     364           0 :     return m_wasmTranslation->GetEndColumn(m_id, m_functionIndex);
     365             :   }
     366           0 :   int length() const override {
     367           0 :     return static_cast<int>(source(0, UINT_MAX).length());
     368             :   }
     369             : 
     370          24 :   bool getPossibleBreakpoints(
     371             :       const v8::debug::Location& start, const v8::debug::Location& end,
     372             :       bool restrictToFunction,
     373             :       std::vector<v8::debug::BreakLocation>* locations) override {
     374          48 :     v8::HandleScope scope(m_isolate);
     375          24 :     v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
     376          24 :     String16 v8ScriptId = String16::fromInteger(script->Id());
     377             : 
     378          24 :     v8::debug::Location translatedStart = start;
     379          24 :     TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedStart,
     380          24 :                                           scriptId(), v8ScriptId);
     381             : 
     382          24 :     v8::debug::Location translatedEnd = end;
     383          24 :     if (translatedEnd.IsEmpty()) {
     384             :       // Stop before the start of the next function.
     385             :       translatedEnd =
     386           8 :           v8::debug::Location(translatedStart.GetLineNumber() + 1, 0);
     387             :     } else {
     388          16 :       TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedEnd,
     389          16 :                                             scriptId(), v8ScriptId);
     390             :     }
     391             : 
     392          24 :     bool success = script->GetPossibleBreakpoints(
     393          24 :         translatedStart, translatedEnd, restrictToFunction, locations);
     394          96 :     for (v8::debug::BreakLocation& loc : *locations) {
     395          72 :       TranslateV8LocationToProtocolLocation(m_wasmTranslation, &loc, v8ScriptId,
     396          72 :                                             scriptId());
     397             :     }
     398          24 :     return success;
     399             :   }
     400             : 
     401         184 :   void resetBlackboxedStateCache() override {}
     402             : 
     403           4 :   int offset(int lineNumber, int columnNumber) const override {
     404           4 :     return kNoOffset;
     405             :   }
     406             : 
     407           0 :   v8::debug::Location location(int offset) const override {
     408           0 :     return v8::debug::Location();
     409             :   }
     410             : 
     411          80 :   bool setBreakpoint(const String16& condition, v8::debug::Location* location,
     412             :                      int* id) const override {
     413         160 :     v8::HandleScope scope(m_isolate);
     414          80 :     v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
     415          80 :     String16 v8ScriptId = String16::fromInteger(script->Id());
     416             : 
     417          80 :     TranslateProtocolLocationToV8Location(m_wasmTranslation, location,
     418          80 :                                           scriptId(), v8ScriptId);
     419          80 :     if (location->IsEmpty()) return false;
     420          80 :     if (!script->SetBreakpoint(toV8String(m_isolate, condition), location, id))
     421             :       return false;
     422          80 :     TranslateV8LocationToProtocolLocation(m_wasmTranslation, location,
     423          80 :                                           v8ScriptId, scriptId());
     424          80 :     return true;
     425             :   }
     426             : 
     427          92 :   const String16& hash() const override {
     428          92 :     if (m_hash.isEmpty()) {
     429         184 :       m_hash = m_wasmTranslation->GetHash(m_id, m_functionIndex);
     430             :     }
     431          92 :     return m_hash;
     432             :   }
     433             : 
     434          92 :   void MakeWeak() override {}
     435             : 
     436             :  private:
     437          92 :   static const String16& emptyString() {
     438             :     // On the heap and leaked so that no destructor needs to run at exit time.
     439         136 :     static const String16* singleEmptyString = new String16;
     440          92 :     return *singleEmptyString;
     441             :   }
     442             : 
     443           0 :   v8::Local<v8::debug::Script> script() const override {
     444           0 :     return m_script.Get(m_isolate);
     445             :   }
     446             : 
     447             :   v8::Global<v8::debug::WasmScript> m_script;
     448             :   WasmTranslation* m_wasmTranslation;
     449             :   int m_functionIndex;
     450             :   mutable String16 m_hash;
     451             : };
     452             : 
     453             : }  // namespace
     454             : 
     455       56002 : std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
     456             :     v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
     457             :     bool isLiveEdit, V8DebuggerAgentImpl* agent, V8InspectorClient* client) {
     458      112004 :   return v8::base::make_unique<ActualScript>(isolate, scriptObj, isLiveEdit,
     459       56002 :                                              agent, client);
     460             : }
     461             : 
     462          92 : std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm(
     463             :     v8::Isolate* isolate, WasmTranslation* wasmTranslation,
     464             :     v8::Local<v8::debug::WasmScript> underlyingScript, String16 id,
     465             :     String16 url, int functionIndex) {
     466         184 :   return v8::base::make_unique<WasmVirtualScript>(
     467             :       isolate, wasmTranslation, underlyingScript, std::move(id), std::move(url),
     468          92 :       functionIndex);
     469             : }
     470             : 
     471       56094 : V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
     472             :                                    String16 url)
     473      112188 :     : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {}
     474             : 
     475             : V8DebuggerScript::~V8DebuggerScript() = default;
     476             : 
     477         186 : void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
     478         186 :   if (sourceURL.length() > 0) {
     479          25 :     m_hasSourceURLComment = true;
     480             :     m_url = sourceURL;
     481             :   }
     482         186 : }
     483             : 
     484           0 : bool V8DebuggerScript::setBreakpoint(const String16& condition,
     485             :                                      v8::debug::Location* loc, int* id) const {
     486           0 :   v8::HandleScope scope(m_isolate);
     487           0 :   return script()->SetBreakpoint(toV8String(m_isolate, condition), loc, id);
     488             : }
     489             : 
     490             : }  // namespace v8_inspector

Generated by: LCOV version 1.10