From 78acfb6ee2e0b49968ab097f54ff76debb4c4fc2 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Tue, 16 Jun 2026 12:48:16 +0200 Subject: [PATCH] refactor(furvm): refactor function Refs: #12 --- furvm/include/furvm/executor.hpp | 5 +- furvm/include/furvm/function.hpp | 83 +++++++++++--------------------- furvm/include/furvm/fwd.hpp | 5 ++ furvm/include/furvm/module.hpp | 46 ++++++++++++++++-- furvm/src/executor.cpp | 11 +++-- furvm/src/function.cpp | 13 ++--- furvm/src/main.cpp | 5 +- furvm/src/serializer.cpp | 7 ++- 8 files changed, 94 insertions(+), 81 deletions(-) diff --git a/furvm/include/furvm/executor.hpp b/furvm/include/furvm/executor.hpp index a2c264c..3f0a187 100644 --- a/furvm/include/furvm/executor.hpp +++ b/furvm/include/furvm/executor.hpp @@ -97,9 +97,10 @@ public: /** * @brief Pushes a new frame. * - * @param function Function. + * @param mod Module. + * @param function Function handle. */ - void push_frame(const function_p& function); + void push_frame(const mod_p& mod, function_handle function); /** * @brief Pops the top frame. diff --git a/furvm/include/furvm/function.hpp b/furvm/include/furvm/function.hpp index 2831cc1..4356a05 100644 --- a/furvm/include/furvm/function.hpp +++ b/furvm/include/furvm/function.hpp @@ -2,7 +2,6 @@ #define FURVM_FUNCTION_HPP #include "furvm/fwd.hpp" -#include "furvm/module.hpp" // IWYU pragma: keep #include #include @@ -20,33 +19,30 @@ enum class function_t : std::uint8_t { using native_function = std::function; class function { -private: - /** - * @brief A private token for the private constructor. - * - * Also `funkcja` in Polish translates to `function` from what I heard. - */ - struct funkcja { - explicit funkcja() = default; - }; public: - /** - * @brief Private constructor. - * - * @param id - * @param position - * @param mod - */ - function(funkcja, function_handle id, std::size_t position, const mod_p& mod); + template + function(Name&& name, bytecode_pos position) + : m_name(std::forward(name)), m_type(function_t::Normal), m_value(position) {} - /** - * @brief Private constructor. - * - * @param id - * @param native - * @param mod - */ - function(funkcja, function_handle id, const native_function& native, const mod_p& mod); + function(const char* name, bytecode_pos position) + : m_name(name), m_type(function_t::Normal), m_value(position) {} + + template + function(Name&& name, const native_function& native) + : m_name(std::forward(name)), m_type(function_t::Native), m_value(native) {} + + function(const char* name, const native_function& native) + : m_name(name), m_type(function_t::Native), m_value(native) {} + + template + function(Name&& name, ModuleName&& moduleName, function_handle function) + : m_name(std::forward(name)), + m_type(function_t::Import), + m_value(std::forward(moduleName), function) {} + + template + function(const char* name, ModuleName&& moduleName, function_handle function) + : m_name(name), m_type(function_t::Import), m_value(std::forward(moduleName), function) {} ~function(); @@ -64,28 +60,11 @@ public: function& operator=(const function&) = delete; public: /** - * @brief Returns a new function. + * @brief Returns a name of this function. * - * @param mod Module. - * @param args Arguments to pass to the function constructor. - * @return The new function. + * @return The name. */ - template >> - static function_p create(const mod_p& mod, Args&&... args) { - function_handle id = mod->m_functions.size(); - - auto func = std::make_shared(funkcja{}, id, std::forward(args)..., mod); - mod->m_functions.emplace(mod->m_functions.begin() + id, func); - return std::move(func); - } -public: - /** - * @brief Returns an id of this function. - * - * @return The id. - */ - constexpr function_handle id() const { return m_id; } + constexpr const std::string& name() const { return m_name; } /** * @brief Returns a type of this function. @@ -93,13 +72,6 @@ public: * @return The type. */ constexpr function_t type() const { return m_type; } - - /** - * @brief Returns a parent module of this function. - * - * @return A shared pointer to the module. - */ - const mod_p& mod() const { return m_module; } public: /** * @brief Returns a value for normal function. @@ -141,9 +113,8 @@ public: return m_value.imp.function; } private: - function_handle m_id; - function_t m_type; - mod_p m_module; + std::string m_name; + function_t m_type; union value { std::size_t position = 0; diff --git a/furvm/include/furvm/fwd.hpp b/furvm/include/furvm/fwd.hpp index 04f5a2f..ef8e3f2 100644 --- a/furvm/include/furvm/fwd.hpp +++ b/furvm/include/furvm/fwd.hpp @@ -17,6 +17,11 @@ namespace furvm { */ using byte = std::uint8_t; +/** + * @brief An offset into bytecode. + */ +using bytecode_pos = std::uint64_t; + // constant.hpp /** diff --git a/furvm/include/furvm/module.hpp b/furvm/include/furvm/module.hpp index 582c38e..d39e85d 100644 --- a/furvm/include/furvm/module.hpp +++ b/furvm/include/furvm/module.hpp @@ -1,9 +1,15 @@ #ifndef FURVM_MODULE_HPP #define FURVM_MODULE_HPP +#include "furvm/function.hpp" #include "furvm/fwd.hpp" +#include +#include +#include #include +#include +#include #include namespace furvm { @@ -80,6 +86,17 @@ public: */ constexpr const bytecode_t& bytecode() const { return m_bytecode; } public: + /** + * @brief Returns a function from this module. + * + * @param name Name of the function. + * @return The function. + */ + template + constexpr const function_p& function_at(Name&& name) const { + return m_functions.at(std::forward(name)); + } + /** * @brief Returns a function from this module. * @@ -87,10 +104,33 @@ public: * @return The function. */ constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); } + + /** + * @brief Returns an id of a function. + * + * @param function Function to get the id of. + * @return The function's id. + */ + function_handle function_id(const function_p& function) const { + if (auto it = std::find(m_functions.begin(), m_functions.end(), function); it != m_functions.end()) + return it - m_functions.begin(); + throw std::runtime_error("function not in the module"); + } + + template + function_handle emplace_function(Args&&... args) { + function_p function = std::make_shared(std::forward(args)...); + m_functionMap.emplace(function->name(), function); + function_handle id = m_functions.size(); + m_functions.emplace_back(std::move(function)); + return id; + } private: - std::string m_name; - bytecode_t m_bytecode; - std::vector m_functions; + std::string m_name; + bytecode_t m_bytecode; + + std::unordered_map m_functionMap; + std::vector m_functions; }; } // namespace furvm diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 6e858bd..563c6b0 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -25,9 +25,10 @@ executor_p executor::create(const context_p& context) { return std::move(ex); } -void executor::push_frame(const function_p& function) { - if (function->type() != function_t::Normal) return; - m_frames.emplace((struct executor::frame){ function->mod(), function->position(), m_stack.size() }); +void executor::push_frame(const mod_p& mod, function_handle function) { + const auto& func = mod->function_at(function); + if (func->type() != function_t::Normal) throw std::runtime_error("unexpected function type"); + m_frames.emplace((struct executor::frame){ mod, func->position(), m_stack.size() }); } struct executor::frame executor::pop_frame() { @@ -185,11 +186,11 @@ void executor::step() { const function_p& function = frame.mod->function_at(funcId); switch (function->type()) { - case function_t::Normal: push_frame(function); break; + case function_t::Normal: push_frame(frame.mod, funcId); break; case function_t::Native: function->native()(*this); break; case function_t::Import: { const mod_p& impMod = m_context->m_modules.at(function->imported_module()); - push_frame(impMod->function_at(function->imported_function())); + push_frame(frame.mod, function->imported_function()); } break; } } break; diff --git a/furvm/src/function.cpp b/furvm/src/function.cpp index 7092a3c..baf34c8 100644 --- a/furvm/src/function.cpp +++ b/furvm/src/function.cpp @@ -4,12 +4,6 @@ namespace furvm { -function::function(funkcja, function_handle id, std::size_t position, const mod_p& mod) - : m_id(id), m_type(function_t::Normal), m_module(mod), m_value(position) {} - -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) {} - function::~function() { switch (m_type) { case function_t::Normal: @@ -22,7 +16,7 @@ function::~function() { } function::function(function&& other) noexcept - : m_id(other.m_id), m_type(other.m_type), m_module(std::move(other.m_module)) { + : m_name(std::move(other.m_name)), m_type(other.m_type) { switch (m_type) { case function_t::Normal: { m_value.position = other.m_value.position; @@ -41,9 +35,8 @@ function::function(function&& other) noexcept function& function::operator=(function&& other) noexcept { if (this == &other) return *this; - m_id = other.m_id; - m_type = other.m_type; - m_module = std::move(other.m_module); + m_name = std::move(other.m_name); + m_type = other.m_type; switch (m_type) { case function_t::Normal: { m_value.position = other.m_value.position; diff --git a/furvm/src/main.cpp b/furvm/src/main.cpp index e2287ab..d3238f7 100644 --- a/furvm/src/main.cpp +++ b/furvm/src/main.cpp @@ -25,14 +25,13 @@ int main(void) { auto context = std::make_shared(); auto mainModule = context->emplace_module("main", s_bytecode.begin(), s_bytecode.end()); - - auto mainFunction = furvm::function::create(mainModule, 0); + mainModule->emplace_function("main", 0); std::ofstream file("./test.furm", std::ios::binary); furvm::serializer::serialize_module(file, mainModule); auto executor = furvm::executor::create(context); - executor->push_frame(mainFunction); + executor->push_frame(mainModule, 0); static constexpr std::size_t FPC = 3; // Frames per collection diff --git a/furvm/src/serializer.cpp b/furvm/src/serializer.cpp index 94a8a71..dc76b58 100644 --- a/furvm/src/serializer.cpp +++ b/furvm/src/serializer.cpp @@ -1,6 +1,8 @@ #include "furvm/serializer.hpp" #include "furvm/function.hpp" // IWYU pragma: keep +#include "furvm/fwd.hpp" +#include "furvm/module.hpp" // IWYU pragma: keep #include #include @@ -73,8 +75,9 @@ bool serializer::serialize_module(std::ostream& os, const mod_p& mod) { write_u32(os, VERSION); write_u32(os, mod->m_functions.size()); - for (const auto& func : mod->m_functions) { - write_u16(os, func->id()); + for (function_handle id = 0; id < static_cast(mod->m_functions.size()); ++id) { + const auto& func = mod->m_functions[id]; + write_u16(os, id); write_u8(os, static_cast(func->type())); switch (func->type()) { case function_t::Normal: {