71 lines
1.1 KiB
C
71 lines
1.1 KiB
C
|
#include "vm.h"
|
||
|
#include "lib/commons.h"
|
||
|
|
||
|
void vm_init(vm_t* vm)
|
||
|
{
|
||
|
assert(vm);
|
||
|
|
||
|
vm->pc = 0;
|
||
|
vm->bp = 0;
|
||
|
vm->sp = 0;
|
||
|
}
|
||
|
|
||
|
void vm_free(vm_t* vm)
|
||
|
{
|
||
|
assert(vm);
|
||
|
}
|
||
|
|
||
|
size_t vm_stack_str(vm_t* vm, char* buffer, size_t size)
|
||
|
{
|
||
|
assert(vm);
|
||
|
assert(buffer);
|
||
|
|
||
|
size_t sz = 0;
|
||
|
|
||
|
for (size_t i=0; i<vm->sp; i++)
|
||
|
{
|
||
|
sz += snprintf(buffer + sz, size - sz, "| %d |\n", vm->stack[vm->sp - 1 - i]);
|
||
|
}
|
||
|
|
||
|
return sz;
|
||
|
}
|
||
|
|
||
|
void vm_exec_mod(vm_t* vm, mod_t* mod)
|
||
|
{
|
||
|
assert(vm);
|
||
|
vm->pc = 0;
|
||
|
|
||
|
while (vm->pc < mod->program.size)
|
||
|
{
|
||
|
vm_exec_instr(vm, mod->program.ops[vm->pc],
|
||
|
mod->program.params[vm->pc]);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void vm_exec_instr(vm_t* vm, Opcode op, param_t param)
|
||
|
{
|
||
|
assert(vm);
|
||
|
|
||
|
switch (op)
|
||
|
{
|
||
|
|
||
|
case OP_PUSH: {
|
||
|
if (vm->sp + 1 >= RZ_STACK_LIMIT)
|
||
|
{
|
||
|
fprintf(stderr, "Stack overflow\n");
|
||
|
abort();
|
||
|
}
|
||
|
|
||
|
vm->stack[vm->sp] = param;
|
||
|
vm->sp++;
|
||
|
vm->pc++;
|
||
|
} break;
|
||
|
|
||
|
default: {
|
||
|
fprintf(stderr, "Cannot execute unknown opcode '%s'.\n",
|
||
|
OpcodeStr[op]);
|
||
|
abort();
|
||
|
};
|
||
|
}
|
||
|
}
|