refactor(furvm): refactor mod

Refs: #12
This commit is contained in:
2026-06-16 12:04:02 +02:00
parent b35a274e81
commit 43dac1ec6d
6 changed files with 90 additions and 58 deletions
+26 -32
View File
@@ -6,7 +6,10 @@
#include "furvm/module.hpp" #include "furvm/module.hpp"
#include <queue> #include <queue>
#include <string>
#include <type_traits> #include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector> #include <vector>
namespace furvm { namespace furvm {
@@ -33,73 +36,64 @@ public:
context& operator=(const context&) = delete; context& operator=(const context&) = delete;
public: public:
/** /**
* @brief Adds a module to this context. * @brief Emplaces a new module in this context.
* *
* @param args Arguments to forward to module's constructor. * @param args Arguments to forward to module's constructor.
* @return An index to the emplaced module. * @return An index to the emplaced module.
*/ */
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<mod, module_handle, Args...>>> template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<mod, Args...>>>
constexpr const auto& emplace(Args&&... args) { auto& emplace_module(Args&&... args) {
module_handle id = static_cast<module_handle>(m_modules.size()); mod_p mod = std::make_shared<class mod>(std::forward<Args>(args)...);
return m_modules.emplace_back(std::make_unique<mod>(id, std::forward<Args>(args)...)); return m_modules.emplace(mod->name(), std::move(mod)).first->second;
} }
/** /**
* @brief Erases a module from this context. * @brief Erases a module from this context.
* *
* @param index Index to the module. * @param name Name of the module to erase.
* @return Old value. * @return A shared pointer to the erased module.
*/ */
mod_p erase(module_handle index) { template <typename Name>
if (index >= m_modules.size()) return nullptr; mod_p erase_module(Name&& name) {
return std::move(m_modules[index]); return std::move(m_modules.erase(std::forward<Name>(name))->second);
} }
/** /**
* @brief Returns a module of this context. * @brief Returns a module of this context.
* *
* @param index Position of the module. * @param name Name of the module.
* @return The module. * @return The module.
*/ */
constexpr mod_p& operator[](module_handle index) { return m_modules[index]; } template <typename Name>
constexpr mod_p& module_at(Name&& name) {
return m_modules.at(std::forward<Name>(name));
}
/** /**
* @brief Returns a module of this context. * @brief Returns a module of this context.
* *
* @param index Position of the module. * @param name Name of the module.
* @return The module. * @return The module.
*/ */
constexpr const mod_p& operator[](module_handle index) const { return m_modules[index]; } template <typename Name>
constexpr const mod_p& module_at(Name&& name) const {
/** return m_modules.at(std::forward<Name>(name));
* @brief Returns a module of this context. }
*
* @param index Position of the module.
* @return The module.
*/
constexpr mod_p& at(module_handle index) { return m_modules.at(index); }
/**
* @brief Returns a module of this context.
*
* @param index Position of the module.
* @return The module.
*/
constexpr const mod_p& at(module_handle index) const { return m_modules.at(index); }
/** /**
* @brief Returns how many does this context have modules. * @brief Returns how many does this context have modules.
* *
* @return The module count. * @return The module count.
*/ */
constexpr size_t size() const { return m_modules.size(); } constexpr size_t module_count() const { return m_modules.size(); }
public: public:
/** /**
* @brief Removes unreferenced things from the thing list. * @brief Removes unreferenced things from the thing list.
*/ */
void collect(); void collect();
private: private:
std::vector<mod_p> m_modules; std::unordered_map<std::string, mod_p> m_modules;
std::vector<thing_p> m_things; std::vector<thing_p> m_things;
std::vector<executor_p> m_executors; std::vector<executor_p> m_executors;
+11 -8
View File
@@ -6,6 +6,8 @@
#include <functional> #include <functional>
#include <stdexcept> #include <stdexcept>
#include <string>
#include <utility>
namespace furvm { namespace furvm {
@@ -46,7 +48,7 @@ public:
*/ */
function(funkcja, function_handle id, const native_function& native, const mod_p& mod); function(funkcja, function_handle id, const native_function& native, const mod_p& mod);
~function() = default; ~function();
/** /**
* @brief Move constructor. * @brief Move constructor.
@@ -120,13 +122,13 @@ public:
} }
/** /**
* @brief Returns a module of imported function. * @brief Returns a name of the function's module.
* *
* @return A handle to the module. * @return The name.
*/ */
module_handle imported_module() const { const std::string& imported_module() const {
if (m_type != function_t::Import) throw std::runtime_error("function type mismatch"); if (m_type != function_t::Import) throw std::runtime_error("function type mismatch");
return m_value.imp.mod; return m_value.imp.moduleName;
} }
/** /**
@@ -147,7 +149,7 @@ private:
std::size_t position = 0; std::size_t position = 0;
native_function native; native_function native;
struct { struct {
module_handle mod; std::string moduleName;
function_handle function; function_handle function;
} imp; } imp;
@@ -159,8 +161,9 @@ private:
value(const native_function& native) value(const native_function& native)
: native(native) {} : native(native) {}
value(module_handle mod, function_handle function) template <typename Name>
: imp({ mod, function }) {} value(Name&& moduleName, function_handle function)
: imp({ std::forward<Name>(moduleName), function }) {}
~value() {} ~value() {}
-5
View File
@@ -93,11 +93,6 @@ class mod;
*/ */
using mod_p = std::shared_ptr<mod>; using mod_p = std::shared_ptr<mod>;
/**
* @brief Furvm module's index.
*/
using module_handle = std::uint32_t;
// thing.hpp // thing.hpp
/** /**
+34 -7
View File
@@ -3,6 +3,7 @@
#include "furvm/fwd.hpp" #include "furvm/fwd.hpp"
#include <string>
#include <vector> #include <vector>
namespace furvm { namespace furvm {
@@ -16,12 +17,24 @@ public:
/** /**
* @brief Construct a new module. * @brief Construct a new module.
* *
* @param id Id of this module. * @param name Name of this module.
* @param args Arguments to forward to bytecode's constructor.
*/
template <typename Name,
typename... Args,
typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>>
mod(Name&& name, Args&&... args)
: m_name(std::forward<Name>(name)), m_bytecode(std::forward<Args>(args)...) {}
/**
* @brief Construct a new module.
*
* @param name C-string name of this module.
* @param args Arguments to forward to bytecode's constructor. * @param args Arguments to forward to bytecode's constructor.
*/ */
template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>> template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<bytecode_t, Args...>>>
mod(module_handle id, Args&&... args) mod(const char* name, Args&&... args)
: m_id(id), m_bytecode(std::forward<Args>(args)...) {} : m_name(name), m_bytecode(std::forward<Args>(args)...) {}
~mod() = default; ~mod() = default;
@@ -39,11 +52,11 @@ public:
mod& operator=(const mod&) = delete; mod& operator=(const mod&) = delete;
public: public:
/** /**
* @brief Returns an id of this module. * @brief Returns this module's name.
* *
* @return The id. * @return The name.
*/ */
constexpr module_handle id() const { return m_id; } constexpr const std::string& name() const { return m_name; }
/** /**
* @brief Returns a byte from bytecode of this module. * @brief Returns a byte from bytecode of this module.
@@ -52,6 +65,20 @@ public:
* @return The byte. * @return The byte.
*/ */
constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); } constexpr byte byte(std::size_t offset) const { return m_bytecode.at(offset); }
/**
* @brief Returns a reference to the module's bytecode.
*
* @return The reference to bytecode.
*/
constexpr bytecode_t& bytecode() { return m_bytecode; }
/**
* @brief Returns a const reference to the module's bytecode.
*
* @return The reference to bytecode.
*/
constexpr const bytecode_t& bytecode() const { return m_bytecode; }
public: public:
/** /**
* @brief Returns a function from this module. * @brief Returns a function from this module.
@@ -61,7 +88,7 @@ public:
*/ */
constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); } constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); }
private: private:
module_handle m_id; std::string m_name;
bytecode_t m_bytecode; bytecode_t m_bytecode;
std::vector<function_p> m_functions; std::vector<function_p> m_functions;
}; };
+15 -2
View File
@@ -1,5 +1,7 @@
#include "furvm/function.hpp" #include "furvm/function.hpp"
#include <utility>
namespace furvm { namespace furvm {
function::function(funkcja, function_handle id, std::size_t position, const mod_p& mod) function::function(funkcja, function_handle id, std::size_t position, const mod_p& mod)
@@ -8,6 +10,17 @@ function::function(funkcja, function_handle id, std::size_t position, const mod_
function::function(funkcja, function_handle id, const native_function& native, const mod_p& mod) function::function(funkcja, function_handle id, const native_function& native, const mod_p& mod)
: m_id(id), m_type(function_t::Native), m_module(mod), m_value(native) {} : m_id(id), m_type(function_t::Native), m_module(mod), m_value(native) {}
function::~function() {
switch (m_type) {
case function_t::Normal:
case function_t::Native:
default: break;
case function_t::Import: {
m_value.imp.moduleName.~basic_string();
} break;
}
}
function::function(function&& other) noexcept function::function(function&& other) noexcept
: m_id(other.m_id), m_type(other.m_type), m_module(std::move(other.m_module)) { : m_id(other.m_id), m_type(other.m_type), m_module(std::move(other.m_module)) {
switch (m_type) { switch (m_type) {
@@ -18,7 +31,7 @@ function::function(function&& other) noexcept
new (&m_value.native) native_function(std::move(other.m_value.native)); new (&m_value.native) native_function(std::move(other.m_value.native));
} break; } break;
case function_t::Import: { case function_t::Import: {
m_value.imp.mod = other.m_value.imp.mod; m_value.imp.moduleName = std::move(other.m_value.imp.moduleName);
m_value.imp.function = other.m_value.imp.function; m_value.imp.function = other.m_value.imp.function;
} break; } break;
} }
@@ -39,7 +52,7 @@ function& function::operator=(function&& other) noexcept {
new (&m_value.native) native_function(std::move(other.m_value.native)); new (&m_value.native) native_function(std::move(other.m_value.native));
} break; } break;
case function_t::Import: { case function_t::Import: {
m_value.imp.mod = other.m_value.imp.mod; m_value.imp.moduleName = std::move(other.m_value.imp.moduleName);
m_value.imp.function = other.m_value.imp.function; m_value.imp.function = other.m_value.imp.function;
} break; } break;
} }
+1 -1
View File
@@ -24,7 +24,7 @@ static constexpr std::array<furvm::byte, 8> s_bytecode = {
int main(void) { int main(void) {
auto context = std::make_shared<furvm::context>(); auto context = std::make_shared<furvm::context>();
auto mainModule = context->emplace(s_bytecode.begin(), s_bytecode.end()); auto mainModule = context->emplace_module("main", s_bytecode.begin(), s_bytecode.end());
auto mainFunction = furvm::function::create(mainModule, 0); auto mainFunction = furvm::function::create(mainModule, 0);