first commit
This commit is contained in:
65
src/VM/VM.c
Normal file
65
src/VM/VM.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include "VM.h"
|
||||
#include "../instructions/instructions.h"
|
||||
|
||||
void VM_init(VM* vm){
|
||||
memset(vm, 0, sizeof(VM));
|
||||
vm->state = VMState_Initialized;
|
||||
}
|
||||
|
||||
bool VM_loadProgram(VM* vm, u8* data, size_t size){
|
||||
if(data == NULL){
|
||||
VM_setErrorMessage(vm, "[VM_loadProgram] can't load program because data == NULL");
|
||||
return false;
|
||||
}
|
||||
if(size == 0){
|
||||
VM_setErrorMessage(vm, "[VM_loadProgram] can't load program because size == 0");
|
||||
return false;
|
||||
}
|
||||
|
||||
vm->data = data;
|
||||
vm->data_size = size;
|
||||
return true;
|
||||
}
|
||||
|
||||
i32 VM_executeProgram(VM* vm){
|
||||
if(vm->data == NULL){
|
||||
VM_setErrorMessage(vm, "[VM_executeProgram] data is null");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t pos = 0;
|
||||
while (pos < vm->data_size){
|
||||
u8 opcode = vm->data[pos];
|
||||
|
||||
const Instruction* instr = Instruction_getFromOpcode(opcode);
|
||||
if(instr == NULL){
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
pos++;
|
||||
i32 bytes_read = instr->implementation(vm, pos);
|
||||
if(bytes_read < 0)
|
||||
return -1;
|
||||
|
||||
pos += bytes_read;
|
||||
}
|
||||
|
||||
if(vm->state != VMState_Exited){
|
||||
VM_setErrorMessage(vm, "[%p] unexpected end of program", (void*)pos);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// exit code of the program should be in ax register
|
||||
return vm->ax.i32v;
|
||||
}
|
||||
|
||||
bool VM_dataRead(VM* vm, void* dst, size_t pos, size_t size){
|
||||
if(pos + size >= vm->data_size){
|
||||
VM_setErrorMessage(vm, "[%p] unexpected end of data", (void*)vm->data_size);
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(dst, vm->data + pos, size);
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user