Showing the changes to src/vm/thread.cpp (1 of 8 files). Show all
Unified · Split
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <exceptions.h> | 12 | #include <exceptions.h> |
| 13 | #include <vm_memory.h> | 13 | #include <vm_memory.h> |
| 14 | #include <debug.h> | 14 | #include <debug.h> |
| 15 | #include <utils.h> | ||
| 15 | #include "execution_table.h" | 16 | #include "execution_table.h" |
| 16 | #include "tool_dispatch.h" | 17 | #include "tool_dispatch.h" |
| 17 | 18 | ||
| @@ -51,10 +52,11 @@ namespace · 33 unmodified lines | |||
| 51 | } | 52 | } |
| 52 | 53 | ||
| 53 | vm_registers_t::vm_registers_t( | 54 | vm_registers_t::vm_registers_t( |
| 54 | const vm_thread_t &thread, | 55 | vm_thread_t &thread, |
| 55 | vm_module_ref_t &entry) | 56 | vm_module_ref_t &entry) |
| 56 | : current_thread_state{ vm_thread_state_t::ready } | 57 | : current_thread_state{ vm_thread_state_t::ready } |
| 57 | , current_thread_quanta{ 0 } | 58 | , current_thread_quanta{ 0 } |
| 59 | , trap_flags{ vm_trap_flags_t::none } | ||
| 58 | , module_ref{ &entry } | 60 | , module_ref{ &entry } |
| 59 | , mp_base{ entry.mp_base } | 61 | , mp_base{ entry.mp_base } |
| 60 | , thread{ thread } | 62 | , thread{ thread } |
| @@ -174,25 +176,37 @@ namespace · 113 unmodified lines | |||
| 174 | { | 176 | { |
| 175 | struct execute_with_tool_t final | 177 | struct execute_with_tool_t final |
| 176 | { | 178 | { |
| 177 | static void begin_exec_loop(vm_registers_t ®isters, vm_t &) | 179 | static void begin_exec_loop(vm_registers_t &r, vm_t &) |
| 178 | { | 180 | { |
| 179 | auto tool_dispatch = registers.tool_dispatch.load(); | 181 | auto tool_dispatch = r.tool_dispatch.load(); |
| 180 | assert(tool_dispatch != nullptr); | 182 | assert(tool_dispatch != nullptr); |
| 181 | 183 | ||
| 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); | ||
| 183 | } | 197 | } |
| 184 | }; | 198 | }; |
| 185 | 199 | ||
| 186 | struct execute_normal_t final | 200 | struct execute_normal_t final |
| 187 | { | 201 | { |
| 188 | static void begin_exec_loop(vm_registers_t &, vm_t &) { } | 202 | static void begin_exec_loop(vm_registers_t &, vm_t &) { } |
| 203 | static void after_exec(vm_registers_t &, vm_t &) { } | ||
| 189 | }; | 204 | }; |
| 190 | 205 | ||
| 191 | template<typename EXEC_DETOUR> | 206 | template<typename EXEC_DETOUR> |
| 192 | void execute_impl(vm_registers_t &r, vm_t &vm) | 207 | void execute_impl(vm_registers_t &r, vm_t &vm) |
| 193 | { | 208 | { |
| 194 | auto &execution_duration = r.current_thread_quanta; | 209 | for (; 0 != r.current_thread_quanta; --r.current_thread_quanta) |
| 195 | for (; 0 != execution_duration; --execution_duration) | ||
| 196 | { | 210 | { |
| 197 | EXEC_DETOUR::begin_exec_loop(r, vm); | 211 | EXEC_DETOUR::begin_exec_loop(r, vm); |
| 198 | assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack"); | 212 | assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack"); |
| @@ -212,6 +226,8 @@ namespace · 13 unmodified lines | |||
| 212 | vm_exec_table[opcode](r, vm); | 226 | vm_exec_table[opcode](r, vm); |
| 213 | r.pc = r.next_pc; | 227 | r.pc = r.next_pc; |
| 214 | 228 | ||
| 229 | EXEC_DETOUR::after_exec(r, vm); | ||
| 230 | |||
| 215 | if (r.current_thread_state != vm_thread_state_t::running) | 231 | if (r.current_thread_state != vm_thread_state_t::running) |
| 216 | break; | 232 | break; |
| 217 | } | 233 | } |
| @@ -306,11 +322,6 @@ void vm_thread_t::set_tool_dispatch(vm_tool_dispatch_t *dispatch) · 88 unmodified lines | |||
| 306 | _registers.tool_dispatch = dispatch; | 322 | _registers.tool_dispatch = dispatch; |
| 307 | } | 323 | } |
| 308 | 324 | ||
| 309 | vm_thread_state_t vm_thread_t::get_state() const | ||
| 310 | { | ||
| 311 | return _registers.current_thread_state; | ||
| 312 | } | ||
| 313 | |||
| 314 | const char *vm_thread_t::get_error_message() const | 325 | const char *vm_thread_t::get_error_message() const |
| 315 | { | 326 | { |
| 316 | return _error_message; | 327 | return _error_message; |
| @@ -329,4 +340,4 @@ uint32_t vm_thread_t::get_parent_thread_id() const · 12 unmodified lines | |||
| 329 | const vm_registers_t& vm_thread_t::get_registers() const | 340 | const vm_registers_t& vm_thread_t::get_registers() const |
| 330 | { | 341 | { |
| 331 | return _registers; | 342 | return _registers; |
| 332 | } | 343 | } |