Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(313)

Side by Side Diff: src/inspector/wasm-translation.cc

Issue 2655653003: [inspector] Expose GetPossibleBreakpoints for wasm (Closed)
Patch Set: Address comments Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/wasm-translation.h" 5 #include "src/inspector/wasm-translation.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "src/debug/debug-interface.h" 9 #include "src/debug/debug-interface.h"
10 #include "src/inspector/protocol/Debugger.h" 10 #include "src/inspector/protocol/Debugger.h"
(...skipping 15 matching lines...) Expand all
26 int line; 26 int line;
27 int column; 27 int column;
28 TransLocation(WasmTranslation *translation, String16 script_id, int line, 28 TransLocation(WasmTranslation *translation, String16 script_id, int line,
29 int column) 29 int column)
30 : translation(translation), 30 : translation(translation),
31 script_id(script_id), 31 script_id(script_id),
32 line(line), 32 line(line),
33 column(column) {} 33 column(column) {}
34 }; 34 };
35 35
36 TranslatorImpl(WasmTranslation* translation, int script_id) {
37 DCHECK_EQ(0, translation->wasm_translators_.count(script_id));
38 translation->wasm_translators_.insert(
39 std::make_pair(script_id, std::unique_ptr<TranslatorImpl>(this)));
40 }
41
36 virtual void Translate(TransLocation *loc) = 0; 42 virtual void Translate(TransLocation *loc) = 0;
37 virtual void TranslateBack(TransLocation *loc) = 0; 43 virtual void TranslateBack(TransLocation *loc) = 0;
38 44
39 class RawTranslator; 45 class RawTranslator;
40 class DisassemblingTranslator; 46 class DisassemblingTranslator;
41 }; 47 };
42 48
43 class WasmTranslation::TranslatorImpl::RawTranslator 49 class WasmTranslation::TranslatorImpl::RawTranslator
44 : public WasmTranslation::TranslatorImpl { 50 : public WasmTranslation::TranslatorImpl {
45 public: 51 public:
52 RawTranslator(WasmTranslation* translation, Local<debug::WasmScript> script)
53 : TranslatorImpl(translation, script->Id()) {}
46 void Translate(TransLocation *loc) {} 54 void Translate(TransLocation *loc) {}
47 void TranslateBack(TransLocation *loc) {} 55 void TranslateBack(TransLocation *loc) {}
48 }; 56 };
49 57
50 class WasmTranslation::TranslatorImpl::DisassemblingTranslator 58 class WasmTranslation::TranslatorImpl::DisassemblingTranslator
51 : public WasmTranslation::TranslatorImpl { 59 : public WasmTranslation::TranslatorImpl {
52 using OffsetTable = debug::WasmDisassembly::OffsetTable; 60 using OffsetTable = debug::WasmDisassembly::OffsetTable;
53 61
54 public: 62 public:
55 DisassemblingTranslator(Isolate *isolate, Local<debug::WasmScript> script, 63 DisassemblingTranslator(Isolate* isolate, Local<debug::WasmScript> script,
56 WasmTranslation *translation, 64 WasmTranslation* translation,
57 V8DebuggerAgentImpl *agent) 65 V8DebuggerAgentImpl* agent)
58 : script_(isolate, script) { 66 : TranslatorImpl(translation, script->Id()), script_(isolate, script) {
59 // Register fake scripts for each function in this wasm module/script. 67 // Register fake scripts for each function in this wasm module/script.
60 int num_functions = script->NumFunctions(); 68 int num_functions = script->NumFunctions();
61 int num_imported_functions = script->NumImportedFunctions(); 69 int num_imported_functions = script->NumImportedFunctions();
62 DCHECK_LE(0, num_imported_functions); 70 DCHECK_LE(0, num_imported_functions);
63 DCHECK_LE(0, num_functions); 71 DCHECK_LE(0, num_functions);
64 DCHECK_GE(num_functions, num_imported_functions); 72 DCHECK_GE(num_functions, num_imported_functions);
65 String16 script_id = String16::fromInteger(script->Id()); 73 String16 script_id = String16::fromInteger(script->Id());
66 for (int func_idx = num_imported_functions; func_idx < num_functions; 74 for (int func_idx = num_imported_functions; func_idx < num_functions;
67 ++func_idx) { 75 ++func_idx) {
68 AddFakeScript(isolate, script_id, func_idx, translation, agent); 76 AddFakeScript(isolate, script_id, func_idx, translation, agent);
(...skipping 25 matching lines...) Expand all
94 loc->line = 0; 102 loc->line = 0;
95 loc->column = 0; 103 loc->column = 0;
96 } 104 }
97 } 105 }
98 106
99 void TranslateBack(TransLocation *loc) { 107 void TranslateBack(TransLocation *loc) {
100 int func_index = GetFunctionIndexFromFakeScriptId(loc->script_id); 108 int func_index = GetFunctionIndexFromFakeScriptId(loc->script_id);
101 const OffsetTable *reverse_table = GetReverseTable(func_index); 109 const OffsetTable *reverse_table = GetReverseTable(func_index);
102 if (!reverse_table) return; 110 if (!reverse_table) return;
103 DCHECK(!reverse_table->empty()); 111 DCHECK(!reverse_table->empty());
112 v8::Isolate* isolate = loc->translation->isolate_;
104 113
105 // Binary search for the given line and column. 114 // Binary search for the given line and column.
106 unsigned left = 0; // inclusive 115 unsigned left = 0; // inclusive
107 unsigned right = static_cast<unsigned>(reverse_table->size()); // exclusive 116 unsigned right = static_cast<unsigned>(reverse_table->size()); // exclusive
108 while (right - left > 1) { 117 while (right - left > 1) {
109 unsigned mid = (left + right) / 2; 118 unsigned mid = (left + right) / 2;
110 auto &entry = (*reverse_table)[mid]; 119 auto &entry = (*reverse_table)[mid];
111 if (entry.line < loc->line || 120 if (entry.line < loc->line ||
112 (entry.line == loc->line && entry.column <= loc->column)) { 121 (entry.line == loc->line && entry.column <= loc->column)) {
113 left = mid; 122 left = mid;
114 } else { 123 } else {
115 right = mid; 124 right = mid;
116 } 125 }
117 } 126 }
118 127
119 int found_byte_offset = 0; 128 int found_byte_offset = 0;
120 // If we found an exact match, use it. Otherwise check whether the next 129 // If we found an exact match, use it. Otherwise check whether the next
121 // bigger entry is still in the same line. Report that one then. 130 // bigger entry is still in the same line. Report that one then.
131 // Otherwise we might have hit the special case of pointing after the last
132 // line, which is translated to the end of the function (one byte after the
133 // last function byte).
122 if ((*reverse_table)[left].line == loc->line && 134 if ((*reverse_table)[left].line == loc->line &&
123 (*reverse_table)[left].column == loc->column) { 135 (*reverse_table)[left].column == loc->column) {
124 found_byte_offset = (*reverse_table)[left].byte_offset; 136 found_byte_offset = (*reverse_table)[left].byte_offset;
125 } else if (left + 1 < reverse_table->size() && 137 } else if (left + 1 < reverse_table->size() &&
126 (*reverse_table)[left + 1].line == loc->line) { 138 (*reverse_table)[left + 1].line == loc->line) {
127 found_byte_offset = (*reverse_table)[left + 1].byte_offset; 139 found_byte_offset = (*reverse_table)[left + 1].byte_offset;
140 } else if (left == reverse_table->size() - 1 &&
141 (*reverse_table)[left].line == loc->line - 1 &&
142 loc->column == 0) {
143 std::pair<int, int> func_range =
144 script_.Get(isolate)->GetFunctionRange(func_index);
145 DCHECK_LE(func_range.first, func_range.second);
146 found_byte_offset = func_range.second - func_range.first;
128 } 147 }
129 148
130 v8::Isolate *isolate = loc->translation->isolate_;
131 loc->script_id = String16::fromInteger(script_.Get(isolate)->Id()); 149 loc->script_id = String16::fromInteger(script_.Get(isolate)->Id());
132 loc->line = func_index; 150 loc->line = func_index;
133 loc->column = found_byte_offset; 151 loc->column = found_byte_offset;
134 } 152 }
135 153
136 private: 154 private:
137 String16 GetFakeScriptUrl(v8::Isolate *isolate, int func_index) { 155 String16 GetFakeScriptUrl(v8::Isolate *isolate, int func_index) {
138 Local<debug::WasmScript> script = script_.Get(isolate); 156 Local<debug::WasmScript> script = script_.Get(isolate);
139 String16 script_name = toProtocolString(script->Name().ToLocalChecked()); 157 String16 script_name = toProtocolString(script->Name().ToLocalChecked());
140 int numFunctions = script->NumFunctions(); 158 int numFunctions = script->NumFunctions();
(...skipping 29 matching lines...) Expand all
170 v8::Local<debug::WasmScript> script = script_.Get(isolate); 188 v8::Local<debug::WasmScript> script = script_.Get(isolate);
171 // TODO(clemensh): Generate disassembly lazily when queried by the frontend. 189 // TODO(clemensh): Generate disassembly lazily when queried by the frontend.
172 debug::WasmDisassembly disassembly = script->DisassembleFunction(func_idx); 190 debug::WasmDisassembly disassembly = script->DisassembleFunction(func_idx);
173 191
174 DCHECK_EQ(0, offset_tables_.count(func_idx)); 192 DCHECK_EQ(0, offset_tables_.count(func_idx));
175 offset_tables_.insert( 193 offset_tables_.insert(
176 std::make_pair(func_idx, std::move(disassembly.offset_table))); 194 std::make_pair(func_idx, std::move(disassembly.offset_table)));
177 String16 source(disassembly.disassembly.data(), 195 String16 source(disassembly.disassembly.data(),
178 disassembly.disassembly.length()); 196 disassembly.disassembly.length());
179 std::unique_ptr<V8DebuggerScript> fake_script = 197 std::unique_ptr<V8DebuggerScript> fake_script =
180 V8DebuggerScript::CreateWasm(isolate, script, fake_script_id, 198 V8DebuggerScript::CreateWasm(isolate, translation, script,
181 std::move(fake_script_url), source); 199 fake_script_id, std::move(fake_script_url),
200 source);
182 201
183 translation->AddFakeScript(fake_script->scriptId(), this); 202 translation->AddFakeScript(fake_script->scriptId(), this);
184 agent->didParseSource(std::move(fake_script), true); 203 agent->didParseSource(std::move(fake_script), true);
185 } 204 }
186 205
187 int GetFunctionIndexFromFakeScriptId(const String16 &fake_script_id) { 206 int GetFunctionIndexFromFakeScriptId(const String16 &fake_script_id) {
188 size_t last_dash_pos = fake_script_id.reverseFind('-'); 207 size_t last_dash_pos = fake_script_id.reverseFind('-');
189 DCHECK_GT(fake_script_id.length(), last_dash_pos); 208 DCHECK_GT(fake_script_id.length(), last_dash_pos);
190 bool ok = true; 209 bool ok = true;
191 int func_index = fake_script_id.substring(last_dash_pos + 1).toInteger(&ok); 210 int func_index = fake_script_id.substring(last_dash_pos + 1).toInteger(&ok);
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 std::unordered_map<int, const OffsetTable> reverse_tables_; 252 std::unordered_map<int, const OffsetTable> reverse_tables_;
234 }; 253 };
235 254
236 WasmTranslation::WasmTranslation(v8::Isolate *isolate) 255 WasmTranslation::WasmTranslation(v8::Isolate *isolate)
237 : isolate_(isolate), mode_(Disassemble) {} 256 : isolate_(isolate), mode_(Disassemble) {}
238 257
239 WasmTranslation::~WasmTranslation() { Clear(); } 258 WasmTranslation::~WasmTranslation() { Clear(); }
240 259
241 void WasmTranslation::AddScript(Local<debug::WasmScript> script, 260 void WasmTranslation::AddScript(Local<debug::WasmScript> script,
242 V8DebuggerAgentImpl *agent) { 261 V8DebuggerAgentImpl *agent) {
243 int script_id = script->Id(); 262 // Instantiate new TranslatorImpls via new, the base class will register them
244 DCHECK_EQ(0, wasm_translators_.count(script_id)); 263 // in wasm_translators_, taking ownership. This early registration is
245 std::unique_ptr<TranslatorImpl> impl; 264 // necessary since the DisassemblingTranslator constructor already registers
265 // the fake scripts, which triggers setting breakpoints.
246 switch (mode_) { 266 switch (mode_) {
247 case Raw: 267 case Raw:
248 impl.reset(new TranslatorImpl::RawTranslator()); 268 new TranslatorImpl::RawTranslator(this, script);
249 break; 269 return;
250 case Disassemble: 270 case Disassemble:
251 impl.reset(new TranslatorImpl::DisassemblingTranslator(isolate_, script, 271 new TranslatorImpl::DisassemblingTranslator(isolate_, script, this,
252 this, agent)); 272 agent);
253 break; 273 return;
254 } 274 }
255 DCHECK(impl); 275 UNREACHABLE();
256 wasm_translators_.insert(std::make_pair(script_id, std::move(impl)));
257 } 276 }
258 277
259 void WasmTranslation::Clear() { 278 void WasmTranslation::Clear() {
260 wasm_translators_.clear(); 279 wasm_translators_.clear();
261 fake_scripts_.clear(); 280 fake_scripts_.clear();
262 } 281 }
263 282
264 // Translation "forward" (to artificial scripts). 283 // Translation "forward" (to artificial scripts).
265 bool WasmTranslation::TranslateWasmScriptLocationToProtocolLocation( 284 bool WasmTranslation::TranslateWasmScriptLocationToProtocolLocation(
266 String16 *script_id, int *line_number, int *column_number) { 285 String16 *script_id, int *line_number, int *column_number) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 *column_number = trans_loc.column; 319 *column_number = trans_loc.column;
301 320
302 return true; 321 return true;
303 } 322 }
304 323
305 void WasmTranslation::AddFakeScript(const String16 &scriptId, 324 void WasmTranslation::AddFakeScript(const String16 &scriptId,
306 TranslatorImpl *translator) { 325 TranslatorImpl *translator) {
307 DCHECK_EQ(0, fake_scripts_.count(scriptId)); 326 DCHECK_EQ(0, fake_scripts_.count(scriptId));
308 fake_scripts_.insert(std::make_pair(scriptId, translator)); 327 fake_scripts_.insert(std::make_pair(scriptId, translator));
309 } 328 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698