153 lines · 5.3 KB · C
RawDownload
//// Dis VM// File: disvm.h// Author: arr// #ifndef _DISVM_SRC_INCLUDE_DISVM_H_#define _DISVM_SRC_INCLUDE_DISVM_H_ #include <array>#include <iosfwd>#include <memory>#include <functional>#include <mutex>#include <forward_list>#include "runtime.h"#include "exceptions.h" namespace disvm{    // Read in a module from the supplied stream    std::unique_ptr<runtime::vm_module_t> read_module(std::istream &data);     template <typename C>    using create_vm_interface_callback_t = std::unique_ptr<C>(*)(vm_t &);     // VM version structure    // Adheres to the semantic versioning scheme found at http://semver.org/    struct vm_version_t final    {        const uint32_t major;        const uint32_t minor;        const uint32_t patch;        const char * const label; // Optional    };     // Loaded module reference    class loaded_vm_module_t final    {    public:        runtime::module_id_t vm_id;         // Origin of module        std::unique_ptr<runtime::vm_string_t> origin;         // Weak reference to a loaded module        std::weak_ptr<runtime::vm_module_t> module;    };     // Callback for enumerating loaded modules - return 'false' to stop enumeration, otherwise 'true'    using loaded_vm_module_callback_t = std::function<bool(const loaded_vm_module_t&)>;     // Configuration for the created VM    class vm_config_t final    {    public:        vm_config_t();        vm_config_t(vm_config_t &&);         // Settings for the default scheduler. Only used if create_scheduler is not set.        // Both of these values are initialized to valid default values on construction.        uint32_t sys_thread_pool_size;        uint32_t thread_quanta;         create_vm_interface_callback_t<runtime::vm_scheduler_t> create_scheduler;        create_vm_interface_callback_t<runtime::vm_garbage_collector_t> create_gc;         // Prefix paths used by the default module resolver if the path supplied by        // the user isn't found. Note these will be concatenated with the supplied        // path, not other manipulation will be performed.        std::vector<std::string> probing_paths;        std::vector<std::unique_ptr<runtime::vm_module_resolver_t>> additional_resolvers;    };     // Virtual machine    class vm_t final    {    public: // static        static const uint32_t root_vm_thread_id;     public:        explicit vm_t();        explicit vm_t(vm_config_t config);         ~vm_t();     public:        // Get the VM version.        // All fields on the output structure will be set.        vm_version_t get_version() const;         // Begin execution of the module at the supplied path and return the ID of        // the executing thread.        uint32_t exec(const char *path);         // Begin execution of the supplied module and return the ID of the executing thread.        uint32_t exec(std::unique_ptr<runtime::vm_module_t> entry_module);         // Begin execution of a child thread in the supplied module at the indicated        // program counter and return the ID of the executing thread.        uint32_t fork(            const uint32_t parent_tid,            runtime::vm_module_ref_t &module_ref,            const runtime::vm_frame_t &initial_frame,            runtime::vm_pc_t initial_pc);         // Load the module at the supplied path into the virtual machine.        std::shared_ptr<runtime::vm_module_t> load_module(const char *path);         // Enumerate all loaded modules - this can include references to modules that        // have been unloaded due to no longer being used. If the module instance is null, the        // module is no longer loaded.        // Note this will only enumerate modules that have been loaded via a path.        void enum_loaded_modules(loaded_vm_module_callback_t callback) const;         // Access the scheduler control for this VM.        runtime::vm_scheduler_control_t &get_scheduler_control() const;         // Access the garbage collector for this VM.        runtime::vm_garbage_collector_t &get_garbage_collector() const;         // Spin and sleep until the VM is idle, then return.        // Idle is defined as no vm threads executing, scheduled to be executed, or blocked.        void spin_sleep_till_idle(std::chrono::milliseconds sleep_interval) const;         // Loads a tool into the VM        std::size_t load_tool(std::shared_ptr<runtime::vm_tool_t> tool);         // Unloads the tool associated with the supplied ID        void unload_tool(std::size_t tool_id);     private:        void schedule_thread(std::unique_ptr<runtime::vm_thread_t> thread);         using loaded_modules_t = std::forward_list<loaded_vm_module_t>;        mutable std::mutex _modules_lock;        loaded_modules_t _modules;         std::vector<std::unique_ptr<runtime::vm_module_resolver_t>> _module_resolvers;        std::unique_ptr<runtime::vm_scheduler_t> _scheduler;        std::unique_ptr<runtime::vm_garbage_collector_t> _gc;        std::unique_ptr<runtime::vm_tool_dispatch_t> _tool_dispatch;        std::mutex _tool_dispatch_lock;         std::atomic_flag _last_syscall_error_message_lock;        std::array<char, 128> _last_syscall_error_message;         friend void disvm::runtime::push_syscall_error_message(disvm::vm_t &, const char *) noexcept;        friend std::string disvm::runtime::pop_syscall_error_message(disvm::vm_t &);    };} #endif // _DISVM_SRC_INCLUDE_DISVM_H_