| 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 // This call should never trigger a new fake script to be created, so passing |
| 93 // -1 as contextGroupId is fine. A DCHECK in the wasm translation will fail |
| 94 // whenever this contextGroupId is used to find the corrensponding debugger |
| 95 // agent. |
| 96 wasmTranslation->TranslateWasmScriptLocationToProtocolLocation( |
| 97 &translatedScriptId, &lineNumber, &columnNumber, -1); |
| 98 DCHECK_EQ(expectedProtocolScriptId.utf8(), translatedScriptId.utf8()); |
| 99 *loc = v8::DebugInterface::Location(lineNumber, columnNumber); |
| 100 } |
| 101 |
| 71 class ActualScript : public V8DebuggerScript { | 102 class ActualScript : public V8DebuggerScript { |
| 72 friend class V8DebuggerScript; | 103 friend class V8DebuggerScript; |
| 73 | 104 |
| 74 public: | 105 public: |
| 75 ActualScript(v8::Local<v8::DebugInterface::Script> script, String16 url) | 106 ActualScript(v8::Local<v8::DebugInterface::Script> script, String16 url) |
| 76 : V8DebuggerScript(script->GetIsolate(), | 107 : V8DebuggerScript(script->GetIsolate(), |
| 77 String16::fromInteger(script->Id()), std::move(url)) {} | 108 String16::fromInteger(script->Id()), std::move(url)) {} |
| 78 | 109 |
| 79 bool isLiveEdit() const override { return m_isLiveEdit; } | 110 bool isLiveEdit() const override { return m_isLiveEdit; } |
| 80 | 111 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 v8::Global<v8::String> m_sourceObj; | 147 v8::Global<v8::String> m_sourceObj; |
| 117 String16 m_executionContextAuxData; | 148 String16 m_executionContextAuxData; |
| 118 bool m_isLiveEdit = false; | 149 bool m_isLiveEdit = false; |
| 119 v8::Global<v8::DebugInterface::Script> m_script; | 150 v8::Global<v8::DebugInterface::Script> m_script; |
| 120 }; | 151 }; |
| 121 | 152 |
| 122 class WasmVirtualScript : public V8DebuggerScript { | 153 class WasmVirtualScript : public V8DebuggerScript { |
| 123 friend class V8DebuggerScript; | 154 friend class V8DebuggerScript; |
| 124 | 155 |
| 125 public: | 156 public: |
| 126 WasmVirtualScript(v8::Local<v8::DebugInterface::Script> script, String16 id, | 157 WasmVirtualScript(v8::Local<v8::DebugInterface::Script> script, |
| 127 String16 url, String16 source) | 158 WasmTranslation* translation, String16 id, String16 url, |
| 159 String16 source) |
| 128 : V8DebuggerScript(script->GetIsolate(), std::move(id), std::move(url)), | 160 : V8DebuggerScript(script->GetIsolate(), std::move(id), std::move(url)), |
| 129 m_script(script->GetIsolate(), script) { | 161 m_script(script->GetIsolate(), script), |
| 162 m_wasmTranslation(translation) { |
| 130 m_source = std::move(source); | 163 m_source = std::move(source); |
| 131 } | 164 } |
| 132 | 165 |
| 133 const String16& sourceMappingURL() const override { return emptyString(); } | 166 const String16& sourceMappingURL() const override { return emptyString(); } |
| 134 const String16& executionContextAuxData() const override { | 167 const String16& executionContextAuxData() const override { |
| 135 return emptyString(); | 168 return emptyString(); |
| 136 } | 169 } |
| 137 bool isLiveEdit() const override { return false; } | 170 bool isLiveEdit() const override { return false; } |
| 138 | 171 |
| 139 bool getPossibleBreakpoints( | 172 bool getPossibleBreakpoints( |
| 140 const v8::DebugInterface::Location& start, | 173 const v8::DebugInterface::Location& start, |
| 141 const v8::DebugInterface::Location& end, | 174 const v8::DebugInterface::Location& end, |
| 142 std::vector<v8::DebugInterface::Location>* locations) override { | 175 std::vector<v8::DebugInterface::Location>* locations) override { |
| 143 // TODO(clemensh): Returning false produces the protocol error "Internal | 176 v8::HandleScope scope(m_isolate); |
| 144 // error". Implement and fix expected output of | 177 v8::Local<v8::DebugInterface::Script> script = m_script.Get(m_isolate); |
| 145 // wasm-get-breakable-locations.js. | 178 String16 v8ScriptId = String16::fromInteger(script->Id()); |
| 146 return false; | 179 |
| 180 v8::DebugInterface::Location translatedStart = start; |
| 181 TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedStart, |
| 182 scriptId(), v8ScriptId); |
| 183 |
| 184 v8::DebugInterface::Location translatedEnd = end; |
| 185 TranslateProtocolLocationToV8Location(m_wasmTranslation, &translatedEnd, |
| 186 scriptId(), v8ScriptId); |
| 187 if (translatedEnd.IsEmpty()) { |
| 188 // Stop before the start of the next function. |
| 189 translatedEnd = |
| 190 v8::DebugInterface::Location(translatedStart.GetLineNumber() + 1, 0); |
| 191 } |
| 192 |
| 193 bool success = script->GetPossibleBreakpoints(translatedStart, |
| 194 translatedEnd, locations); |
| 195 for (v8::DebugInterface::Location& loc : *locations) { |
| 196 TranslateV8LocationToProtocolLocation(m_wasmTranslation, &loc, v8ScriptId, |
| 197 scriptId()); |
| 198 } |
| 199 return success; |
| 147 } | 200 } |
| 148 | 201 |
| 149 private: | 202 private: |
| 150 static const String16& emptyString() { | 203 static const String16& emptyString() { |
| 151 static const String16 singleEmptyString; | 204 static const String16 singleEmptyString; |
| 152 return singleEmptyString; | 205 return singleEmptyString; |
| 153 } | 206 } |
| 154 | 207 |
| 155 v8::Global<v8::DebugInterface::Script> m_script; | 208 v8::Global<v8::DebugInterface::Script> m_script; |
| 209 WasmTranslation* m_wasmTranslation; |
| 156 }; | 210 }; |
| 157 | 211 |
| 158 } // namespace | 212 } // namespace |
| 159 | 213 |
| 160 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( | 214 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( |
| 161 v8::Isolate* isolate, v8::Local<v8::DebugInterface::Script> scriptObj, | 215 v8::Isolate* isolate, v8::Local<v8::DebugInterface::Script> scriptObj, |
| 162 bool isLiveEdit) { | 216 bool isLiveEdit) { |
| 163 String16 url; | 217 String16 url; |
| 164 String16 sourceUrl; | 218 String16 sourceUrl; |
| 165 v8::Local<v8::String> tmp; | 219 v8::Local<v8::String> tmp; |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 script->m_endLine++; | 271 script->m_endLine++; |
| 218 script->m_endColumn = 0; | 272 script->m_endColumn = 0; |
| 219 } | 273 } |
| 220 } | 274 } |
| 221 | 275 |
| 222 script->m_script.Reset(script->m_isolate, scriptObj); | 276 script->m_script.Reset(script->m_isolate, scriptObj); |
| 223 return std::move(script); | 277 return std::move(script); |
| 224 } | 278 } |
| 225 | 279 |
| 226 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( | 280 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( |
| 227 v8::Local<v8::DebugInterface::Script> script, String16 id, String16 url, | 281 v8::Local<v8::DebugInterface::Script> script, |
| 282 WasmTranslation* wasmTranslation, String16 id, String16 url, |
| 228 String16 source) { | 283 String16 source) { |
| 229 int num_lines = 0; | 284 int num_lines = 0; |
| 230 int last_newline = -1; | 285 int last_newline = -1; |
| 231 size_t next_newline = source.find('\n', last_newline + 1); | 286 size_t next_newline = source.find('\n', last_newline + 1); |
| 232 while (next_newline != String16::kNotFound) { | 287 while (next_newline != String16::kNotFound) { |
| 233 last_newline = static_cast<int>(next_newline); | 288 last_newline = static_cast<int>(next_newline); |
| 234 next_newline = source.find('\n', last_newline + 1); | 289 next_newline = source.find('\n', last_newline + 1); |
| 235 ++num_lines; | 290 ++num_lines; |
| 236 } | 291 } |
| 237 int m_endLine = num_lines; | 292 int m_endLine = num_lines; |
| 238 int m_endColumn = static_cast<int>(source.length()) - last_newline - 1; | 293 int m_endColumn = static_cast<int>(source.length()) - last_newline - 1; |
| 239 return std::unique_ptr<WasmVirtualScript>(new WasmVirtualScript( | 294 return std::unique_ptr<WasmVirtualScript>( |
| 240 script, std::move(id), std::move(url), std::move(source))); | 295 new WasmVirtualScript(script, wasmTranslation, std::move(id), |
| 296 std::move(url), std::move(source))); |
| 241 } | 297 } |
| 242 | 298 |
| 243 V8DebuggerScript::~V8DebuggerScript() {} | 299 V8DebuggerScript::~V8DebuggerScript() {} |
| 244 | 300 |
| 245 const String16& V8DebuggerScript::sourceURL() const { | 301 const String16& V8DebuggerScript::sourceURL() const { |
| 246 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; | 302 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; |
| 247 } | 303 } |
| 248 | 304 |
| 249 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { | 305 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { |
| 250 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); | 306 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); |
| 251 DCHECK(!m_hash.isEmpty()); | 307 DCHECK(!m_hash.isEmpty()); |
| 252 return m_hash; | 308 return m_hash; |
| 253 } | 309 } |
| 254 | 310 |
| 255 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { | 311 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { |
| 256 m_sourceURL = sourceURL; | 312 m_sourceURL = sourceURL; |
| 257 } | 313 } |
| 258 | 314 |
| 259 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, | 315 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, |
| 260 String16 url) | 316 String16 url) |
| 261 : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {} | 317 : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {} |
| 262 | 318 |
| 263 } // namespace v8_inspector | 319 } // namespace v8_inspector |
| OLD | NEW |