History

Update registers struct to include next_pc member. This allows the pc member to always point at the current PC instead of having been incremented to the 'next' PC.

arr committed 9 years ago

Commit a46f30c1 parent 87f2d5b6 files · +67 −68Browse files

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

Unified · Split

src/vm/thread.cpp+18−17
@@ -59,6 +59,7 @@ vm_registers_t::vm_registers_t( · 58 unmodified lines
5959 , mp_base{ entry.mp_base }
6060 , thread{ thread }
6161 , pc{ entry.module->header.entry_pc }
62+ , next_pc { entry.module->header.entry_pc }
6263 , stack{ static_cast<std::size_t>(entry.module->header.stack_extent) }
6364 , tool_dispatch{ nullptr }
6465 , src{ nullptr }
@@ -171,9 +172,9 @@ vm_thread_t::~vm_thread_t() · 106 unmodified lines
171172
172173 namespace
173174 {
174− struct execute_with_tool_t
175+ struct execute_with_tool_t final
175176 {
176− void begin_exec_loop(vm_registers_t &registers, vm_t &)
177+ static void begin_exec_loop(vm_registers_t &registers, vm_t &)
177178 {
178179 auto tool_dispatch = registers.tool_dispatch.load();
179180 assert(tool_dispatch != nullptr);
@@ -182,36 +183,36 @@ namespace · 2 unmodified lines
182183 }
183184 };
184185
185− struct execute_normal_t
186+ struct execute_normal_t final
186187 {
187− void begin_exec_loop(vm_registers_t &, vm_t &) { }
188+ static void begin_exec_loop(vm_registers_t &, vm_t &) { }
188189 };
189190
190191 template<typename EXEC_DETOUR>
191− void execute_impl(vm_registers_t &registers, vm_t &vm)
192+ void execute_impl(vm_registers_t &r, vm_t &vm)
192193 {
193− EXEC_DETOUR detour{};
194− auto &execution_duration = registers.current_thread_quanta;
194+ auto &execution_duration = r.current_thread_quanta;
195195 for (; 0 != execution_duration; --execution_duration)
196196 {
197− detour.begin_exec_loop(registers, vm);
198− assert(registers.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");
197+ EXEC_DETOUR::begin_exec_loop(r, vm);
198+ assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");
199199
200− const auto &code_section = registers.module_ref->code_section;
201− assert(static_cast<std::size_t>(registers.pc) < code_section.size());
200+ const auto &code_section = r.module_ref->code_section;
201+ assert(static_cast<std::size_t>(r.pc) < code_section.size());
202202
203− assert(!registers.module_ref->is_builtin_module() && "Interpreter thread is unable to execute native instructions");
204− const auto &inst = code_section[registers.pc].op;
203+ assert(!r.module_ref->is_builtin_module() && "Interpreter thread is unable to execute native instructions");
204+ const auto &inst = code_section[r.pc].op;
205205 const auto opcode = static_cast<std::size_t>(inst.opcode);
206206 if (static_cast<std::size_t>(opcode_t::last_opcode) < opcode)
207207 throw vm_system_exception{ "Unknown op-code" };
208208
209209 // Instruction is valid, decode and update registers for operation
210− decode_address(inst, registers);
211− registers.pc++;
212− vm_exec_table[opcode](registers, vm);
210+ decode_address(inst, r);
211+ r.next_pc = (r.pc + 1);
212+ vm_exec_table[opcode](r, vm);
213+ r.pc = r.next_pc;
213214
214− if (registers.current_thread_state != vm_thread_state_t::running)
215+ if (r.current_thread_state != vm_thread_state_t::running)
215216 break;
216217 }
217218 }