Showing the changes to src/include (6 of 16 files). Show all
Unified · Split
| @@ -24,6 +24,7 @@ namespace disvm · 23 unmodified lines | |||
| 24 | stack, | 24 | stack, |
| 25 | channel, | 25 | channel, |
| 26 | exception, | 26 | exception, |
| 27 | tool, | ||
| 27 | memory, // Noisy component | 28 | memory, // Noisy component |
| 28 | addressing, // Noisy component [DEBUG build only] | 29 | addressing, // Noisy component [DEBUG build only] |
| 29 | 30 | ||
| @@ -71,6 +71,10 @@ namespace disvm · 70 unmodified lines | |||
| 71 | // Load the module at the supplied path into the virtual machine | 71 | // Load the module at the supplied path into the virtual machine |
| 72 | std::shared_ptr<const runtime::vm_module_t> load_module(const char *path); | 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 | // Access the scheduler control for this VM. | 78 | // Access the scheduler control for this VM. |
| 75 | runtime::vm_scheduler_control_t &get_scheduler_control() const; | 79 | runtime::vm_scheduler_control_t &get_scheduler_control() const; |
| 76 | 80 | ||
| @@ -86,7 +90,7 @@ namespace disvm · 9 unmodified lines | |||
| 86 | class loaded_module_t final | 90 | class loaded_module_t final |
| 87 | { | 91 | { |
| 88 | public: | 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 | loaded_module_t(const loaded_module_t &) = delete; | 94 | loaded_module_t(const loaded_module_t &) = delete; |
| 91 | loaded_module_t &operator=(const loaded_module_t &) = delete; | 95 | loaded_module_t &operator=(const loaded_module_t &) = delete; |
| 92 | 96 | ||
| @@ -97,11 +101,11 @@ namespace disvm · 4 unmodified lines | |||
| 97 | std::unique_ptr<runtime::vm_string_t> origin; | 101 | std::unique_ptr<runtime::vm_string_t> origin; |
| 98 | 102 | ||
| 99 | // Weak reference to a loaded module | 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 | using loaded_modules_t = std::forward_list<loaded_module_t>; | 107 | using loaded_modules_t = std::forward_list<loaded_module_t>; |
| 104 | std::mutex _modules_lock; | 108 | mutable std::mutex _modules_lock; |
| 105 | loaded_modules_t _modules; | 109 | loaded_modules_t _modules; |
| 106 | 110 | ||
| 107 | std::unique_ptr<runtime::vm_scheduler_t> _scheduler; | 111 | std::unique_ptr<runtime::vm_scheduler_t> _scheduler; |
| @@ -190,9 +190,12 @@ namespace disvm · 189 unmodified lines | |||
| 190 | expf, | 190 | expf, |
| 191 | self, | 191 | self, |
| 192 | 192 | ||
| 193 | // [SPEC] Added opcode for debugging support. | ||
| 194 | brkpt, | ||
| 195 | |||
| 193 | // markers | 196 | // markers |
| 194 | first_opcode = invalid, | 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 | namespace disvm | 22 | namespace disvm |
| 23 | { | 23 | { |
| 24 | // VM forward declation | 24 | // Forward declaration |
| 25 | class vm_t; | 25 | class vm_t; |
| 26 | 26 | ||
| 27 | namespace runtime | 27 | namespace runtime |
| @@ -43,7 +43,7 @@ namespace disvm · 15 unmodified lines | |||
| 43 | // VM memory management | 43 | // VM memory management |
| 44 | // | 44 | // |
| 45 | 45 | ||
| 46 | // VM forward declation | 46 | // Forward declaration |
| 47 | class vm_alloc_t; | 47 | class vm_alloc_t; |
| 48 | 48 | ||
| 49 | // Finalizer callback for allocations. | 49 | // Finalizer callback for allocations. |
| @@ -75,7 +75,7 @@ namespace disvm · 25 unmodified lines | |||
| 75 | const vm_alloc_instance_finalizer_t finalizer; | 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 | class intrinsic_type_desc final | 79 | class intrinsic_type_desc final |
| 80 | { | 80 | { |
| 81 | public: | 81 | public: |
| @@ -262,7 +262,7 @@ namespace disvm · 180 unmodified lines | |||
| 262 | const bool _is_alloc; | 262 | const bool _is_alloc; |
| 263 | }; | 263 | }; |
| 264 | 264 | ||
| 265 | // VM forward declation | 265 | // Forward declaration |
| 266 | class vm_channel_t; | 266 | class vm_channel_t; |
| 267 | 267 | ||
| 268 | // VM request mutex | 268 | // VM request mutex |
| @@ -299,10 +299,12 @@ namespace disvm · 30 unmodified lines | |||
| 299 | public: //static | 299 | public: //static |
| 300 | static std::shared_ptr<const type_descriptor_t> type_desc(); | 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 | public: | 304 | public: |
| 303 | vm_channel_t( | 305 | vm_channel_t( |
| 304 | std::shared_ptr<const type_descriptor_t> td, | 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 | word_t buffer_len); | 308 | word_t buffer_len); |
| 307 | ~vm_channel_t(); | 309 | ~vm_channel_t(); |
| 308 | 310 | ||
| @@ -331,7 +333,7 @@ namespace disvm · 22 unmodified lines | |||
| 331 | private: | 333 | private: |
| 332 | std::mutex _data_lock; | 334 | std::mutex _data_lock; |
| 333 | std::shared_ptr<const type_descriptor_t> _data_type; | 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 | vm_array_t *_data_buffer; | 338 | vm_array_t *_data_buffer; |
| 337 | uint32_t _data_buffer_head; // Next element to remove from buffer | 339 | uint32_t _data_buffer_head; // Next element to remove from buffer |
| @@ -406,7 +408,7 @@ namespace disvm · 68 unmodified lines | |||
| 406 | using src_data_t = inst_data_generic_t; | 408 | using src_data_t = inst_data_generic_t; |
| 407 | using dest_data_t = inst_data_generic_t; | 409 | using dest_data_t = inst_data_generic_t; |
| 408 | 410 | ||
| 409 | // VM forward declation | 411 | // Forward declaration |
| 410 | class vm_registers_t; | 412 | class vm_registers_t; |
| 411 | 413 | ||
| 412 | // Instruction execution operation | 414 | // Instruction execution operation |
| @@ -710,6 +712,7 @@ namespace disvm · 297 unmodified lines | |||
| 710 | 712 | ||
| 711 | // Forward declaration | 713 | // Forward declaration |
| 712 | class vm_thread_t; | 714 | class vm_thread_t; |
| 715 | class vm_tool_dispatch_t; | ||
| 713 | 716 | ||
| 714 | // VM registers | 717 | // VM registers |
| 715 | class vm_registers_t | 718 | class vm_registers_t |
| @@ -721,6 +724,7 @@ namespace disvm · 5 unmodified lines | |||
| 721 | ~vm_registers_t(); | 724 | ~vm_registers_t(); |
| 722 | 725 | ||
| 723 | const vm_thread_t &thread; | 726 | const vm_thread_t &thread; |
| 727 | std::atomic<vm_tool_dispatch_t *> tool_dispatch; | ||
| 724 | vm_stack_t stack; // Frame pointer access (FP) | 728 | vm_stack_t stack; // Frame pointer access (FP) |
| 725 | vm_pc_t pc; // Program counter (Index into module code section) | 729 | vm_pc_t pc; // Program counter (Index into module code section) |
| 726 | vm_alloc_t *mp_base; // Module data base pointer (MP) | 730 | vm_alloc_t *mp_base; // Module data base pointer (MP) |
| @@ -752,13 +756,17 @@ namespace disvm · 25 unmodified lines | |||
| 752 | uint32_t parent_thread_id); | 756 | uint32_t parent_thread_id); |
| 753 | vm_thread_t( | 757 | vm_thread_t( |
| 754 | vm_module_ref_t &entry, | 758 | vm_module_ref_t &entry, |
| 759 | uint32_t parent_thread_id, | ||
| 755 | const vm_frame_t &initial_frame, | 760 | const vm_frame_t &initial_frame, |
| 756 | vm_pc_t start_pc, | 761 | vm_pc_t start_pc); |
| 757 | uint32_t parent_thread_id); | ||
| 758 | 762 | ||
| 759 | ~vm_thread_t(); | 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 | vm_thread_state_t get_state() const; | 771 | vm_thread_state_t get_state() const; |
| 764 | 772 | ||
| @@ -834,6 +842,25 @@ namespace disvm · 69 unmodified lines | |||
| 834 | 842 | ||
| 835 | // Create a garbage collector that does nothing. | 843 | // Create a garbage collector that does nothing. |
| 836 | std::unique_ptr<vm_garbage_collector_t> create_no_op_gc(vm_t &); | 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 | // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. | 33 | // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. |
| 34 | std::size_t count_codepoints(const uint8_t *str, const std::size_t max_len); | 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 | accept = 0, | 38 | accept = 0, |
| 39 | reject = 12 | 39 | reject = 12 |
| @@ -41,7 +41,7 @@ namespace disvm · 1 unmodified line | |||
| 41 | 41 | ||
| 42 | // Decode a byte at a time to form a codepoint. | 42 | // Decode a byte at a time to form a codepoint. |
| 43 | // See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. | 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 | // Decode the next codepoint in the supplied string. | 46 | // Decode the next codepoint in the supplied string. |
| 47 | // Returns number of characters in string consumed. | 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_ | ||