History

Add support for traps in VM Add instruction trap to enable single step scenario in debugger Remote get_state() function from thread

arr committed 9 years ago

Commit cb408a11 parent eb570d98 files · +120 −40Browse files

Showing the changes to src/vm/thread.cpp (1 of 8 files). Show all

Unified · Split

src/vm/thread.cpp+23−12
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <exceptions.h>
1313 #include <vm_memory.h>
1414 #include <debug.h>
15+#include <utils.h>
1516 #include "execution_table.h"
1617 #include "tool_dispatch.h"
1718
@@ -51,10 +52,11 @@ namespace · 33 unmodified lines
5152 }
5253
5354 vm_registers_t::vm_registers_t(
54− const vm_thread_t &thread,
55+ vm_thread_t &thread,
5556 vm_module_ref_t &entry)
5657 : current_thread_state{ vm_thread_state_t::ready }
5758 , current_thread_quanta{ 0 }
59+ , trap_flags{ vm_trap_flags_t::none }
5860 , module_ref{ &entry }
5961 , mp_base{ entry.mp_base }
6062 , thread{ thread }
@@ -174,25 +176,37 @@ namespace · 113 unmodified lines
174176 {
175177 struct execute_with_tool_t final
176178 {
177− static void begin_exec_loop(vm_registers_t &registers, vm_t &)
179+ static void begin_exec_loop(vm_registers_t &r, vm_t &)
178180 {
179− auto tool_dispatch = registers.tool_dispatch.load();
181+ auto tool_dispatch = r.tool_dispatch.load();
180182 assert(tool_dispatch != nullptr);
181183
182− tool_dispatch->block_if_thread_suspended(registers.thread.get_thread_id());
184+ tool_dispatch->block_if_thread_suspended(r.thread.get_thread_id());
185+ }
186+
187+ static void after_exec(vm_registers_t &r, vm_t &)
188+ {
189+ if (r.trap_flags == vm_trap_flags_t::none
190+ || !util::has_flag(r.trap_flags, vm_trap_flags_t::instruction))
191+ return;
192+
193+ auto tool_dispatch = r.tool_dispatch.load();
194+ assert(tool_dispatch != nullptr);
195+
196+ tool_dispatch->on_trap(r, vm_trap_flags_t::instruction);
183197 }
184198 };
185199
186200 struct execute_normal_t final
187201 {
188202 static void begin_exec_loop(vm_registers_t &, vm_t &) { }
203+ static void after_exec(vm_registers_t &, vm_t &) { }
189204 };
190205
191206 template<typename EXEC_DETOUR>
192207 void execute_impl(vm_registers_t &r, vm_t &vm)
193208 {
194− auto &execution_duration = r.current_thread_quanta;
195− for (; 0 != execution_duration; --execution_duration)
209+ for (; 0 != r.current_thread_quanta; --r.current_thread_quanta)
196210 {
197211 EXEC_DETOUR::begin_exec_loop(r, vm);
198212 assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");
@@ -212,6 +226,8 @@ namespace · 13 unmodified lines
212226 vm_exec_table[opcode](r, vm);
213227 r.pc = r.next_pc;
214228
229+ EXEC_DETOUR::after_exec(r, vm);
230+
215231 if (r.current_thread_state != vm_thread_state_t::running)
216232 break;
217233 }
@@ -306,11 +322,6 @@ void vm_thread_t::set_tool_dispatch(vm_tool_dispatch_t *dispatch) · 88 unmodified lines
306322 _registers.tool_dispatch = dispatch;
307323 }
308324
309−vm_thread_state_t vm_thread_t::get_state() const
310−{
311− return _registers.current_thread_state;
312−}
313−
314325 const char *vm_thread_t::get_error_message() const
315326 {
316327 return _error_message;
@@ -329,4 +340,4 @@ uint32_t vm_thread_t::get_parent_thread_id() const · 12 unmodified lines
329340 const vm_registers_t& vm_thread_t::get_registers() const
330341 {
331342 return _registers;
332−}
343+}