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 |