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 |