From 989fcb71995e33da6474ecb7f4d19dc2670900a5 Mon Sep 17 00:00:00 2001 From: CHatingPython Date: Tue, 11 Aug 2026 16:17:24 +0200 Subject: [PATCH] refactor(furvm): use new instructions in executor --- furvm/include/furvm/module.hpp | 9 +++++- furvm/src/executor.cpp | 52 +++++++++++----------------------- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/furvm/include/furvm/module.hpp b/furvm/include/furvm/module.hpp index cc46d45..532e81d 100644 --- a/furvm/include/furvm/module.hpp +++ b/furvm/include/furvm/module.hpp @@ -2,6 +2,7 @@ #define FURVM_MODULE_HPP #include "furlang/utility/hash.hpp" +#include "furlang/view.hpp" #include "furvm/function.hpp" #include "furvm/fwd.hpp" #include "furvm/handle.hpp" @@ -195,7 +196,7 @@ public: * * @return A constant reference to the bytecode. */ - constexpr const bytecode_t& bytecode() const { return m_bytecode; } + furlang::view bytecode_view() const { return { m_bytecode.data(), m_bytecode.size() }; } public: /** * @brief Emplaces a function in the module's function container. @@ -284,6 +285,10 @@ public: m_functionMap.erase(it); } } + + const handle_container& functions() const { return m_functions; } + + const auto& function_map() const { return m_functionMap; } public: template void set_native_function(NameFwd&& name, Func&& func) { @@ -341,6 +346,8 @@ public: void erase_type(Args&&... args) { m_types.erase(std::forward(args)...); } + + const handle_container& types() const { return m_types; } public: /** * @brief Prints the module in a bytecode form to an output stream. diff --git a/furvm/src/executor.cpp b/furvm/src/executor.cpp index 56e6a79..4d812de 100644 --- a/furvm/src/executor.cpp +++ b/furvm/src/executor.cpp @@ -1,5 +1,6 @@ #include "furvm/executor.hpp" +#include "furlang/view.hpp" #include "furvm/context.hpp" // IWYU pragma: keep #include "furvm/exceptions.hpp" #include "furvm/function.hpp" // IWYU pragma: keep @@ -131,45 +132,36 @@ void executor::step() { struct frame& frame = m_frames.top(); - instruction_t instr = static_cast((*frame.mod).byte_at(frame.position++)); - switch (instr) { + instruction instr{}; + frame.position += instr.read(frame.mod->bytecode_view().subview(frame.position)); + switch (instr.type) { case instruction_t::NoOperation: break; case instruction_t::PushS8: { push_thing({ (struct thing_type){ thing_type::S8 }, m_context->thing_alloc() })->get() = - static_cast(frame.mod->byte_at(frame.position++)); + instr.arg.s8; } break; case instruction_t::PushU8: { push_thing({ (struct thing_type){ thing_type::U8 }, m_context->thing_alloc() })->get() = - static_cast(frame.mod->byte_at(frame.position++)); + instr.arg.u8; } break; case instruction_t::PushS16: { - thing_type::u16 value = frame.mod->byte_at(frame.position++); - value |= static_cast(frame.mod->byte_at(frame.position++) << 8); push_thing({ (struct thing_type){ thing_type::S16 }, m_context->thing_alloc() })->get() = - static_cast(value); + instr.arg.s16; } break; case instruction_t::PushU16: { - thing_type::u16 value = frame.mod->byte_at(frame.position++); - value |= static_cast(frame.mod->byte_at(frame.position++) << 8); push_thing({ (struct thing_type){ thing_type::U16 }, m_context->thing_alloc() })->get() = - value; + instr.arg.u16; } break; case instruction_t::PushS32: { push_thing({ (struct thing_type){ thing_type::S32 }, m_context->thing_alloc() })->get() = - static_cast(frame.mod->byte_at(frame.position++)); + instr.arg.s8; // NOLINT } break; case instruction_t::PushU32: { push_thing({ (struct thing_type){ thing_type::U32 }, m_context->thing_alloc() })->get() = - static_cast(frame.mod->byte_at(frame.position++)); + static_cast(instr.arg.u8); } break; case instruction_t::Array: { - mod_type_id typeId = static_cast(frame.mod->byte_at(frame.position)) | - (static_cast(frame.mod->byte_at(frame.position + 1)) << 8) | - (static_cast(frame.mod->byte_at(frame.position + 2)) << 16) | - (static_cast(frame.mod->byte_at(frame.position + 3)) << 24); - frame.position += 4; - - const auto& type = *mod_to_thing_type(frame.mod, *frame.mod->type_at(typeId)); + const auto& type = *mod_to_thing_type(frame.mod, *frame.mod->type_at(instr.arg.u32)); if (type.type != thing_type::Array || type.value.array.type == nullptr || type.value.array.type == &type) throw std::runtime_error("invalid array type"); @@ -304,31 +296,19 @@ void executor::step() { length->get() = thing->length(); } break; case instruction_t::Load: { - variable_t variable = static_cast(frame.mod->byte_at(frame.position)) | - (static_cast(frame.mod->byte_at(frame.position + 1)) << 8); - frame.position += 2; - push_thing(load_thing(variable)); + push_thing(load_thing(instr.arg.u16)); } break; case instruction_t::Store: { - variable_t variable = static_cast(frame.mod->byte_at(frame.position)) | - (static_cast(frame.mod->byte_at(frame.position + 1)) << 8); - frame.position += 2; - store_thing(variable, std::move(pop_thing())); + store_thing(instr.arg.u16, std::move(pop_thing())); } break; case instruction_t::Call: { - function_id funcId = static_cast(frame.mod->byte_at(frame.position)) | - (static_cast(frame.mod->byte_at(frame.position + 1)) << 8); - frame.position += 2; - push_frame(frame.mod, *frame.mod->function_at(funcId)); + push_frame(frame.mod, *frame.mod->function_at(instr.arg.u16)); } break; case instruction_t::Jump: { - std::int8_t offset = static_cast(frame.mod->byte_at(frame.position++)); - frame.position += offset; + frame.position += instr.arg.s8; } break; case instruction_t::JumpNotZero: { - byte offset = frame.mod->byte_at(frame.position++); - auto cond = pop_thing(); - if (cond->integer() != 0) frame.position += (std::int8_t)offset; + if (pop_thing()->integer() != 0) frame.position += instr.arg.s8; } break; case instruction_t::Return: { pop_frame();