| Index: src/inspector/v8-debugger-script.cc
|
| diff --git a/src/inspector/v8-debugger-script.cc b/src/inspector/v8-debugger-script.cc
|
| index 5ff73db05e8a16e94c87d9829dd90980656e12c2..060517e2a3d8e3ab4a49581ad0929d12c2ac2c0d 100644
|
| --- a/src/inspector/v8-debugger-script.cc
|
| +++ b/src/inspector/v8-debugger-script.cc
|
| @@ -8,9 +8,11 @@
|
|
|
| namespace v8_inspector {
|
|
|
| -static const char hexDigits[17] = "0123456789ABCDEF";
|
| +namespace {
|
|
|
| -static void appendUnsignedAsHex(uint64_t number, String16Builder* destination) {
|
| +const char hexDigits[17] = "0123456789ABCDEF";
|
| +
|
| +void appendUnsignedAsHex(uint64_t number, String16Builder* destination) {
|
| for (size_t i = 0; i < 8; ++i) {
|
| UChar c = hexDigits[number & 0xF];
|
| destination->append(c);
|
| @@ -22,7 +24,7 @@ static void appendUnsignedAsHex(uint64_t number, String16Builder* destination) {
|
| // Multiplikation in
|
| // eingeschränkten Branchingprogrammmodellen" by Woelfe.
|
| // http://opendatastructures.org/versions/edition-0.1d/ods-java/node33.html#SECTION00832000000000000000
|
| -static String16 calculateHash(const String16& str) {
|
| +String16 calculateHash(const String16& str) {
|
| static uint64_t prime[] = {0x3FB75161, 0xAB1F4E4F, 0x82675BC5, 0xCD924D35,
|
| 0x81ABE279};
|
| static uint64_t random[] = {0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476,
|
| @@ -66,92 +68,188 @@ static String16 calculateHash(const String16& str) {
|
| return hash.toString();
|
| }
|
|
|
| -V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate,
|
| - v8::Local<v8::debug::Script> script,
|
| - bool isLiveEdit) {
|
| - m_isolate = script->GetIsolate();
|
| - m_id = String16::fromInteger(script->Id());
|
| - v8::Local<v8::String> tmp;
|
| - if (script->Name().ToLocal(&tmp)) m_url = toProtocolString(tmp);
|
| - if (script->SourceURL().ToLocal(&tmp)) {
|
| - m_sourceURL = toProtocolString(tmp);
|
| - if (m_url.isEmpty()) m_url = toProtocolString(tmp);
|
| - }
|
| - if (script->SourceMappingURL().ToLocal(&tmp))
|
| - m_sourceMappingURL = toProtocolString(tmp);
|
| - m_startLine = script->LineOffset();
|
| - m_startColumn = script->ColumnOffset();
|
| - std::vector<int> lineEnds = script->LineEnds();
|
| - CHECK(lineEnds.size());
|
| - int source_length = lineEnds[lineEnds.size() - 1];
|
| - if (lineEnds.size()) {
|
| - m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1;
|
| - if (lineEnds.size() > 1) {
|
| - m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1;
|
| +class ActualScript : public V8DebuggerScript {
|
| + friend class V8DebuggerScript;
|
| +
|
| + public:
|
| + ActualScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
|
| + bool isLiveEdit)
|
| + : V8DebuggerScript(isolate, String16::fromInteger(script->Id()),
|
| + GetNameOrSourceUrl(script)),
|
| + m_isLiveEdit(isLiveEdit) {
|
| + v8::Local<v8::String> tmp;
|
| + if (script->SourceURL().ToLocal(&tmp)) m_sourceURL = toProtocolString(tmp);
|
| + if (script->SourceMappingURL().ToLocal(&tmp))
|
| + m_sourceMappingURL = toProtocolString(tmp);
|
| + m_startLine = script->LineOffset();
|
| + m_startColumn = script->ColumnOffset();
|
| + std::vector<int> lineEnds = script->LineEnds();
|
| + CHECK(lineEnds.size());
|
| + int source_length = lineEnds[lineEnds.size() - 1];
|
| + if (lineEnds.size()) {
|
| + m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1;
|
| + if (lineEnds.size() > 1) {
|
| + m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1;
|
| + } else {
|
| + m_endColumn = source_length + m_startColumn;
|
| + }
|
| } else {
|
| - m_endColumn = source_length + m_startColumn;
|
| + m_endLine = m_startLine;
|
| + m_endColumn = m_startColumn;
|
| + }
|
| +
|
| + if (script->ContextData().ToLocal(&tmp)) {
|
| + String16 contextData = toProtocolString(tmp);
|
| + size_t firstComma = contextData.find(",", 0);
|
| + size_t secondComma = firstComma != String16::kNotFound
|
| + ? contextData.find(",", firstComma + 1)
|
| + : String16::kNotFound;
|
| + if (secondComma != String16::kNotFound) {
|
| + String16 executionContextId =
|
| + contextData.substring(firstComma + 1, secondComma - firstComma - 1);
|
| + bool isOk = false;
|
| + m_executionContextId = executionContextId.toInteger(&isOk);
|
| + if (!isOk) m_executionContextId = 0;
|
| + m_executionContextAuxData = contextData.substring(secondComma + 1);
|
| + }
|
| }
|
| - } else {
|
| - m_endLine = m_startLine;
|
| - m_endColumn = m_startColumn;
|
| - }
|
|
|
| - if (script->ContextData().ToLocal(&tmp)) {
|
| - String16 contextData = toProtocolString(tmp);
|
| - size_t firstComma = contextData.find(",", 0);
|
| - size_t secondComma = firstComma != String16::kNotFound
|
| - ? contextData.find(",", firstComma + 1)
|
| - : String16::kNotFound;
|
| - if (secondComma != String16::kNotFound) {
|
| - String16 executionContextId =
|
| - contextData.substring(firstComma + 1, secondComma - firstComma - 1);
|
| - bool isOk = false;
|
| - m_executionContextId = executionContextId.toInteger(&isOk);
|
| - if (!isOk) m_executionContextId = 0;
|
| - m_executionContextAuxData = contextData.substring(secondComma + 1);
|
| + if (script->Source().ToLocal(&tmp)) {
|
| + m_sourceObj.Reset(m_isolate, tmp);
|
| + String16 source = toProtocolString(tmp);
|
| + // V8 will not count last line if script source ends with \n.
|
| + if (source.length() > 1 && source[source.length() - 1] == '\n') {
|
| + m_endLine++;
|
| + m_endColumn = 0;
|
| + }
|
| }
|
| +
|
| + m_script.Reset(m_isolate, script);
|
| }
|
|
|
| - m_isLiveEdit = isLiveEdit;
|
| + bool isLiveEdit() const override { return m_isLiveEdit; }
|
| +
|
| + const String16& executionContextAuxData() const override {
|
| + return m_executionContextAuxData;
|
| + }
|
| +
|
| + const String16& sourceMappingURL() const override {
|
| + return m_sourceMappingURL;
|
| + }
|
| +
|
| + String16 source(v8::Isolate* isolate) const override {
|
| + if (!m_sourceObj.IsEmpty())
|
| + return toProtocolString(m_sourceObj.Get(isolate));
|
| + return V8DebuggerScript::source(isolate);
|
| + }
|
| +
|
| + void setSourceMappingURL(const String16& sourceMappingURL) override {
|
| + m_sourceMappingURL = sourceMappingURL;
|
| + }
|
| +
|
| + void setSource(v8::Local<v8::String> source) override {
|
| + m_source = String16();
|
| + m_sourceObj.Reset(m_isolate, source);
|
| + m_hash = String16();
|
| + }
|
| +
|
| + bool getPossibleBreakpoints(
|
| + const v8::debug::Location& start, const v8::debug::Location& end,
|
| + std::vector<v8::debug::Location>* locations) override {
|
| + v8::HandleScope scope(m_isolate);
|
| + v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
|
| + return script->GetPossibleBreakpoints(start, end, locations);
|
| + }
|
| +
|
| + private:
|
| + String16 GetNameOrSourceUrl(v8::Local<v8::debug::Script> script) {
|
| + v8::Local<v8::String> name;
|
| + if (script->Name().ToLocal(&name) || script->SourceURL().ToLocal(&name))
|
| + return toProtocolString(name);
|
| + return String16();
|
| + }
|
|
|
| - if (script->Source().ToLocal(&tmp)) {
|
| - m_sourceObj.Reset(m_isolate, tmp);
|
| - String16 source = toProtocolString(tmp);
|
| - // V8 will not count last line if script source ends with \n.
|
| - if (source.length() > 1 && source[source.length() - 1] == '\n') {
|
| - m_endLine++;
|
| - m_endColumn = 0;
|
| + String16 m_sourceMappingURL;
|
| + v8::Global<v8::String> m_sourceObj;
|
| + String16 m_executionContextAuxData;
|
| + bool m_isLiveEdit = false;
|
| + v8::Global<v8::debug::Script> m_script;
|
| +};
|
| +
|
| +class WasmVirtualScript : public V8DebuggerScript {
|
| + friend class V8DebuggerScript;
|
| +
|
| + public:
|
| + WasmVirtualScript(v8::Isolate* isolate,
|
| + v8::Local<v8::debug::WasmScript> script, String16 id,
|
| + String16 url, String16 source)
|
| + : V8DebuggerScript(isolate, std::move(id), std::move(url)),
|
| + m_script(isolate, script) {
|
| + int num_lines = 0;
|
| + int last_newline = -1;
|
| + size_t next_newline = source.find('\n', last_newline + 1);
|
| + while (next_newline != String16::kNotFound) {
|
| + last_newline = static_cast<int>(next_newline);
|
| + next_newline = source.find('\n', last_newline + 1);
|
| + ++num_lines;
|
| }
|
| + m_endLine = num_lines;
|
| + m_endColumn = static_cast<int>(source.length()) - last_newline - 1;
|
| + m_source = std::move(source);
|
| }
|
|
|
| - m_script.Reset(m_isolate, script);
|
| -}
|
| + const String16& sourceMappingURL() const override { return emptyString(); }
|
| + const String16& executionContextAuxData() const override {
|
| + return emptyString();
|
| + }
|
| + bool isLiveEdit() const override { return false; }
|
| + void setSourceMappingURL(const String16&) override {}
|
| +
|
| + bool getPossibleBreakpoints(
|
| + const v8::debug::Location& start, const v8::debug::Location& end,
|
| + std::vector<v8::debug::Location>* locations) override {
|
| + // TODO(clemensh): Returning false produces the protocol error "Internal
|
| + // error". Implement and fix expected output of
|
| + // wasm-get-breakable-locations.js.
|
| + return false;
|
| + }
|
|
|
| -V8DebuggerScript::V8DebuggerScript(String16 id, String16 url, String16 source)
|
| - : m_id(std::move(id)), m_url(std::move(url)), m_source(std::move(source)) {
|
| - int num_lines = 0;
|
| - int last_newline = -1;
|
| - size_t next_newline = m_source.find('\n', last_newline + 1);
|
| - while (next_newline != String16::kNotFound) {
|
| - last_newline = static_cast<int>(next_newline);
|
| - next_newline = m_source.find('\n', last_newline + 1);
|
| - ++num_lines;
|
| + private:
|
| + static const String16& emptyString() {
|
| + static const String16 singleEmptyString;
|
| + return singleEmptyString;
|
| }
|
| - m_endLine = num_lines;
|
| - m_endColumn = static_cast<int>(m_source.length()) - last_newline - 1;
|
| +
|
| + v8::Global<v8::debug::WasmScript> m_script;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create(
|
| + v8::Isolate* isolate, v8::Local<v8::debug::Script> scriptObj,
|
| + bool isLiveEdit) {
|
| + return std::unique_ptr<ActualScript>(
|
| + new ActualScript(isolate, scriptObj, isLiveEdit));
|
| +}
|
| +
|
| +std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm(
|
| + v8::Isolate* isolate, v8::Local<v8::debug::WasmScript> underlyingScript,
|
| + String16 id, String16 url, String16 source) {
|
| + return std::unique_ptr<WasmVirtualScript>(
|
| + new WasmVirtualScript(isolate, underlyingScript, std::move(id),
|
| + std::move(url), std::move(source)));
|
| }
|
|
|
| +V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id,
|
| + String16 url)
|
| + : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {}
|
| +
|
| V8DebuggerScript::~V8DebuggerScript() {}
|
|
|
| const String16& V8DebuggerScript::sourceURL() const {
|
| return m_sourceURL.isEmpty() ? m_url : m_sourceURL;
|
| }
|
|
|
| -String16 V8DebuggerScript::source(v8::Isolate* isolate) const {
|
| - if (m_sourceObj.IsEmpty()) return m_source;
|
| - return toProtocolString(m_sourceObj.Get(isolate));
|
| -}
|
| -
|
| const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const {
|
| if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate));
|
| DCHECK(!m_hash.isEmpty());
|
| @@ -162,22 +260,4 @@ void V8DebuggerScript::setSourceURL(const String16& sourceURL) {
|
| m_sourceURL = sourceURL;
|
| }
|
|
|
| -void V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) {
|
| - m_sourceMappingURL = sourceMappingURL;
|
| -}
|
| -
|
| -void V8DebuggerScript::setSource(v8::Local<v8::String> source) {
|
| - m_source = String16();
|
| - m_sourceObj.Reset(m_isolate, source);
|
| - m_hash = String16();
|
| -}
|
| -
|
| -bool V8DebuggerScript::getPossibleBreakpoints(
|
| - const v8::debug::Location& start, const v8::debug::Location& end,
|
| - std::vector<v8::debug::Location>* locations) {
|
| - v8::HandleScope scope(m_isolate);
|
| - v8::Local<v8::debug::Script> script = m_script.Get(m_isolate);
|
| - return script->GetPossibleBreakpoints(start, end, locations);
|
| -}
|
| -
|
| } // namespace v8_inspector
|
|
|