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

Unified · Split

6 files
  1. src/exec/debugger.cpp +1 −2
  2. src/include/exceptions.h +1 −1
  3. src/include/runtime.h +2 −1
  4. src/vm/execution_table.cpp +44 −45
  5. src/vm/thread.cpp +18 −17
  6. src/vm/tool_dispatch.cpp +1 −2
src/exec/debugger.cpp+1−2
@@ -630,8 +630,7 @@ namespace · 629 unmodified lines
630 const auto &r = *cxt.current_register;630 const auto &r = *cxt.current_register;
631 const auto &code_section = r.module_ref->code_section;631 const auto &code_section = r.module_ref->code_section;
632 632
633 // The current PC is actually the next PC to execute.633 auto begin_pc = r.pc;
634 auto begin_pc = r.pc == 0 ? r.pc : r.pc - 1;
635 auto end_pc = begin_pc;634 auto end_pc = begin_pc;
636 if (absolute_pc)635 if (absolute_pc)
637 {636 {
src/include/exceptions.h+1−1
@@ -36,7 +36,7 @@ namespace disvm · 35 unmodified lines
36 { }36 { }
37 };37 };
38 38
39 class vm_syscall_exception : public vm_system_exception39 class vm_syscall_exception final : public vm_system_exception
40 {40 {
41 public:41 public:
42 explicit vm_syscall_exception(disvm::vm_t &vm, const char *message)42 explicit vm_syscall_exception(disvm::vm_t &vm, const char *message)
src/include/runtime.h+2−1
@@ -745,7 +745,8 @@ namespace disvm · 744 unmodified lines
745 const vm_thread_t &thread;745 const vm_thread_t &thread;
746 std::atomic<vm_tool_dispatch_t *> tool_dispatch;746 std::atomic<vm_tool_dispatch_t *> tool_dispatch;
747 vm_stack_t stack; // Frame pointer access (FP)747 vm_stack_t stack; // Frame pointer access (FP)
748 vm_pc_t pc; // Program counter (Index into module code section)748 vm_pc_t pc; // Current Program counter (Index into module code section)
749 vm_pc_t next_pc; // Next Program counter
749 vm_alloc_t *mp_base; // Module data base pointer (MP)750 vm_alloc_t *mp_base; // Module data base pointer (MP)
750 vm_module_ref_t *module_ref; // Module reference751 vm_module_ref_t *module_ref; // Module reference
751 vm_request_mutex_t request_mutex;752 vm_request_mutex_t request_mutex;
src/vm/execution_table.cpp+44−45
@@ -548,33 +548,33 @@ namespace · 547 unmodified lines
548 // Compare and Branch operations548 // Compare and Branch operations
549 //549 //
550 550
551 EXEC_DECL(bltb) { if (vt_ref<byte_t>(r.src) < vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }551 EXEC_DECL(bltb) { if (vt_ref<byte_t>(r.src) < vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
552 EXEC_DECL(bgtb) { if (vt_ref<byte_t>(r.src) > vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }552 EXEC_DECL(bgtb) { if (vt_ref<byte_t>(r.src) > vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
553 EXEC_DECL(bleb) { if (vt_ref<byte_t>(r.src) <= vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }553 EXEC_DECL(bleb) { if (vt_ref<byte_t>(r.src) <= vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
554 EXEC_DECL(bgeb) { if (vt_ref<byte_t>(r.src) >= vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }554 EXEC_DECL(bgeb) { if (vt_ref<byte_t>(r.src) >= vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
555 EXEC_DECL(beqb) { if (vt_ref<byte_t>(r.src) == vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }555 EXEC_DECL(beqb) { if (vt_ref<byte_t>(r.src) == vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
556 EXEC_DECL(bneb) { if (vt_ref<byte_t>(r.src) != vt_ref<byte_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }556 EXEC_DECL(bneb) { if (vt_ref<byte_t>(r.src) != vt_ref<byte_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
557 557
558 EXEC_DECL(bltw) { if (vt_ref<word_t>(r.src) < vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }558 EXEC_DECL(bltw) { if (vt_ref<word_t>(r.src) < vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
559 EXEC_DECL(bgtw) { if (vt_ref<word_t>(r.src) > vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }559 EXEC_DECL(bgtw) { if (vt_ref<word_t>(r.src) > vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
560 EXEC_DECL(blew) { if (vt_ref<word_t>(r.src) <= vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }560 EXEC_DECL(blew) { if (vt_ref<word_t>(r.src) <= vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
561 EXEC_DECL(bgew) { if (vt_ref<word_t>(r.src) >= vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }561 EXEC_DECL(bgew) { if (vt_ref<word_t>(r.src) >= vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
562 EXEC_DECL(beqw) { if (vt_ref<word_t>(r.src) == vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }562 EXEC_DECL(beqw) { if (vt_ref<word_t>(r.src) == vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
563 EXEC_DECL(bnew) { if (vt_ref<word_t>(r.src) != vt_ref<word_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }563 EXEC_DECL(bnew) { if (vt_ref<word_t>(r.src) != vt_ref<word_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
564 564
565 EXEC_DECL(bltf) { if (vt_ref<real_t>(r.src) < vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }565 EXEC_DECL(bltf) { if (vt_ref<real_t>(r.src) < vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
566 EXEC_DECL(bgtf) { if (vt_ref<real_t>(r.src) > vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }566 EXEC_DECL(bgtf) { if (vt_ref<real_t>(r.src) > vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
567 EXEC_DECL(blef) { if (vt_ref<real_t>(r.src) <= vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }567 EXEC_DECL(blef) { if (vt_ref<real_t>(r.src) <= vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
568 EXEC_DECL(bgef) { if (vt_ref<real_t>(r.src) >= vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }568 EXEC_DECL(bgef) { if (vt_ref<real_t>(r.src) >= vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
569 EXEC_DECL(beqf) { if (vt_ref<real_t>(r.src) == vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }569 EXEC_DECL(beqf) { if (vt_ref<real_t>(r.src) == vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
570 EXEC_DECL(bnef) { if (vt_ref<real_t>(r.src) != vt_ref<real_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }570 EXEC_DECL(bnef) { if (vt_ref<real_t>(r.src) != vt_ref<real_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
571 571
572 EXEC_DECL(bltl) { if (vt_ref<big_t>(r.src) < vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }572 EXEC_DECL(bltl) { if (vt_ref<big_t>(r.src) < vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
573 EXEC_DECL(bgtl) { if (vt_ref<big_t>(r.src) > vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }573 EXEC_DECL(bgtl) { if (vt_ref<big_t>(r.src) > vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
574 EXEC_DECL(blel) { if (vt_ref<big_t>(r.src) <= vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }574 EXEC_DECL(blel) { if (vt_ref<big_t>(r.src) <= vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
575 EXEC_DECL(bgel) { if (vt_ref<big_t>(r.src) >= vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }575 EXEC_DECL(bgel) { if (vt_ref<big_t>(r.src) >= vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
576 EXEC_DECL(beql) { if (vt_ref<big_t>(r.src) == vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }576 EXEC_DECL(beql) { if (vt_ref<big_t>(r.src) == vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
577 EXEC_DECL(bnel) { if (vt_ref<big_t>(r.src) != vt_ref<big_t>(r.mid)) r.pc = vt_ref<vm_pc_t>(r.dest); }577 EXEC_DECL(bnel) { if (vt_ref<big_t>(r.src) != vt_ref<big_t>(r.mid)) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
578 578
579 // Define case table constants579 // Define case table constants
580 // [SPEC]Table format is partially defined in Dis VM specification580 // [SPEC]Table format is partially defined in Dis VM specification
@@ -621,7 +621,7 @@ namespace · 40 unmodified lines
621 }621 }
622 622
623 assert(0 <= static_cast<std::size_t>(target_pc) && static_cast<std::size_t>(target_pc) < r.module_ref->code_section.size());623 assert(0 <= static_cast<std::size_t>(target_pc) && static_cast<std::size_t>(target_pc) < r.module_ref->code_section.size());
624 r.pc = static_cast<vm_pc_t>(target_pc);624 r.next_pc = static_cast<vm_pc_t>(target_pc);
625 }625 }
626 626
627 EXEC_DECL(casew) { _case<word_t>(r); }627 EXEC_DECL(casew) { _case<word_t>(r); }
@@ -675,19 +675,19 @@ namespace · 47 unmodified lines
675 }675 }
676 676
677 assert(0 <= static_cast<std::size_t>(target_pc) && static_cast<std::size_t>(target_pc) < r.module_ref->code_section.size());677 assert(0 <= static_cast<std::size_t>(target_pc) && static_cast<std::size_t>(target_pc) < r.module_ref->code_section.size());
678 r.pc = target_pc;678 r.next_pc = target_pc;
679 }679 }
680 680
681 //681 //
682 // String operations682 // String operations
683 //683 //
684 684
685 EXEC_DECL(bltc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) < 0) r.pc = vt_ref<vm_pc_t>(r.dest); }685 EXEC_DECL(bltc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) < 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
686 EXEC_DECL(bgtc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) > 0) r.pc = vt_ref<vm_pc_t>(r.dest); }686 EXEC_DECL(bgtc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) > 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
687 EXEC_DECL(blec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) <= 0) r.pc = vt_ref<vm_pc_t>(r.dest); }687 EXEC_DECL(blec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) <= 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
688 EXEC_DECL(bgec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) >= 0) r.pc = vt_ref<vm_pc_t>(r.dest); }688 EXEC_DECL(bgec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) >= 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
689 EXEC_DECL(beqc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) == 0) r.pc = vt_ref<vm_pc_t>(r.dest); }689 EXEC_DECL(beqc) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) == 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
690 EXEC_DECL(bnec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) != 0) r.pc = vt_ref<vm_pc_t>(r.dest); }690 EXEC_DECL(bnec) { if (vm_string_t::compare(at_val<vm_string_t>(r.src), at_val<vm_string_t>(r.mid)) != 0) r.next_pc = vt_ref<vm_pc_t>(r.dest); }
691 691
692 EXEC_DECL(lenc)692 EXEC_DECL(lenc)
693 {693 {
@@ -1454,7 +1454,7 @@ namespace · 760 unmodified lines
1454 {1454 {
1455 const auto current_top_frame = r.stack.peek_frame();1455 const auto current_top_frame = r.stack.peek_frame();
1456 assert(current_top_frame != nullptr);1456 assert(current_top_frame != nullptr);
1457 r.pc = current_top_frame->prev_pc();1457 r.next_pc = current_top_frame->prev_pc();
1458 1458
1459 if (current_top_frame->prev_module_ref() != nullptr)1459 if (current_top_frame->prev_module_ref() != nullptr)
1460 {1460 {
@@ -1477,7 +1477,7 @@ namespace · 16 unmodified lines
1477 EXEC_DECL(call)1477 EXEC_DECL(call)
1478 {1478 {
1479 auto top_frame = r.stack.push_frame();1479 auto top_frame = r.stack.push_frame();
1480 top_frame->prev_pc() = r.pc;1480 top_frame->prev_pc() = r.next_pc;
1481 1481
1482#ifndef NDEBUG1482#ifndef NDEBUG
1483 // Validate the stack state1483 // Validate the stack state
@@ -1486,7 +1486,7 @@ namespace · 2 unmodified lines
1486 assert(top_frame->base() == frame_base_pointer);1486 assert(top_frame->base() == frame_base_pointer);
1487#endif1487#endif
1488 1488
1489 r.pc = vt_ref<vm_pc_t>(r.dest);1489 r.next_pc = vt_ref<vm_pc_t>(r.dest);
1490 1490
1491 debug::log_msg(debug::component_trace_t::stack, debug::log_level_t::debug, "enter: function");1491 debug::log_msg(debug::component_trace_t::stack, debug::log_level_t::debug, "enter: function");
1492 }1492 }
@@ -1514,7 +1514,7 @@ namespace · 21 unmodified lines
1514#endif1514#endif
1515 1515
1516 // Store current state1516 // Store current state
1517 top_frame->prev_pc() = r.pc;1517 top_frame->prev_pc() = r.next_pc;
1518 top_frame->prev_module_ref() = r.module_ref;1518 top_frame->prev_module_ref() = r.module_ref;
1519 1519
1520 if (debug::is_component_tracing_enabled<debug::component_trace_t::stack>())1520 if (debug::is_component_tracing_enabled<debug::component_trace_t::stack>())
@@ -1533,7 +1533,7 @@ namespace · 12 unmodified lines
1533 r.module_ref = target_module;1533 r.module_ref = target_module;
1534 r.module_ref->add_ref();1534 r.module_ref->add_ref();
1535 r.mp_base = r.module_ref->mp_base;1535 r.mp_base = r.module_ref->mp_base;
1536 r.pc = function_pc;1536 r.next_pc = function_pc;
1537 1537
1538 if (r.module_ref->is_builtin_module())1538 if (r.module_ref->is_builtin_module())
1539 {1539 {
@@ -1554,7 +1554,7 @@ namespace · 14 unmodified lines
1554 }1554 }
1555 }1555 }
1556 1556
1557 EXEC_DECL(jmp) { r.pc = vt_ref<vm_pc_t>(r.dest); }1557 EXEC_DECL(jmp) { r.next_pc = vt_ref<vm_pc_t>(r.dest); }
1558 1558
1559 EXEC_DECL(goto_)1559 EXEC_DECL(goto_)
1560 {1560 {
@@ -1563,7 +1563,7 @@ namespace · 2 unmodified lines
1563 assert(r.dest != nullptr);1563 assert(r.dest != nullptr);
1564 const auto pc_table = reinterpret_cast<vm_pc_t *>(r.dest);1564 const auto pc_table = reinterpret_cast<vm_pc_t *>(r.dest);
1565 1565
1566 r.pc = pc_table[pc_index];1566 r.next_pc = pc_table[pc_index];
1567 }1567 }
1568 1568
1569 //1569 //
@@ -1673,8 +1673,7 @@ namespace · 103 unmodified lines
1673 vm_frame_t *target_frame;1673 vm_frame_t *target_frame;
1674 vm_pc_t handler_pc;1674 vm_pc_t handler_pc;
1675 1675
1676 // The faulting pc is minus one since the VM has already incremented the counter.1676 const auto faulting_pc = r.pc;
1677 const auto faulting_pc = r.pc - 1;
1678 1677
1679 assert(r.module_ref != nullptr);1678 assert(r.module_ref != nullptr);
1680 std::tie(handler, target_frame, handler_pc) = find_exception_handler(r.stack, *r.module_ref, faulting_pc, *exception_id);1679 std::tie(handler, target_frame, handler_pc) = find_exception_handler(r.stack, *r.module_ref, faulting_pc, *exception_id);
@@ -1718,7 +1717,7 @@ namespace · 37 unmodified lines
1718 // Set the exception destination.1717 // Set the exception destination.
1719 pt_ref(exception_destination) = e->get_allocation();1718 pt_ref(exception_destination) = e->get_allocation();
1720 1719
1721 r.pc = handler_pc;1720 r.next_pc = handler_pc;
1722 }1721 }
1723 1722
1724 // [SPEC] Added to support debugger.1723 // [SPEC] Added to support debugger.
src/vm/thread.cpp+18−17
@@ -59,6 +59,7 @@ vm_registers_t::vm_registers_t( · 58 unmodified lines
59 , mp_base{ entry.mp_base }59 , mp_base{ entry.mp_base }
60 , thread{ thread }60 , thread{ thread }
61 , pc{ entry.module->header.entry_pc }61 , pc{ entry.module->header.entry_pc }
62 , next_pc { entry.module->header.entry_pc }
62 , stack{ static_cast<std::size_t>(entry.module->header.stack_extent) }63 , stack{ static_cast<std::size_t>(entry.module->header.stack_extent) }
63 , tool_dispatch{ nullptr }64 , tool_dispatch{ nullptr }
64 , src{ nullptr }65 , src{ nullptr }
@@ -171,9 +172,9 @@ vm_thread_t::~vm_thread_t() · 106 unmodified lines
171 172
172namespace173namespace
173{174{
174 struct execute_with_tool_t175 struct execute_with_tool_t final
175 {176 {
176 void begin_exec_loop(vm_registers_t &registers, vm_t &)177 static void begin_exec_loop(vm_registers_t &registers, vm_t &)
177 {178 {
178 auto tool_dispatch = registers.tool_dispatch.load();179 auto tool_dispatch = registers.tool_dispatch.load();
179 assert(tool_dispatch != nullptr);180 assert(tool_dispatch != nullptr);
@@ -182,36 +183,36 @@ namespace · 2 unmodified lines
182 }183 }
183 };184 };
184 185
185 struct execute_normal_t186 struct execute_normal_t final
186 {187 {
187 void begin_exec_loop(vm_registers_t &, vm_t &) { }188 static void begin_exec_loop(vm_registers_t &, vm_t &) { }
188 };189 };
189 190
190 template<typename EXEC_DETOUR>191 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)
192 {193 {
193 EXEC_DETOUR detour{};194 auto &execution_duration = r.current_thread_quanta;
194 auto &execution_duration = registers.current_thread_quanta;
195 for (; 0 != execution_duration; --execution_duration)195 for (; 0 != execution_duration; --execution_duration)
196 {196 {
197 detour.begin_exec_loop(registers, vm);197 EXEC_DETOUR::begin_exec_loop(r, vm);
198 assert(registers.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");198 assert(r.stack.peek_frame() != nullptr && "Thread state should not be running with empty stack");
199 199
200 const auto &code_section = registers.module_ref->code_section;200 const auto &code_section = r.module_ref->code_section;
201 assert(static_cast<std::size_t>(registers.pc) < code_section.size());201 assert(static_cast<std::size_t>(r.pc) < code_section.size());
202 202
203 assert(!registers.module_ref->is_builtin_module() && "Interpreter thread is unable to execute native instructions");203 assert(!r.module_ref->is_builtin_module() && "Interpreter thread is unable to execute native instructions");
204 const auto &inst = code_section[registers.pc].op;204 const auto &inst = code_section[r.pc].op;
205 const auto opcode = static_cast<std::size_t>(inst.opcode);205 const auto opcode = static_cast<std::size_t>(inst.opcode);
206 if (static_cast<std::size_t>(opcode_t::last_opcode) < opcode)206 if (static_cast<std::size_t>(opcode_t::last_opcode) < opcode)
207 throw vm_system_exception{ "Unknown op-code" };207 throw vm_system_exception{ "Unknown op-code" };
208 208
209 // Instruction is valid, decode and update registers for operation209 // Instruction is valid, decode and update registers for operation
210 decode_address(inst, registers);210 decode_address(inst, r);
211 registers.pc++;211 r.next_pc = (r.pc + 1);
212 vm_exec_table[opcode](registers, vm);212 vm_exec_table[opcode](r, vm);
213 r.pc = r.next_pc;
213 214
214 if (registers.current_thread_state != vm_thread_state_t::running)215 if (r.current_thread_state != vm_thread_state_t::running)
215 break;216 break;
216 }217 }
217 }218 }
src/vm/tool_dispatch.cpp+1−2
@@ -364,7 +364,6 @@ void vm_tool_dispatch_t::resume_all_threads() · 363 unmodified lines
364std::tuple<opcode_t, cookie_t> vm_tool_dispatch_t::get_original_opcode_and_cookie(const vm_registers_t &r)364std::tuple<opcode_t, cookie_t> vm_tool_dispatch_t::get_original_opcode_and_cookie(const vm_registers_t &r)
365{365{
366 const auto module = r.module_ref->module.get();366 const auto module = r.module_ref->module.get();
367 const auto current_pc = r.pc - 1;
368 367
369 if (module == nullptr || util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin))368 if (module == nullptr || util::has_flag(module->header.runtime_flag, runtime_flags_t::builtin))
370 throw vm_system_exception{ "Unable to determine original opcode in supplied module" };369 throw vm_system_exception{ "Unable to determine original opcode in supplied module" };
@@ -375,7 +374,7 @@ std::tuple<opcode_t, cookie_t> vm_tool_dispatch_t::get_original_opcode_and_cooki · 4 unmodified lines
375 if (iter_orig != _breakpoints.original_opcodes.cend())374 if (iter_orig != _breakpoints.original_opcodes.cend())
376 {375 {
377 auto &pc_map = iter_orig->second;376 auto &pc_map = iter_orig->second;
378 auto iter_pc = pc_map.find(current_pc);377 auto iter_pc = pc_map.find(r.pc);
379 if (iter_pc != pc_map.cend())378 if (iter_pc != pc_map.cend())
380 return iter_pc->second;379 return iter_pc->second;
381 }380 }