| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/inspector/v8-debugger-script.h" | 5 #include "src/inspector/v8-debugger-script.h" |
| 6 | 6 |
| 7 #include "src/inspector/string-util.h" | 7 #include "src/inspector/string-util.h" |
| 8 #include "src/inspector/wasm-translation.h" |
| 8 | 9 |
| 9 namespace v8_inspector { | 10 namespace v8_inspector { |
| 10 | 11 |
| 11 namespace { | 12 namespace { |
| 12 | 13 |
| 13 const char hexDigits[17] = "0123456789ABCDEF"; | 14 const char hexDigits[17] = "0123456789ABCDEF"; |
| 14 | 15 |
| 15 void appendUnsignedAsHex(uint64_t number, String16Builder* destination) { | 16 void appendUnsignedAsHex(uint64_t number, String16Builder* destination) { |
| 16 for (size_t i = 0; i < 8; ++i) { | 17 for (size_t i = 0; i < 8; ++i) { |
| 17 UChar c = hexDigits[number & 0xF]; | 18 UChar c = hexDigits[number & 0xF]; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 } | 62 } |
| 62 | 63 |
| 63 for (size_t i = 0; i < hashesSize; ++i) | 64 for (size_t i = 0; i < hashesSize; ++i) |
| 64 hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; | 65 hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; |
| 65 | 66 |
| 66 String16Builder hash; | 67 String16Builder hash; |
| 67 for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash); | 68 for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash); |
| 68 return hash.toString(); | 69 return hash.toString(); |
| 69 } | 70 } |
| 70 | 71 |
| 72 void TranslateProtocolLocationToV8Location(WasmTranslation* wasmTranslation, |
| 73 v8::DebugInterface::Location* loc, |
| 74 const String16& scriptId, |
| 75 const String16& expectedV8ScriptId) { |
| 76 if (loc->IsEmpty()) return; |
| 77 int lineNumber = loc->GetLineNumber(); |
| 78 int columnNumber = loc->GetColumnNumber(); |
| 79 String16 translatedScriptId = scriptId; |
| 80 wasmTranslation->TranslateProtocolLocationToWasmScriptLocation( |
| 81 &translatedScriptId, &lineNumber, &columnNumber); |
| 82 DCHECK_EQ(expectedV8ScriptId.utf8(), translatedScriptId.utf8()); |
| 83 *loc = v8::DebugInterface::Location(lineNumber, columnNumber); |
| 84 } |
| 85 |
| 86 void TranslateV8LocationToProtocolLocation( |
| 87 WasmTranslation* wasmTranslation, v8::DebugInterface::Location* loc, |
| 88 const String16& scriptId, const String16& expectedProtocolScriptId) { |
| 89 int lineNumber = loc->GetLineNumber(); |
| 90 int columnNumber = loc->GetColumnNumber(); |
| 91 String16 translatedScriptId = scriptId; |
| 92 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( |
| 93 &translatedScriptId, &lineNumber, &columnNumber); |
| 94 DCHECK_EQ(expectedProtocolScriptId.utf8(), translatedScriptId.utf8()); |
| 95 *loc = v8::DebugInterface::Location(lineNumber, columnNumber); |
| 96 } |
| 97 |
| 71 class ActualScript : public V8DebuggerScript { | 98 class ActualScript : public V8DebuggerScript { |
| 72 friend class V8DebuggerScript; | 99 friend class V8DebuggerScript; |
| 73 | 100 |
| 74 public: | 101 public: |
| 75 ActualScript(v8::Isolate* isolate, | 102 ActualScript(v8::Isolate* isolate, |
| 76 v8::Local<v8::DebugInterface::Script> script, bool isLiveEdit) | 103 v8::Local<v8::DebugInterface::Script> script, bool isLiveEdit) |
| 77 : V8DebuggerScript(isolate, String16::fromInteger(script->Id()), | 104 : V8DebuggerScript(isolate, String16::fromInteger(script->Id()), |
| 78 GetNameOrSourceUrl(script)), | 105 GetNameOrSourceUrl(script)), |
| 79 m_isLiveEdit(isLiveEdit) { | 106 m_isLiveEdit(isLiveEdit) { |
| 80 v8::Local<v8::String> tmp; | 107 v8::Local<v8::String> tmp; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 bool m_isLiveEdit = false; | 203 bool m_isLiveEdit = false; |
| 177 v8::Global<v8::DebugInterface::Script> m_script; | 204 v8::Global<v8::DebugInterface::Script> m_script; |
| 178 }; | 205 }; |
| 179 | 206 |
| 180 class WasmVirtualScript : public V8DebuggerScript { | 207 class WasmVirtualScript : public V8DebuggerScript { |
| 181 friend class V8DebuggerScript; | 208 friend class V8DebuggerScript; |
| 182 | 209 |
| 183 public: | 210 public: |
| 184 WasmVirtualScript(v8::Isolate* isolate, | 211 WasmVirtualScript(v8::Isolate* isolate, |
| 185 v8::Local<v8::DebugInterface::WasmScript> script, | 212 v8::Local<v8::DebugInterface::WasmScript> script, |
| 186 String16 id, String16 url, String16 source) | 213 WasmTranslation* translation, String16 id, String16 url, |
| 214 String16 source) |
| 187 : V8DebuggerScript(isolate, std::move(id), std::move(url)), | 215 : V8DebuggerScript(isolate, std::move(id), std::move(url)), |
| 188 m_script(isolate, script) { | 216 m_script(isolate, script), |
| 217 m_wasmTranslation(translation) { |
| 189 int num_lines = 0; | 218 int num_lines = 0; |
| 190 int last_newline = -1; | 219 int last_newline = -1; |
| 191 size_t next_newline = source.find('\n', last_newline + 1); | 220 size_t next_newline = source.find('\n', last_newline + 1); |
| 192 while (next_newline != String16::kNotFound) { | 221 while (next_newline != String16::kNotFound) { |
| 193 last_newline = static_cast<int>(next_newline); | 222 last_newline = static_cast<int>(next_newline); |
| 194 next_newline = source.find('\n', last_newline + 1); | 223 next_newline = source.find('\n', last_newline + 1); |
| 195 ++num_lines; | 224 ++num_lines; |
| 196 } | 225 } |
| 197 m_endLine = num_lines; | 226 m_endLine = num_lines; |
| 198 m_endColumn = static_cast<int>(source.length()) - last_newline - 1; | 227 m_endColumn = static_cast<int>(source.length()) - last_newline - 1; |
| 199 m_source = std::move(source); | 228 m_source = std::move(source); |
| 200 } | 229 } |
| 201 | 230 |
| 202 const String16& sourceMappingURL() const override { return emptyString(); } | 231 const String16& sourceMappingURL() const override { return emptyString(); } |
| 203 const String16& executionContextAuxData() const override { | 232 const String16& executionContextAuxData() const override { |
| 204 return emptyString(); | 233 return emptyString(); |
| 205 } | 234 } |
| 206 bool isLiveEdit() const override { return false; } | 235 bool isLiveEdit() const override { return false; } |
| 207 void setSourceMappingURL(const String16&) override {} | 236 void setSourceMappingURL(const String16&) override {} |
| 208 | 237 |
| 209 bool getPossibleBreakpoints( | 238 bool getPossibleBreakpoints( |
| 210 const v8::DebugInterface::Location& start, | 239 const v8::DebugInterface::Location& start, |
| 211 const v8::DebugInterface::Location& end, | 240 const v8::DebugInterface::Location& end, |
| 212 std::vector<v8::DebugInterface::Location>* locations) override { | 241 std::vector<v8::DebugInterface::Location>* locations) override { |
| 213 // TODO(clemensh): Returning false produces the protocol error "Internal | 242 v8::HandleScope scope(m_isolate); |
| 214 // error". Implement and fix expected output of | 243 v8::Local<v8::DebugInterface::Script> script = m_script.Get(m_isolate); |
| 215 // wasm-get-breakable-locations.js. | 244 String16 v8ScriptId = String16::fromInteger(script->Id()); |
| 216 return false; | 245 |
| 246 v8::DebugInterface::Location translatedStart = start; |
| 247 TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedStart, |
| 248 scriptId(), v8ScriptId); |
| 249 |
| 250 v8::DebugInterface::Location translatedEnd = end; |
| 251 TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedEnd, |
| 252 scriptId(), v8ScriptId); |
| 253 if (translatedEnd.IsEmpty()) { |
| 254 // Stop before the start of the next function. |
| 255 translatedEnd = |
| 256 v8::DebugInterface::Location(translatedStart.GetLineNumber() + 1, 0); |
| 257 } |
| 258 |
| 259 bool success = script->GetPossibleBreakpoints(translatedStart, |
| 260 translatedEnd, locations); |
| 261 for (v8::DebugInterface::Location& loc : *locations) { |
| 262 TranslateV8LocationToProtocolLocation(m_wasmTranslation, &loc, v8ScriptId, |
| 263 scriptId()); |
| 264 } |
| 265 return success; |
| 217 } | 266 } |
| 218 | 267 |
| 219 private: | 268 private: |
| 220 static const String16& emptyString() { | 269 static const String16& emptyString() { |
| 221 static const String16 singleEmptyString; | 270 static const String16 singleEmptyString; |
| 222 return singleEmptyString; | 271 return singleEmptyString; |
| 223 } | 272 } |
| 224 | 273 |
| 225 v8::Global<v8::DebugInterface::WasmScript> m_script; | 274 v8::Global<v8::DebugInterface::WasmScript> m_script; |
| 275 WasmTranslation* m_wasmTranslation; |
| 226 }; | 276 }; |
| 227 | 277 |
| 228 } // namespace | 278 } // namespace |
| 229 | 279 |
| 230 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( | 280 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( |
| 231 v8::Isolate* isolate, v8::Local<v8::DebugInterface::Script> scriptObj, | 281 v8::Isolate* isolate, v8::Local<v8::DebugInterface::Script> scriptObj, |
| 232 bool isLiveEdit) { | 282 bool isLiveEdit) { |
| 233 return std::unique_ptr<ActualScript>( | 283 return std::unique_ptr<ActualScript>( |
| 234 new ActualScript(isolate, scriptObj, isLiveEdit)); | 284 new ActualScript(isolate, scriptObj, isLiveEdit)); |
| 235 } | 285 } |
| 236 | 286 |
| 237 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( | 287 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( |
| 238 v8::Isolate* isolate, | 288 v8::Isolate* isolate, |
| 239 v8::Local<v8::DebugInterface::WasmScript> underlyingScript, String16 id, | 289 v8::Local<v8::DebugInterface::WasmScript> underlyingScript, |
| 240 String16 url, String16 source) { | 290 WasmTranslation* translation, String16 id, String16 url, String16 source) { |
| 241 return std::unique_ptr<WasmVirtualScript>( | 291 return std::unique_ptr<WasmVirtualScript>( |
| 242 new WasmVirtualScript(isolate, underlyingScript, std::move(id), | 292 new WasmVirtualScript(isolate, underlyingScript, translation, |
| 243 std::move(url), std::move(source))); | 293 std::move(id), std::move(url), std::move(source))); |
| 244 } | 294 } |
| 245 | 295 |
| 246 V8DebuggerScript::~V8DebuggerScript() {} | 296 V8DebuggerScript::~V8DebuggerScript() {} |
| 247 | 297 |
| 248 const String16& V8DebuggerScript::sourceURL() const { | 298 const String16& V8DebuggerScript::sourceURL() const { |
| 249 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; | 299 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; |
| 250 } | 300 } |
| 251 | 301 |
| 252 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { | 302 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { |
| 253 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); | 303 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); |
| 254 DCHECK(!m_hash.isEmpty()); | 304 DCHECK(!m_hash.isEmpty()); |
| 255 return m_hash; | 305 return m_hash; |
| 256 } | 306 } |
| 257 | 307 |
| 258 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { | 308 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { |
| 259 m_sourceURL = sourceURL; | 309 m_sourceURL = sourceURL; |
| 260 } | 310 } |
| 261 | 311 |
| 262 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, | 312 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, |
| 263 String16 url) | 313 String16 url) |
| 264 : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {} | 314 : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {} |
| 265 | 315 |
| 266 } // namespace v8_inspector | 316 } // namespace v8_inspector |
| OLD | NEW |