70 lines
1.4 KiB
C++
70 lines
1.4 KiB
C++
#include "vm.hh"
|
|
|
|
#include "vm_exceptions.hh"
|
|
|
|
namespace tyche {
|
|
|
|
void VM::load_bytecode(ByteArray const& ba)
|
|
{
|
|
FunctionId f_id = code_.import_bytecode(ba);
|
|
stack_.push(Value::CreateFunctionId(f_id));
|
|
}
|
|
|
|
void VM::call(size_t n_params)
|
|
{
|
|
// TODO - parameters
|
|
|
|
Value f = stack_.pop();
|
|
if (f.type() != Type::Function)
|
|
throw VMTypeError(Type::Function, f.type());
|
|
|
|
loc_.emplace(f.as_function_id(), 0);
|
|
stack_.push_fp();
|
|
run_until_return();
|
|
stack_.pop_fp();
|
|
loc_.pop();
|
|
}
|
|
|
|
int32_t VM::to_integer(int index) const
|
|
{
|
|
Value i = stack_.at(index);
|
|
assert_type(i, Type::Integer);
|
|
return i.as_integer();
|
|
}
|
|
|
|
void VM::push_integer(int32_t value)
|
|
{
|
|
stack_.push(Value::CreateInteger(value));
|
|
}
|
|
|
|
void VM::run_until_return()
|
|
{
|
|
size_t level = stack_.fp_level();
|
|
|
|
while (stack_.fp_level() >= level)
|
|
step();
|
|
}
|
|
|
|
void VM::step()
|
|
{
|
|
Operation op = code_.operation(loc_.top());
|
|
switch (op.instruction) {
|
|
case Instruction::PushInt8:
|
|
case Instruction::PushInt16:
|
|
case Instruction::PushInt32:
|
|
push_integer(op.operator_);
|
|
break;
|
|
default:
|
|
throw VMInvalidOpcode((uint8_t) op.instruction);
|
|
}
|
|
loc_.top() = op.next_location;
|
|
}
|
|
|
|
void VM::assert_type(Value const& val, Type type)
|
|
{
|
|
if (val.type() != type)
|
|
throw VMTypeError(type, val.type());
|
|
}
|
|
|
|
} // tyche
|