slige/runtime/vm.hpp

103 lines
2.3 KiB
C++
Raw Normal View History

2024-11-08 12:22:42 +01:00
#pragma once
#include "arch.hpp"
#include "value.hpp"
#include <cstddef>
#include <cstdint>
2024-11-11 15:31:54 +01:00
#include <format>
#include <iostream>
2024-11-08 12:22:42 +01:00
#include <vector>
namespace sliger {
class VM {
public:
2024-11-11 15:31:54 +01:00
VM(const std::vector<uint32_t>& program)
2024-11-08 12:22:42 +01:00
: program(program.data())
, program_size(program.size())
{
}
void run();
inline void step() { this->pc += 1; }
2024-11-11 15:31:54 +01:00
inline auto eat_op() -> Op
2024-11-08 12:22:42 +01:00
{
auto value = curr_as_op();
step();
return value;
}
inline auto curr_as_op() const -> Op
{
return static_cast<Op>(this->program[this->pc]);
}
2024-11-11 15:31:54 +01:00
inline auto eat_int32() -> int32_t
{
auto value = curr_as_int32();
step();
return value;
}
inline auto curr_as_int32() const -> int32_t
{
return static_cast<int32_t>(this->program[this->pc]);
}
inline auto eat_uint32() -> uint32_t
{
auto value = curr_as_uint32();
step();
return value;
}
inline auto curr_as_uint32() const -> uint32_t
{
return this->program[this->pc];
}
2024-11-08 12:22:42 +01:00
inline auto done() const -> bool { return this->pc >= this->program_size; }
2024-11-11 15:31:54 +01:00
inline auto fn_stack_at(size_t idx) -> Value&
{
return this->stack.at(this->bp + idx);
}
inline void assert_fn_stack_has(size_t count)
{
if (this->stack.size() - this->bp < count) {
std::cerr << std::format("stack underflow");
std::exit(1);
}
}
inline void assert_stack_has(size_t count)
{
if (this->stack.size() < count) {
std::cerr << std::format("stack underflow");
std::exit(1);
}
}
inline void stack_push(Value&& value) { this->stack.push_back(value); }
inline void stack_push(Value& value) { this->stack.push_back(value); }
inline auto stack_pop() -> Value
{
auto value = this->stack.at(this->stack.size() - 1);
this->stack.pop_back();
return value;
}
inline auto assert_program_has(size_t count)
{
if (this->pc + count >= program_size) {
std::cerr << std::format("stack underflow");
std::exit(1);
}
}
2024-11-08 12:22:42 +01:00
private:
uint32_t pc = 0;
2024-11-11 15:31:54 +01:00
uint32_t bp = 0;
const uint32_t* program;
2024-11-08 12:22:42 +01:00
size_t program_size;
std::vector<Value> stack;
std::vector<Value> pool_heap;
};
}