feat(furvm): add call instruction

This commit is contained in:
2026-06-11 15:09:30 +02:00
parent 6ca5fcc995
commit 3f6d0adef6
5 changed files with 33 additions and 5 deletions
+1 -1
View File
@@ -14,7 +14,7 @@ enum class function_t : std::uint8_t {
Native, /**< A native function implemented through furvm API. */ Native, /**< A native function implemented through furvm API. */
}; };
using native_function = std::function<void(const executor_p&)>; using native_function = std::function<void(executor&)>;
class function { class function {
private: private:
+7
View File
@@ -65,6 +65,13 @@ enum class instruction_t : byte {
*/ */
Mod, Mod,
/**
* @brief Calls a function.
*
* Calls a function denoted by next two bytes in little-endian from current frame's module.
*/
Call,
/** /**
* @brief Pops the current call frame. * @brief Pops the current call frame.
*/ */
+8
View File
@@ -51,6 +51,14 @@ 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); }
public:
/**
* @brief Returns a function from this module.
*
* @param id Id of the function.
* @return The function.
*/
constexpr const function_p& function_at(function_handle id) const { return m_functions.at(id); }
private: private:
module_handle m_id; module_handle m_id;
bytecode_t m_bytecode; bytecode_t m_bytecode;
+11
View File
@@ -109,6 +109,17 @@ void executor::step() {
auto lhs = pop_thing(); auto lhs = pop_thing();
push_thing(lhs % rhs); push_thing(lhs % rhs);
} break; } break;
case instruction_t::Call: {
function_handle funcId = static_cast<std::uint16_t>(frame.mod->byte(frame.position)) |
(static_cast<std::uint16_t>(frame.mod->byte(frame.position + 1)) << 8);
frame.position += 2;
const function_p& function = frame.mod->function_at(funcId);
switch (function->type()) {
case function_t::Normal: push_frame(function); break;
case function_t::Native: function->native()(*this); break;
}
} break;
case instruction_t::Return: { case instruction_t::Return: {
pop_frame(); pop_frame();
if (m_frames.empty()) m_flags = m_flags | executor_flags::Done; if (m_frames.empty()) m_flags = m_flags | executor_flags::Done;
+6 -4
View File
@@ -11,17 +11,19 @@
#include <iostream> #include <iostream>
#include <memory> #include <memory>
static constexpr std::array<furvm::byte, 6> s_bytecode = { static constexpr std::array<furvm::byte, 8> s_bytecode = {
furvm::byte(furvm::instruction_t::PushB2I), furvm::byte(furvm::instruction_t::PushB2I),
67, 67,
furvm::byte(furvm::instruction_t::Clone), furvm::byte(furvm::instruction_t::Clone),
furvm::byte(furvm::instruction_t::Add), furvm::byte(furvm::instruction_t::Add),
furvm::byte(furvm::instruction_t::Drop), furvm::byte(furvm::instruction_t::Call),
1,
0,
furvm::byte(furvm::instruction_t::Return), furvm::byte(furvm::instruction_t::Return),
}; };
void print(const furvm::executor_p& exec) { void print(furvm::executor& exec) {
std::cout << exec->pop_thing()->int32() << '\n'; std::cout << exec.pop_thing()->int32() << '\n';
} }
int main(void) { int main(void) {