Chromium Code Reviews| 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 | 8 |
| 9 namespace v8_inspector { | 9 namespace v8_inspector { |
| 10 | 10 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 } | 59 } |
| 60 | 60 |
| 61 for (size_t i = 0; i < hashesSize; ++i) | 61 for (size_t i = 0; i < hashesSize; ++i) |
| 62 hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; | 62 hashes[i] = (hashes[i] + zi[i] * (prime[i] - 1)) % prime[i]; |
| 63 | 63 |
| 64 String16Builder hash; | 64 String16Builder hash; |
| 65 for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash); | 65 for (size_t i = 0; i < hashesSize; ++i) appendUnsignedAsHex(hashes[i], &hash); |
| 66 return hash.toString(); | 66 return hash.toString(); |
| 67 } | 67 } |
| 68 | 68 |
| 69 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, | 69 namespace { |
| 70 v8::Local<v8::DebugInterface::Script> script, | 70 |
| 71 bool isLiveEdit) { | 71 class ActualScript : public V8DebuggerScript { |
| 72 m_isolate = script->GetIsolate(); | 72 friend class V8DebuggerScript; |
| 73 m_id = String16::fromInteger(script->Id()); | 73 |
| 74 public: | |
| 75 ActualScript(v8::Local<v8::DebugInterface::Script> script, String16 url) | |
| 76 : V8DebuggerScript(script->GetIsolate(), | |
| 77 String16::fromInteger(script->Id()), std::move(url)) {} | |
| 78 | |
| 79 bool isLiveEdit() const override { return m_isLiveEdit; } | |
| 80 | |
| 81 const String16& executionContextAuxData() const override { | |
| 82 return m_executionContextAuxData; | |
| 83 } | |
| 84 | |
| 85 const String16& sourceMappingURL() const override { | |
| 86 return m_sourceMappingURL; | |
| 87 } | |
| 88 | |
| 89 String16 source(v8::Isolate* isolate) const override { | |
| 90 if (!m_sourceObj.IsEmpty()) | |
| 91 return toProtocolString(m_sourceObj.Get(isolate)); | |
| 92 return V8DebuggerScript::source(isolate); | |
| 93 } | |
| 94 | |
| 95 void setSourceMappingURL(const String16& sourceMappingURL) override { | |
| 96 m_sourceMappingURL = sourceMappingURL; | |
| 97 } | |
| 98 | |
| 99 void setSource(v8::Local<v8::String> source) override { | |
| 100 m_source = String16(); | |
| 101 m_sourceObj.Reset(m_isolate, source); | |
| 102 m_hash = String16(); | |
|
jgruber
2016/11/24 15:54:50
m_hash is duplicated in ActualScript and V8Debugge
Clemens Hammacher
2016/11/24 17:57:02
Wow, good catch. I remember that I wanted to check
| |
| 103 } | |
| 104 | |
| 105 bool getPossibleBreakpoints( | |
| 106 const v8::DebugInterface::Location& start, | |
| 107 const v8::DebugInterface::Location& end, | |
| 108 std::vector<v8::DebugInterface::Location>* locations) override { | |
| 109 v8::HandleScope scope(m_isolate); | |
| 110 v8::Local<v8::DebugInterface::Script> script = m_script.Get(m_isolate); | |
| 111 return script->GetPossibleBreakpoints(start, end, locations); | |
| 112 } | |
| 113 | |
| 114 private: | |
| 115 String16 m_sourceMappingURL; | |
| 116 v8::Global<v8::String> m_sourceObj; | |
| 117 String16 m_source; | |
|
jgruber
2016/11/24 15:54:50
Likewise for m_source.
Clemens Hammacher
2016/11/24 17:57:02
Done.
| |
| 118 mutable String16 m_hash; | |
| 119 String16 m_executionContextAuxData; | |
| 120 bool m_isLiveEdit = false; | |
| 121 v8::Global<v8::DebugInterface::Script> m_script; | |
| 122 }; | |
| 123 | |
| 124 class WasmVirtualScript : public V8DebuggerScript { | |
| 125 friend class V8DebuggerScript; | |
| 126 | |
| 127 public: | |
| 128 WasmVirtualScript(v8::Local<v8::DebugInterface::Script> script, String16 id, | |
| 129 String16 url, String16 source) | |
| 130 : V8DebuggerScript(script->GetIsolate(), std::move(id), std::move(url)), | |
| 131 m_script(script->GetIsolate(), script) { | |
| 132 m_source = std::move(source); | |
| 133 } | |
| 134 | |
| 135 const String16& sourceMappingURL() const override { return emptyString(); } | |
| 136 const String16& executionContextAuxData() const override { | |
| 137 return emptyString(); | |
| 138 } | |
| 139 bool isLiveEdit() const override { return false; } | |
| 140 | |
| 141 bool getPossibleBreakpoints( | |
| 142 const v8::DebugInterface::Location& start, | |
| 143 const v8::DebugInterface::Location& end, | |
| 144 std::vector<v8::DebugInterface::Location>* locations) override { | |
| 145 // TODO(clemensh): Returning false produces the protocol error "Internal | |
| 146 // error". Implement and fix expected output of | |
| 147 // wasm-get-breakable-locations.js. | |
| 148 return false; | |
| 149 } | |
| 150 | |
| 151 private: | |
| 152 static const String16& emptyString() { | |
| 153 static const String16 singleEmptyString; | |
| 154 return singleEmptyString; | |
| 155 } | |
| 156 | |
| 157 // TODO(clemensh): Move away from using scripts for wasm (bug 667767). | |
| 158 v8::Global<v8::DebugInterface::Script> m_script; | |
| 159 }; | |
| 160 | |
| 161 } // namespace | |
| 162 | |
| 163 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::Create( | |
| 164 v8::Isolate* isolate, v8::Local<v8::DebugInterface::Script> scriptObj, | |
| 165 bool isLiveEdit) { | |
| 166 String16 url; | |
| 167 String16 sourceUrl; | |
| 74 v8::Local<v8::String> tmp; | 168 v8::Local<v8::String> tmp; |
| 75 if (script->Name().ToLocal(&tmp)) m_url = toProtocolString(tmp); | 169 if (scriptObj->Name().ToLocal(&tmp)) url = toProtocolString(tmp); |
| 76 if (script->SourceURL().ToLocal(&tmp)) { | 170 if (scriptObj->SourceURL().ToLocal(&tmp)) { |
| 77 m_sourceURL = toProtocolString(tmp); | 171 sourceUrl = toProtocolString(tmp); |
| 78 if (m_url.isEmpty()) m_url = toProtocolString(tmp); | 172 if (url.isEmpty()) url = sourceUrl; |
| 79 } | 173 } |
| 80 if (script->SourceMappingURL().ToLocal(&tmp)) | 174 std::unique_ptr<ActualScript> script(new ActualScript(scriptObj, url)); |
| 81 m_sourceMappingURL = toProtocolString(tmp); | 175 script->m_sourceURL = std::move(sourceUrl); |
| 82 m_startLine = script->LineOffset(); | 176 if (scriptObj->SourceMappingURL().ToLocal(&tmp)) |
| 83 m_startColumn = script->ColumnOffset(); | 177 script->m_sourceMappingURL = toProtocolString(tmp); |
| 84 std::vector<int> lineEnds = script->LineEnds(); | 178 script->m_startLine = scriptObj->LineOffset(); |
| 179 script->m_startColumn = scriptObj->ColumnOffset(); | |
| 180 std::vector<int> lineEnds = scriptObj->LineEnds(); | |
| 85 CHECK(lineEnds.size()); | 181 CHECK(lineEnds.size()); |
| 86 int source_length = lineEnds[lineEnds.size() - 1]; | 182 int source_length = lineEnds[lineEnds.size() - 1]; |
| 87 if (lineEnds.size()) { | 183 if (lineEnds.size()) { |
| 88 m_endLine = static_cast<int>(lineEnds.size()) + m_startLine - 1; | 184 script->m_endLine = |
| 185 static_cast<int>(lineEnds.size()) + script->m_startLine - 1; | |
| 89 if (lineEnds.size() > 1) { | 186 if (lineEnds.size() > 1) { |
| 90 m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; | 187 script->m_endColumn = source_length - lineEnds[lineEnds.size() - 2] - 1; |
| 91 } else { | 188 } else { |
| 92 m_endColumn = source_length + m_startColumn; | 189 script->m_endColumn = source_length + script->m_startColumn; |
| 93 } | 190 } |
| 94 } else { | 191 } else { |
| 95 m_endLine = m_startLine; | 192 script->m_endLine = script->m_startLine; |
| 96 m_endColumn = m_startColumn; | 193 script->m_endColumn = script->m_startColumn; |
| 97 } | 194 } |
| 98 | 195 |
| 99 if (script->ContextData().ToLocal(&tmp)) { | 196 if (scriptObj->ContextData().ToLocal(&tmp)) { |
| 100 String16 contextData = toProtocolString(tmp); | 197 String16 contextData = toProtocolString(tmp); |
| 101 size_t firstComma = contextData.find(",", 0); | 198 size_t firstComma = contextData.find(",", 0); |
| 102 size_t secondComma = firstComma != String16::kNotFound | 199 size_t secondComma = firstComma != String16::kNotFound |
| 103 ? contextData.find(",", firstComma + 1) | 200 ? contextData.find(",", firstComma + 1) |
| 104 : String16::kNotFound; | 201 : String16::kNotFound; |
| 105 if (secondComma != String16::kNotFound) { | 202 if (secondComma != String16::kNotFound) { |
| 106 String16 executionContextId = | 203 String16 executionContextId = |
| 107 contextData.substring(firstComma + 1, secondComma - firstComma - 1); | 204 contextData.substring(firstComma + 1, secondComma - firstComma - 1); |
| 108 bool isOk = false; | 205 bool isOk = false; |
| 109 m_executionContextId = executionContextId.toInteger(&isOk); | 206 script->m_executionContextId = executionContextId.toInteger(&isOk); |
| 110 if (!isOk) m_executionContextId = 0; | 207 if (!isOk) script->m_executionContextId = 0; |
| 111 m_executionContextAuxData = contextData.substring(secondComma + 1); | 208 script->m_executionContextAuxData = |
| 209 contextData.substring(secondComma + 1); | |
| 112 } | 210 } |
| 113 } | 211 } |
| 114 | 212 |
| 115 m_isLiveEdit = isLiveEdit; | 213 script->m_isLiveEdit = isLiveEdit; |
| 116 | 214 |
| 117 if (script->Source().ToLocal(&tmp)) { | 215 if (scriptObj->Source().ToLocal(&tmp)) { |
| 118 m_sourceObj.Reset(m_isolate, tmp); | 216 script->m_sourceObj.Reset(script->m_isolate, tmp); |
| 119 String16 source = toProtocolString(tmp); | 217 String16 source = toProtocolString(tmp); |
| 120 // V8 will not count last line if script source ends with \n. | 218 // V8 will not count last line if script source ends with \n. |
| 121 if (source.length() > 1 && source[source.length() - 1] == '\n') { | 219 if (source.length() > 1 && source[source.length() - 1] == '\n') { |
| 122 m_endLine++; | 220 script->m_endLine++; |
| 123 m_endColumn = 0; | 221 script->m_endColumn = 0; |
| 124 } | 222 } |
| 125 } | 223 } |
| 126 | 224 |
| 127 m_script.Reset(m_isolate, script); | 225 script->m_script.Reset(script->m_isolate, scriptObj); |
| 226 return std::move(script); | |
| 128 } | 227 } |
| 129 | 228 |
| 130 V8DebuggerScript::V8DebuggerScript(String16 id, String16 url, String16 source) | 229 std::unique_ptr<V8DebuggerScript> V8DebuggerScript::CreateWasm( |
| 131 : m_id(std::move(id)), m_url(std::move(url)), m_source(std::move(source)) { | 230 v8::Local<v8::DebugInterface::Script> script, String16 id, String16 url, |
| 231 String16 source) { | |
| 132 int num_lines = 0; | 232 int num_lines = 0; |
| 133 int last_newline = -1; | 233 int last_newline = -1; |
| 134 size_t next_newline = m_source.find('\n', last_newline + 1); | 234 size_t next_newline = source.find('\n', last_newline + 1); |
| 135 while (next_newline != String16::kNotFound) { | 235 while (next_newline != String16::kNotFound) { |
| 136 last_newline = static_cast<int>(next_newline); | 236 last_newline = static_cast<int>(next_newline); |
| 137 next_newline = m_source.find('\n', last_newline + 1); | 237 next_newline = source.find('\n', last_newline + 1); |
| 138 ++num_lines; | 238 ++num_lines; |
| 139 } | 239 } |
| 140 m_endLine = num_lines; | 240 int m_endLine = num_lines; |
| 141 m_endColumn = static_cast<int>(m_source.length()) - last_newline - 1; | 241 int m_endColumn = static_cast<int>(source.length()) - last_newline - 1; |
| 242 return std::unique_ptr<WasmVirtualScript>(new WasmVirtualScript( | |
| 243 script, std::move(id), std::move(url), std::move(source))); | |
| 142 } | 244 } |
| 143 | 245 |
| 144 V8DebuggerScript::~V8DebuggerScript() {} | 246 V8DebuggerScript::~V8DebuggerScript() {} |
| 145 | 247 |
| 146 const String16& V8DebuggerScript::sourceURL() const { | 248 const String16& V8DebuggerScript::sourceURL() const { |
| 147 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; | 249 return m_sourceURL.isEmpty() ? m_url : m_sourceURL; |
| 148 } | 250 } |
| 149 | 251 |
| 150 String16 V8DebuggerScript::source(v8::Isolate* isolate) const { | |
| 151 if (m_sourceObj.IsEmpty()) return m_source; | |
| 152 return toProtocolString(m_sourceObj.Get(isolate)); | |
| 153 } | |
| 154 | |
| 155 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { | 252 const String16& V8DebuggerScript::hash(v8::Isolate* isolate) const { |
| 156 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); | 253 if (m_hash.isEmpty()) m_hash = calculateHash(source(isolate)); |
| 157 DCHECK(!m_hash.isEmpty()); | 254 DCHECK(!m_hash.isEmpty()); |
| 158 return m_hash; | 255 return m_hash; |
| 159 } | 256 } |
| 160 | 257 |
| 161 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { | 258 void V8DebuggerScript::setSourceURL(const String16& sourceURL) { |
| 162 m_sourceURL = sourceURL; | 259 m_sourceURL = sourceURL; |
| 163 } | 260 } |
| 164 | 261 |
| 165 void V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) { | 262 V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate, String16 id, |
| 166 m_sourceMappingURL = sourceMappingURL; | 263 String16 url) |
| 167 } | 264 : m_id(std::move(id)), m_url(std::move(url)), m_isolate(isolate) {} |
| 168 | |
| 169 void V8DebuggerScript::setSource(v8::Local<v8::String> source) { | |
| 170 m_source = String16(); | |
| 171 m_sourceObj.Reset(m_isolate, source); | |
| 172 m_hash = String16(); | |
| 173 } | |
| 174 | |
| 175 bool V8DebuggerScript::getPossibleBreakpoints( | |
| 176 const v8::DebugInterface::Location& start, | |
| 177 const v8::DebugInterface::Location& end, | |
| 178 std::vector<v8::DebugInterface::Location>* locations) { | |
| 179 v8::HandleScope scope(m_isolate); | |
| 180 v8::Local<v8::DebugInterface::Script> script = m_script.Get(m_isolate); | |
| 181 return script->GetPossibleBreakpoints(start, end, locations); | |
| 182 } | |
| 183 | 265 |
| 184 } // namespace v8_inspector | 266 } // namespace v8_inspector |
| OLD | NEW |