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/assembler-inl.h" | 5 #include "src/assembler-inl.h" |
6 #include "src/assert-scope.h" | 6 #include "src/assert-scope.h" |
7 #include "src/compiler/wasm-compiler.h" | 7 #include "src/compiler/wasm-compiler.h" |
8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/frames-inl.h" | 10 #include "src/frames-inl.h" |
11 #include "src/isolate.h" | 11 #include "src/isolate.h" |
12 #include "src/wasm/module-decoder.h" | 12 #include "src/wasm/module-decoder.h" |
13 #include "src/wasm/wasm-interpreter.h" | 13 #include "src/wasm/wasm-interpreter.h" |
14 #include "src/wasm/wasm-limits.h" | 14 #include "src/wasm/wasm-limits.h" |
15 #include "src/wasm/wasm-module.h" | 15 #include "src/wasm/wasm-module.h" |
16 #include "src/wasm/wasm-objects.h" | 16 #include "src/wasm/wasm-objects.h" |
17 #include "src/zone/accounting-allocator.h" | 17 #include "src/zone/accounting-allocator.h" |
18 | 18 |
19 using namespace v8::internal; | 19 using namespace v8::internal; |
20 using namespace v8::internal::wasm; | 20 using namespace v8::internal::wasm; |
21 | 21 |
22 namespace { | 22 namespace { |
23 | 23 |
24 class InterpreterHandle { | 24 class InterpreterHandle { |
25 AccountingAllocator allocator_; | 25 AccountingAllocator allocator_; |
26 WasmInstance instance_; | 26 WasmInstance instance_; |
27 WasmInterpreter interpreter_; | 27 WasmInterpreter interpreter_; |
| 28 Isolate *isolate_; |
28 | 29 |
29 public: | 30 public: |
30 // Initialize in the right order, using helper methods to make this possible. | 31 // Initialize in the right order, using helper methods to make this possible. |
31 // WasmInterpreter has to be allocated in place, since it is not movable. | 32 // WasmInterpreter has to be allocated in place, since it is not movable. |
32 InterpreterHandle(Isolate *isolate, WasmDebugInfo *debug_info) | 33 InterpreterHandle(Isolate *isolate, WasmDebugInfo *debug_info) |
33 : instance_(debug_info->wasm_instance()->compiled_module()->module()), | 34 : instance_(debug_info->wasm_instance()->compiled_module()->module()), |
34 interpreter_(GetBytesEnv(&instance_, debug_info), &allocator_) { | 35 interpreter_(GetBytesEnv(&instance_, debug_info), &allocator_), |
| 36 isolate_(isolate) { |
35 Handle<JSArrayBuffer> mem_buffer = | 37 Handle<JSArrayBuffer> mem_buffer = |
36 handle(debug_info->wasm_instance()->memory_buffer(), isolate); | 38 handle(debug_info->wasm_instance()->memory_buffer(), isolate); |
37 if (mem_buffer->IsUndefined(isolate)) { | 39 if (mem_buffer->IsUndefined(isolate)) { |
38 DCHECK_EQ(0, instance_.module->min_mem_pages); | 40 DCHECK_EQ(0, instance_.module->min_mem_pages); |
39 instance_.mem_start = nullptr; | 41 instance_.mem_start = nullptr; |
40 instance_.mem_size = 0; | 42 instance_.mem_size = 0; |
41 } else { | 43 } else { |
42 instance_.mem_start = | 44 instance_.mem_start = |
43 reinterpret_cast<byte *>(mem_buffer->backing_store()); | 45 reinterpret_cast<byte *>(mem_buffer->backing_store()); |
44 CHECK(mem_buffer->byte_length()->ToUint32(&instance_.mem_size)); | 46 CHECK(mem_buffer->byte_length()->ToUint32(&instance_.mem_size)); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 DCHECK(thread->state() == WasmInterpreter::STOPPED || | 92 DCHECK(thread->state() == WasmInterpreter::STOPPED || |
91 thread->state() == WasmInterpreter::FINISHED); | 93 thread->state() == WasmInterpreter::FINISHED); |
92 thread->Reset(); | 94 thread->Reset(); |
93 thread->PushFrame(&module()->functions[func_index], wasm_args.start()); | 95 thread->PushFrame(&module()->functions[func_index], wasm_args.start()); |
94 WasmInterpreter::State state; | 96 WasmInterpreter::State state; |
95 do { | 97 do { |
96 state = thread->Run(); | 98 state = thread->Run(); |
97 switch (state) { | 99 switch (state) { |
98 case WasmInterpreter::State::PAUSED: { | 100 case WasmInterpreter::State::PAUSED: { |
99 // We hit a breakpoint. | 101 // We hit a breakpoint. |
100 // TODO(clemensh): Handle this. | 102 StackTraceFrameIterator frame_it(isolate_); |
| 103 isolate_->debug()->Break(frame_it.frame()); |
101 } break; | 104 } break; |
102 case WasmInterpreter::State::FINISHED: | 105 case WasmInterpreter::State::FINISHED: |
103 // Perfect, just break the switch and exit the loop. | 106 // Perfect, just break the switch and exit the loop. |
104 break; | 107 break; |
105 case WasmInterpreter::State::TRAPPED: | 108 case WasmInterpreter::State::TRAPPED: |
106 // TODO(clemensh): Generate appropriate JS exception. | 109 // TODO(clemensh): Generate appropriate JS exception. |
107 UNIMPLEMENTED(); | 110 UNIMPLEMENTED(); |
108 break; | 111 break; |
109 // STOPPED and RUNNING should never occur here. | 112 // STOPPED and RUNNING should never occur here. |
110 case WasmInterpreter::State::STOPPED: | 113 case WasmInterpreter::State::STOPPED: |
(...skipping 18 matching lines...) Expand all Loading... |
129 CASE_RET_TYPE(kWasmI32, uint32_t) | 132 CASE_RET_TYPE(kWasmI32, uint32_t) |
130 CASE_RET_TYPE(kWasmI64, uint64_t) | 133 CASE_RET_TYPE(kWasmI64, uint64_t) |
131 CASE_RET_TYPE(kWasmF32, float) | 134 CASE_RET_TYPE(kWasmF32, float) |
132 CASE_RET_TYPE(kWasmF64, double) | 135 CASE_RET_TYPE(kWasmF64, double) |
133 #undef CASE_RET_TYPE | 136 #undef CASE_RET_TYPE |
134 default: | 137 default: |
135 UNREACHABLE(); | 138 UNREACHABLE(); |
136 } | 139 } |
137 } | 140 } |
138 } | 141 } |
| 142 |
| 143 std::vector<std::pair<uint32_t, int>> GetInterpretedStack( |
| 144 Address frame_pointer) { |
| 145 // TODO(clemensh): Use frame_pointer. |
| 146 USE(frame_pointer); |
| 147 |
| 148 DCHECK_EQ(1, interpreter()->GetThreadCount()); |
| 149 WasmInterpreter::Thread *thread = interpreter()->GetThread(0); |
| 150 std::vector<std::pair<uint32_t, int>> stack; |
| 151 for (int i = thread->GetFrameCount() - 1; i >= 0; --i) { |
| 152 wasm::InterpretedFrame frame = thread->GetFrame(0); |
| 153 stack.push_back({frame.function()->func_index, frame.pc()}); |
| 154 } |
| 155 return stack; |
| 156 } |
| 157 |
| 158 wasm::InterpretedFrame GetInterpretedFrame(Address frame_pointer, int idx) { |
| 159 // TODO(clemensh): Use frame_pointer. |
| 160 USE(frame_pointer); |
| 161 |
| 162 DCHECK_EQ(1, interpreter()->GetThreadCount()); |
| 163 WasmInterpreter::Thread *thread = interpreter()->GetThread(0); |
| 164 return thread->GetMutableFrame(idx); |
| 165 } |
139 }; | 166 }; |
140 | 167 |
141 InterpreterHandle *GetOrCreateInterpreterHandle( | 168 InterpreterHandle *GetOrCreateInterpreterHandle( |
142 Isolate *isolate, Handle<WasmDebugInfo> debug_info) { | 169 Isolate *isolate, Handle<WasmDebugInfo> debug_info) { |
143 Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandle), | 170 Handle<Object> handle(debug_info->get(WasmDebugInfo::kInterpreterHandle), |
144 isolate); | 171 isolate); |
145 if (handle->IsUndefined(isolate)) { | 172 if (handle->IsUndefined(isolate)) { |
146 InterpreterHandle *cpp_handle = new InterpreterHandle(isolate, *debug_info); | 173 InterpreterHandle *cpp_handle = new InterpreterHandle(isolate, *debug_info); |
147 handle = Managed<InterpreterHandle>::New(isolate, cpp_handle); | 174 handle = Managed<InterpreterHandle>::New(isolate, cpp_handle); |
148 debug_info->set(WasmDebugInfo::kInterpreterHandle, *handle); | 175 debug_info->set(WasmDebugInfo::kInterpreterHandle, *handle); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 EnsureRedirectToInterpreter(isolate, debug_info, func_index); | 292 EnsureRedirectToInterpreter(isolate, debug_info, func_index); |
266 } | 293 } |
267 | 294 |
268 void WasmDebugInfo::RunInterpreter(Handle<WasmDebugInfo> debug_info, | 295 void WasmDebugInfo::RunInterpreter(Handle<WasmDebugInfo> debug_info, |
269 int func_index, uint8_t *arg_buffer) { | 296 int func_index, uint8_t *arg_buffer) { |
270 DCHECK_LE(0, func_index); | 297 DCHECK_LE(0, func_index); |
271 InterpreterHandle *interp_handle = | 298 InterpreterHandle *interp_handle = |
272 GetOrCreateInterpreterHandle(debug_info->GetIsolate(), debug_info); | 299 GetOrCreateInterpreterHandle(debug_info->GetIsolate(), debug_info); |
273 interp_handle->Execute(static_cast<uint32_t>(func_index), arg_buffer); | 300 interp_handle->Execute(static_cast<uint32_t>(func_index), arg_buffer); |
274 } | 301 } |
| 302 |
| 303 std::vector<std::pair<uint32_t, int>> WasmDebugInfo::GetInterpretedStack( |
| 304 Handle<WasmDebugInfo> debug_info, Address frame_pointer) { |
| 305 InterpreterHandle *interp_handle = |
| 306 GetOrCreateInterpreterHandle(debug_info->GetIsolate(), debug_info); |
| 307 return interp_handle->GetInterpretedStack(frame_pointer); |
| 308 } |
| 309 |
| 310 std::unique_ptr<wasm::InterpretedFrame> WasmDebugInfo::GetInterpretedFrame( |
| 311 Handle<WasmDebugInfo> debug_info, Address frame_pointer, int idx) { |
| 312 InterpreterHandle *interp_handle = |
| 313 GetOrCreateInterpreterHandle(debug_info->GetIsolate(), debug_info); |
| 314 return std::unique_ptr<wasm::InterpretedFrame>(new wasm::InterpretedFrame( |
| 315 interp_handle->GetInterpretedFrame(frame_pointer, idx))); |
| 316 } |
OLD | NEW |