| OLD | NEW |
| 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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 class WasmTranslation::TranslatorImpl::RawTranslator | 66 class WasmTranslation::TranslatorImpl::RawTranslator |
| 67 : public WasmTranslation::TranslatorImpl { | 67 : public WasmTranslation::TranslatorImpl { |
| 68 public: | 68 public: |
| 69 void Translate(TransLocation *loc) {} | 69 void Translate(TransLocation *loc) {} |
| 70 void TranslateBack(TransLocation *loc) {} | 70 void TranslateBack(TransLocation *loc) {} |
| 71 }; | 71 }; |
| 72 | 72 |
| 73 class WasmTranslation::TranslatorImpl::DisassemblingTranslator | 73 class WasmTranslation::TranslatorImpl::DisassemblingTranslator |
| 74 : public WasmTranslation::TranslatorImpl { | 74 : public WasmTranslation::TranslatorImpl { |
| 75 using OffsetTable = std::vector<std::tuple<uint32_t, int, int>>; | 75 using OffsetTable = debug::WasmDisassembly::OffsetTable; |
| 76 | 76 |
| 77 public: | 77 public: |
| 78 DisassemblingTranslator(Isolate *isolate, Local<Object> script) | 78 DisassemblingTranslator(Isolate *isolate, Local<Object> script) |
| 79 : script_(isolate, script) {} | 79 : script_(isolate, script) {} |
| 80 | 80 |
| 81 void Translate(TransLocation *loc) { | 81 void Translate(TransLocation *loc) { |
| 82 const OffsetTable &offset_table = GetOffsetTable(loc); | 82 const OffsetTable &offset_table = GetOffsetTable(loc); |
| 83 DCHECK(!offset_table.empty()); | 83 DCHECK(!offset_table.empty()); |
| 84 uint32_t byte_offset = static_cast<uint32_t>(loc->column); | 84 uint32_t byte_offset = static_cast<uint32_t>(loc->column); |
| 85 | 85 |
| 86 // Binary search for the given offset. | 86 // Binary search for the given offset. |
| 87 unsigned left = 0; // inclusive | 87 unsigned left = 0; // inclusive |
| 88 unsigned right = static_cast<unsigned>(offset_table.size()); // exclusive | 88 unsigned right = static_cast<unsigned>(offset_table.size()); // exclusive |
| 89 while (right - left > 1) { | 89 while (right - left > 1) { |
| 90 unsigned mid = (left + right) / 2; | 90 unsigned mid = (left + right) / 2; |
| 91 if (std::get<0>(offset_table[mid]) <= byte_offset) { | 91 if (offset_table[mid].byte_offset <= byte_offset) { |
| 92 left = mid; | 92 left = mid; |
| 93 } else { | 93 } else { |
| 94 right = mid; | 94 right = mid; |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 loc->script_id = GetFakeScriptId(loc); | 98 loc->script_id = GetFakeScriptId(loc); |
| 99 if (std::get<0>(offset_table[left]) == byte_offset) { | 99 if (offset_table[left].byte_offset == byte_offset) { |
| 100 loc->line = std::get<1>(offset_table[left]); | 100 loc->line = offset_table[left].line; |
| 101 loc->column = std::get<2>(offset_table[left]); | 101 loc->column = offset_table[left].column; |
| 102 } else { | 102 } else { |
| 103 loc->line = 0; | 103 loc->line = 0; |
| 104 loc->column = 0; | 104 loc->column = 0; |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 void TranslateBack(TransLocation *loc) { | 108 void TranslateBack(TransLocation *loc) { |
| 109 int func_index = GetFunctionIndexFromFakeScriptId(loc->script_id); | 109 int func_index = GetFunctionIndexFromFakeScriptId(loc->script_id); |
| 110 const OffsetTable *reverse_table = GetReverseTable(func_index); | 110 const OffsetTable *reverse_table = GetReverseTable(func_index); |
| 111 if (!reverse_table) return; | 111 if (!reverse_table) return; |
| 112 DCHECK(!reverse_table->empty()); | 112 DCHECK(!reverse_table->empty()); |
| 113 | 113 |
| 114 // Binary search for the given line and column. | 114 // Binary search for the given line and column. |
| 115 unsigned left = 0; // inclusive | 115 unsigned left = 0; // inclusive |
| 116 unsigned right = static_cast<unsigned>(reverse_table->size()); // exclusive | 116 unsigned right = static_cast<unsigned>(reverse_table->size()); // exclusive |
| 117 while (right - left > 1) { | 117 while (right - left > 1) { |
| 118 unsigned mid = (left + right) / 2; | 118 unsigned mid = (left + right) / 2; |
| 119 auto &entry = (*reverse_table)[mid]; | 119 auto &entry = (*reverse_table)[mid]; |
| 120 if (std::get<1>(entry) < loc->line || | 120 if (entry.line < loc->line || |
| 121 (std::get<1>(entry) == loc->line && | 121 (entry.line == loc->line && entry.column <= loc->column)) { |
| 122 std::get<2>(entry) <= loc->column)) { | |
| 123 left = mid; | 122 left = mid; |
| 124 } else { | 123 } else { |
| 125 right = mid; | 124 right = mid; |
| 126 } | 125 } |
| 127 } | 126 } |
| 128 | 127 |
| 129 int found_byte_offset = 0; | 128 int found_byte_offset = 0; |
| 130 // 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 |
| 131 // 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. |
| 132 if (std::get<1>((*reverse_table)[left]) == loc->line && | 131 if ((*reverse_table)[left].line == loc->line && |
| 133 std::get<2>((*reverse_table)[left]) == loc->column) { | 132 (*reverse_table)[left].column == loc->column) { |
| 134 found_byte_offset = std::get<0>((*reverse_table)[left]); | 133 found_byte_offset = (*reverse_table)[left].byte_offset; |
| 135 } else if (left + 1 < reverse_table->size() && | 134 } else if (left + 1 < reverse_table->size() && |
| 136 std::get<1>((*reverse_table)[left + 1]) == loc->line) { | 135 (*reverse_table)[left + 1].line == loc->line) { |
| 137 found_byte_offset = std::get<0>((*reverse_table)[left + 1]); | 136 found_byte_offset = (*reverse_table)[left + 1].byte_offset; |
| 138 } | 137 } |
| 139 | 138 |
| 140 v8::Isolate *isolate = loc->translation->isolate_; | 139 v8::Isolate *isolate = loc->translation->isolate_; |
| 141 loc->script_id = | 140 loc->script_id = |
| 142 String16::fromInteger(GetScriptId(isolate, script_.Get(isolate))); | 141 String16::fromInteger(GetScriptId(isolate, script_.Get(isolate))); |
| 143 loc->line = func_index; | 142 loc->line = func_index; |
| 144 loc->column = found_byte_offset; | 143 loc->column = found_byte_offset; |
| 145 } | 144 } |
| 146 | 145 |
| 147 private: | 146 private: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 165 DCHECK(ok); | 164 DCHECK(ok); |
| 166 return func_index; | 165 return func_index; |
| 167 } | 166 } |
| 168 | 167 |
| 169 const OffsetTable &GetOffsetTable(const TransLocation *loc) { | 168 const OffsetTable &GetOffsetTable(const TransLocation *loc) { |
| 170 int func_index = loc->line; | 169 int func_index = loc->line; |
| 171 auto it = offset_tables_.find(func_index); | 170 auto it = offset_tables_.find(func_index); |
| 172 if (it != offset_tables_.end()) return it->second; | 171 if (it != offset_tables_.end()) return it->second; |
| 173 | 172 |
| 174 v8::Isolate *isolate = loc->translation->isolate_; | 173 v8::Isolate *isolate = loc->translation->isolate_; |
| 175 std::pair<std::string, OffsetTable> disassembly = | 174 debug::WasmDisassembly disassembly_result = |
| 176 DebugInterface::DisassembleWasmFunction(isolate, script_.Get(isolate), | 175 DebugInterface::DisassembleWasmFunction(isolate, script_.Get(isolate), |
| 177 func_index); | 176 func_index); |
| 178 | 177 |
| 179 it = offset_tables_ | 178 it = offset_tables_ |
| 180 .insert(std::make_pair(func_index, std::move(disassembly.second))) | 179 .insert(std::make_pair(func_index, |
| 180 std::move(disassembly_result.offset_table))) |
| 181 .first; | 181 .first; |
| 182 | 182 |
| 183 String16 fake_script_id = GetFakeScriptId(loc); | 183 String16 fake_script_id = GetFakeScriptId(loc); |
| 184 String16 fake_script_url = GetFakeScriptUrl(loc); | 184 String16 fake_script_url = GetFakeScriptUrl(loc); |
| 185 String16 source(disassembly.first.data(), disassembly.first.length()); | 185 String16 source(disassembly_result.disassembly.data(), |
| 186 disassembly_result.disassembly.length()); |
| 186 std::unique_ptr<V8DebuggerScript> fake_script(new V8DebuggerScript( | 187 std::unique_ptr<V8DebuggerScript> fake_script(new V8DebuggerScript( |
| 187 fake_script_id, std::move(fake_script_url), source)); | 188 fake_script_id, std::move(fake_script_url), source)); |
| 188 | 189 |
| 189 loc->translation->AddFakeScript(std::move(fake_script), this, | 190 loc->translation->AddFakeScript(std::move(fake_script), this, |
| 190 loc->context_group_id); | 191 loc->context_group_id); |
| 191 | 192 |
| 192 return it->second; | 193 return it->second; |
| 193 } | 194 } |
| 194 | 195 |
| 195 const OffsetTable *GetReverseTable(int func_index) { | 196 const OffsetTable *GetReverseTable(int func_index) { |
| 196 auto it = reverse_tables_.find(func_index); | 197 auto it = reverse_tables_.find(func_index); |
| 197 if (it != reverse_tables_.end()) return &it->second; | 198 if (it != reverse_tables_.end()) return &it->second; |
| 198 | 199 |
| 199 // Find offset table, copy and sort it to get reverse table. | 200 // Find offset table, copy and sort it to get reverse table. |
| 200 it = offset_tables_.find(func_index); | 201 it = offset_tables_.find(func_index); |
| 201 if (it == offset_tables_.end()) return nullptr; | 202 if (it == offset_tables_.end()) return nullptr; |
| 202 | 203 |
| 203 OffsetTable reverse_table = it->second; | 204 OffsetTable reverse_table = it->second; |
| 204 // Order by line, column, then byte offset. | 205 // Order by line, column, then byte offset. |
| 205 auto cmp = [](std::tuple<uint32_t, int, int> el1, | 206 auto cmp = [](OffsetTable::value_type el1, OffsetTable::value_type el2) { |
| 206 std::tuple<uint32_t, int, int> el2) { | 207 if (el1.line != el2.line) return el1.line < el2.line; |
| 207 if (std::get<1>(el1) != std::get<1>(el2)) | 208 if (el1.column != el2.column) return el1.column < el2.column; |
| 208 return std::get<1>(el1) < std::get<1>(el2); | 209 return el1.byte_offset < el2.byte_offset; |
| 209 if (std::get<2>(el1) != std::get<2>(el2)) | |
| 210 return std::get<2>(el1) < std::get<2>(el2); | |
| 211 return std::get<0>(el1) < std::get<0>(el2); | |
| 212 }; | 210 }; |
| 213 std::sort(reverse_table.begin(), reverse_table.end(), cmp); | 211 std::sort(reverse_table.begin(), reverse_table.end(), cmp); |
| 214 | 212 |
| 215 auto inserted = reverse_tables_.insert( | 213 auto inserted = reverse_tables_.insert( |
| 216 std::make_pair(func_index, std::move(reverse_table))); | 214 std::make_pair(func_index, std::move(reverse_table))); |
| 217 DCHECK(inserted.second); | 215 DCHECK(inserted.second); |
| 218 return &inserted.first->second; | 216 return &inserted.first->second; |
| 219 } | 217 } |
| 220 | 218 |
| 221 Global<Object> script_; | 219 Global<Object> script_; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 int context_group_id) { | 299 int context_group_id) { |
| 302 bool inserted = | 300 bool inserted = |
| 303 fake_scripts_.insert(std::make_pair(fake_script->scriptId(), translator)) | 301 fake_scripts_.insert(std::make_pair(fake_script->scriptId(), translator)) |
| 304 .second; | 302 .second; |
| 305 DCHECK(inserted); | 303 DCHECK(inserted); |
| 306 USE(inserted); | 304 USE(inserted); |
| 307 V8DebuggerAgentImpl *agent = | 305 V8DebuggerAgentImpl *agent = |
| 308 debugger_->inspector()->enabledDebuggerAgentForGroup(context_group_id); | 306 debugger_->inspector()->enabledDebuggerAgentForGroup(context_group_id); |
| 309 agent->didParseSource(std::move(fake_script), true); | 307 agent->didParseSource(std::move(fake_script), true); |
| 310 } | 308 } |
| OLD | NEW |