Showing the changes to src/include (6 of 16 files). Show all
Unified · Split
| @@ -24,6 +24,7 @@ namespace disvm · 23 unmodified lines | ||
| 24 | 24 | stack, |
| 25 | 25 | channel, |
| 26 | 26 | exception, |
| 27 | + tool, | |
| 27 | 28 | memory, // Noisy component |
| 28 | 29 | addressing, // Noisy component [DEBUG build only] |
| 29 | 30 | |
| @@ -71,6 +71,10 @@ namespace disvm · 70 unmodified lines | ||
| 71 | 71 | // Load the module at the supplied path into the virtual machine |
| 72 | 72 | std::shared_ptr<const runtime::vm_module_t> load_module(const char *path); |
| 73 | 73 | |
| 74 | + // Get a collection of all currently loaded modules. | |
| 75 | + // Note this will only include modules that have been loaded by a call to vm_t::load_module. | |
| 76 | + std::vector<std::shared_ptr<const runtime::vm_module_t>> get_loaded_modules() const; | |
| 77 | + | |
| 74 | 78 | // Access the scheduler control for this VM. |
| 75 | 79 | runtime::vm_scheduler_control_t &get_scheduler_control() const; |
| 76 | 80 | |
| @@ -86,7 +90,7 @@ namespace disvm · 9 unmodified lines | ||
| 86 | 90 | class loaded_module_t final |
| 87 | 91 | { |
| 88 | 92 | public: |
| 89 | − loaded_module_t(std::unique_ptr<runtime::vm_string_t> origin, std::shared_ptr<const runtime::vm_module_t> module); | |
| 93 | + loaded_module_t(std::unique_ptr<runtime::vm_string_t> origin, std::shared_ptr<runtime::vm_module_t> module); | |
| 90 | 94 | loaded_module_t(const loaded_module_t &) = delete; |
| 91 | 95 | loaded_module_t &operator=(const loaded_module_t &) = delete; |
| 92 | 96 | |
| @@ -97,11 +101,11 @@ namespace disvm · 4 unmodified lines | ||
| 97 | 101 | std::unique_ptr<runtime::vm_string_t> origin; |
| 98 | 102 | |
| 99 | 103 | // Weak reference to a loaded module |
| 100 | − std::weak_ptr<const runtime::vm_module_t> module; | |
| 104 | + std::weak_ptr<runtime::vm_module_t> module; | |
| 101 | 105 | }; |
| 102 | 106 | |
| 103 | 107 | using loaded_modules_t = std::forward_list<loaded_module_t>; |
| 104 | − std::mutex _modules_lock; | |
| 108 | + mutable std::mutex _modules_lock; | |
| 105 | 109 | loaded_modules_t _modules; |
| 106 | 110 | |
| 107 | 111 | std::unique_ptr<runtime::vm_scheduler_t> _scheduler; |
| @@ -190,9 +190,12 @@ namespace disvm · 189 unmodified lines | ||
| 190 | 190 | expf, |
| 191 | 191 | self, |
| 192 | 192 | |
| 193 | + // [SPEC] Added opcode for debugging support. | |
| 194 | + brkpt, | |
| 195 | + | |
| 193 | 196 | // markers |
| 194 | 197 | first_opcode = invalid, |
| 195 | − last_opcode = self | |
| 198 | + last_opcode = brkpt | |
| 196 | 199 | }; |
| 197 | 200 | } |
| 198 | 201 | |
| @@ -21,7 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | |
| 22 | 22 | namespace disvm |
| 23 | 23 | { |
| 24 | − // VM forward declation | |
| 24 | + // Forward declaration | |
| 25 | 25 | class vm_t; |
| 26 | 26 | |
| 27 | 27 | namespace runtime |
| @@ -43,7 +43,7 @@ namespace disvm · 15 unmodified lines | ||
| 43 | 43 | // VM memory management |
| 44 | 44 | // |
| 45 | 45 | |
| 46 | − // VM forward declation | |
| 46 | + // Forward declaration | |
| 47 | 47 | class vm_alloc_t; |
| 48 | 48 | |
| 49 | 49 | // Finalizer callback for allocations. |
| @@ -75,7 +75,7 @@ namespace disvm · 25 unmodified lines | ||
| 75 | 75 | const vm_alloc_instance_finalizer_t finalizer; |
| 76 | 76 | }; |
| 77 | 77 | |
| 78 | − // Access to type descriptors for VM intrinsic types. | |
| 78 | + // Access to type descriptors for VM intrinsic types | |
| 79 | 79 | class intrinsic_type_desc final |
| 80 | 80 | { |
| 81 | 81 | public: |
| @@ -262,7 +262,7 @@ namespace disvm · 180 unmodified lines | ||
| 262 | 262 | const bool _is_alloc; |
| 263 | 263 | }; |
| 264 | 264 | |
| 265 | − // VM forward declation | |
| 265 | + // Forward declaration | |
| 266 | 266 | class vm_channel_t; |
| 267 | 267 | |
| 268 | 268 | // VM request mutex |
| @@ -299,10 +299,12 @@ namespace disvm · 30 unmodified lines | ||
| 299 | 299 | public: //static |
| 300 | 300 | static std::shared_ptr<const type_descriptor_t> type_desc(); |
| 301 | 301 | |
| 302 | + using data_transfer_func_t = void(*)(pointer_t, pointer_t, const type_descriptor_t *); | |
| 303 | + | |
| 302 | 304 | public: |
| 303 | 305 | vm_channel_t( |
| 304 | 306 | std::shared_ptr<const type_descriptor_t> td, |
| 305 | − std::function<void(pointer_t, pointer_t, const type_descriptor_t *)> transfer, | |
| 307 | + data_transfer_func_t transfer, | |
| 306 | 308 | word_t buffer_len); |
| 307 | 309 | ~vm_channel_t(); |
| 308 | 310 | |
| @@ -331,7 +333,7 @@ namespace disvm · 22 unmodified lines | ||
| 331 | 333 | private: |
| 332 | 334 | std::mutex _data_lock; |
| 333 | 335 | std::shared_ptr<const type_descriptor_t> _data_type; |
| 334 | − std::function<void(pointer_t, pointer_t, const type_descriptor_t *)> _data_transfer; | |
| 336 | + data_transfer_func_t _data_transfer; | |
| 335 | 337 | |
| 336 | 338 | vm_array_t *_data_buffer; |
| 337 | 339 | uint32_t _data_buffer_head; // Next element to remove from buffer |
| @@ -406,7 +408,7 @@ namespace disvm · 68 unmodified lines | ||
| 406 | 408 | using src_data_t = inst_data_generic_t; |
| 407 | 409 | using dest_data_t = inst_data_generic_t; |
| 408 | 410 | |
| 409 | − // VM forward declation | |
| 411 | + // Forward declaration | |
| 410 | 412 | class vm_registers_t; |
| 411 | 413 | |
| 412 | 414 | // Instruction execution operation |
| @@ -710,6 +712,7 @@ namespace disvm · 297 unmodified lines | ||
| 710 | 712 | |
| 711 | 713 | // Forward declaration |
| 712 | 714 | class vm_thread_t; |
| 715 | + class vm_tool_dispatch_t; | |
| 713 | 716 | |
| 714 | 717 | // VM registers |
| 715 | 718 | class vm_registers_t |
| @@ -721,6 +724,7 @@ namespace disvm · 5 unmodified lines | ||
| 721 | 724 | ~vm_registers_t(); |
| 722 | 725 | |
| 723 | 726 | const vm_thread_t &thread; |
| 727 | + std::atomic<vm_tool_dispatch_t *> tool_dispatch; | |
| 724 | 728 | vm_stack_t stack; // Frame pointer access (FP) |
| 725 | 729 | vm_pc_t pc; // Program counter (Index into module code section) |
| 726 | 730 | vm_alloc_t *mp_base; // Module data base pointer (MP) |
| @@ -752,13 +756,17 @@ namespace disvm · 25 unmodified lines | ||
| 752 | 756 | uint32_t parent_thread_id); |
| 753 | 757 | vm_thread_t( |
| 754 | 758 | vm_module_ref_t &entry, |
| 759 | + uint32_t parent_thread_id, | |
| 755 | 760 | const vm_frame_t &initial_frame, |
| 756 | − vm_pc_t start_pc, | |
| 757 | − uint32_t parent_thread_id); | |
| 761 | + vm_pc_t start_pc); | |
| 758 | 762 | |
| 759 | 763 | ~vm_thread_t(); |
| 760 | 764 | |
| 761 | − vm_thread_state_t execute(vm_t &virtual_machine, const uint32_t quanta); | |
| 765 | + vm_thread_state_t execute(vm_t &vm, const uint32_t quanta); | |
| 766 | + | |
| 767 | + // There is no way to get the current dispatch value. | |
| 768 | + // Setting the dispatch to 'null' detaches all tool related behavior | |
| 769 | + void set_tool_dispatch(vm_tool_dispatch_t *dispatch); | |
| 762 | 770 | |
| 763 | 771 | vm_thread_state_t get_state() const; |
| 764 | 772 | |
| @@ -834,6 +842,25 @@ namespace disvm · 69 unmodified lines | ||
| 834 | 842 | |
| 835 | 843 | // Create a garbage collector that does nothing. |
| 836 | 844 | std::unique_ptr<vm_garbage_collector_t> create_no_op_gc(vm_t &); |
| 845 | + | |
| 846 | + // Forward declaration | |
| 847 | + class vm_tool_controller_t; | |
| 848 | + | |
| 849 | + // VM tool interface | |
| 850 | + // Used to implement tools (e.g. debugger or profiler) | |
| 851 | + class vm_tool_t | |
| 852 | + { | |
| 853 | + public: | |
| 854 | + virtual ~vm_tool_t() = 0; | |
| 855 | + | |
| 856 | + // Called when the tool is loaded into the VM | |
| 857 | + virtual void on_load(vm_t &vm, vm_tool_controller_t &controller, std::size_t tool_id) = 0; | |
| 858 | + | |
| 859 | + // Called when the tool is unloaded from the VM. | |
| 860 | + // Note once the tool has been unloaded the vm and controller references supplied during load | |
| 861 | + // should not be used as they may no longer be valid. | |
| 862 | + virtual void on_unload() = 0; | |
| 863 | + }; | |
| 837 | 864 | } |
| 838 | 865 | } |
| 839 | 866 | |
| @@ -33,7 +33,7 @@ namespace disvm · 32 unmodified lines | ||
| 33 | 33 | // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. |
| 34 | 34 | std::size_t count_codepoints(const uint8_t *str, const std::size_t max_len); |
| 35 | 35 | |
| 36 | − enum class decode_state | |
| 36 | + enum class decode_state_t | |
| 37 | 37 | { |
| 38 | 38 | accept = 0, |
| 39 | 39 | reject = 12 |
| @@ -41,7 +41,7 @@ namespace disvm · 1 unmodified line | ||
| 41 | 41 | |
| 42 | 42 | // Decode a byte at a time to form a codepoint. |
| 43 | 43 | // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. |
| 44 | − decode_state decode_step(decode_state &state, rune_t &codepoint, uint8_t byte); | |
| 44 | + decode_state_t decode_step(decode_state_t &state, rune_t &codepoint, uint8_t byte); | |
| 45 | 45 | |
| 46 | 46 | // Decode the next codepoint in the supplied string. |
| 47 | 47 | // Returns number of characters in string consumed. |
| @@ -0,0 +1,63 @@ | ||
| 1 | +// | |
| 2 | +// Dis VM | |
| 3 | +// File: vm_tools.h | |
| 4 | +// Author: arr | |
| 5 | +// | |
| 6 | + | |
| 7 | +#ifndef _DISVM_SRC_INCLUDE_VM_TOOLS_H_ | |
| 8 | +#define _DISVM_SRC_INCLUDE_VM_TOOLS_H_ | |
| 9 | + | |
| 10 | +#include <cstdint> | |
| 11 | +#include <vector> | |
| 12 | +#include <memory> | |
| 13 | +#include <functional> | |
| 14 | +#include "runtime.h" | |
| 15 | + | |
| 16 | +namespace disvm | |
| 17 | +{ | |
| 18 | + namespace runtime | |
| 19 | + { | |
| 20 | + union vm_context_value_t | |
| 21 | + { | |
| 22 | + std::size_t i; | |
| 23 | + vm_t *vm; | |
| 24 | + vm_module_t *module; | |
| 25 | + vm_registers_t *registers; | |
| 26 | + vm_alloc_t *alloc; | |
| 27 | + }; | |
| 28 | + | |
| 29 | + struct vm_event_context_t | |
| 30 | + { | |
| 31 | + vm_context_value_t value1; | |
| 32 | + vm_context_value_t value2; | |
| 33 | + }; | |
| 34 | + | |
| 35 | + enum class vm_event_t | |
| 36 | + { | |
| 37 | + module_load, // value1: vm_module_t | |
| 38 | + module_unload, // value1: vm_module_t | |
| 39 | + thread_begin, // value1: vm_registers_t | |
| 40 | + thread_end, // value1: vm_registers_t | |
| 41 | + exception_raised, // value1: vm_registers_t value2: vm_alloc_t | |
| 42 | + exception_unhandled, // value1: vm_registers_t value2: vm_alloc_t | |
| 43 | + breakpoint, // value1: vm_registers_t value2: std::size_t | |
| 44 | + }; | |
| 45 | + | |
| 46 | + using vm_event_callback_t = std::function<void(vm_event_t, vm_event_context_t &)>; | |
| 47 | + | |
| 48 | + // VM tool controller | |
| 49 | + class vm_tool_controller_t | |
| 50 | + { | |
| 51 | + public: | |
| 52 | + // Call the supplied callback when the specified event occurs | |
| 53 | + virtual std::size_t subscribe_event(vm_event_t, vm_event_callback_t) = 0; | |
| 54 | + virtual void unsubscribe_event(std::size_t) = 0; | |
| 55 | + | |
| 56 | + // Set a breakpoint in the supplied module at the specified PC location | |
| 57 | + virtual std::size_t set_breakpoint(std::shared_ptr<const vm_module_t>, vm_pc_t) = 0; | |
| 58 | + virtual void clear_breakpoint(std::size_t) = 0; | |
| 59 | + }; | |
| 60 | + } | |
| 61 | +} | |
| 62 | + | |
| 63 | +#endif // _DISVM_SRC_INCLUDE_VM_TOOLS_H_ | |