fixed some bugs and added VMState_InternalError

This commit is contained in:
Timerix 2024-11-16 23:09:33 +05:00
parent bc54f34a4d
commit a073d0ebd9
4 changed files with 32 additions and 18 deletions

View File

@ -20,6 +20,7 @@ void _VM_setError(VM* vm, const char* context, const char* format, ...){
strcpy(buf, "SPRINTF FAILED");
}
vm->error_message = buf;
vm->state = VMState_InternalError;
}
bool VM_loadProgram(VM* vm, u8* data, size_t size){
@ -43,22 +44,26 @@ i32 VM_executeProgram(VM* vm){
return -1;
}
vm->state = VMState_Executing;
vm->current_pos = 0;
while (vm->current_pos < vm->data_size){
u8 opcode = vm->data[vm->current_pos];
const Instruction* instr = Instruction_getFromOpcode(opcode);
// printfe("[at 0x%x] %02X %s\n", (u32)vm->current_pos, opcode, instr->name);
if(instr == NULL){
VM_setError(vm, "unknown opcode %02X", opcode);
return -1;
}
vm->current_pos++;
i32 bytes_read = instr->implementation(vm);
// internal error occured
if(bytes_read < 0)
return -1;
vm->current_pos += bytes_read;
if(vm->state == VMState_Exited)
break;
}
if(vm->state != VMState_Exited){

View File

@ -31,6 +31,7 @@ typedef enum VMState {
VMState_Initialized,
VMState_Executing,
VMState_Exited,
VMState_InternalError
} VMState;
typedef struct VM {
@ -45,7 +46,7 @@ typedef struct VM {
};
VMState state;
char* NULLABLE(error_message);
char* NULLABLE(error_message); // not null on if state == VMState_InternalError
u8* data;
size_t data_size;

View File

@ -10,6 +10,7 @@ i32 PUSH_impl(VM* vm){
vm->registers[dst_register_i].u32v = 0;
if(!VM_dataRead(vm, &vm->registers[dst_register_i].u32v, vm->current_pos, value_size))
return -1;
vm->current_pos += value_size;
return sizeof(dst_register_i) + sizeof(value_size) + value_size;
}

View File

@ -26,37 +26,37 @@ i32 main(const i32 argc, const char** argv){
}
else if(arg_is("-i") || arg_is("--image")){
if(++argi >= argc){
printfe("ERROR: no image file specified");
printfe("ERROR: no image file specified\n");
return 1;
}
filename = argv[argi];
}
else {
printfe("ERROR: unknown argument '%s'", argv[argi]);
printfe("ERROR: unknown argument '%s'\n", argv[argi]);
return 1;
}
}
if(filename == NULL){
printfe("ERROR: no arguments provided. Use --help to know more.");
printfe("ERROR: no arguments provided. Use --help to know more.\n");
return 1;
}
FILE* file = fopen(filename, "rb");
if(file == NULL){
printfe("ERROR: can't open file '%s'", filename);
printfe("ERROR: can't open file '%s'\n", filename);
return 1;
}
const size_t buffer_size = 1024*1024;
u8* buffer = malloc(buffer_size);
memset(buffer, 0, buffer_size);
u8* vm_memory = malloc(buffer_size);
memset(vm_memory, 0, buffer_size);
size_t bytes_read = fread(buffer, 1, buffer_size, file);
size_t bytes_read = fread(vm_memory, 1, buffer_size, file);
fclose(file);
if(bytes_read == (size_t)EOF){
printfe("ERROR: can't read file '%s'", filename);
free(buffer);
printfe("ERROR: can't read file '%s'\n", filename);
free(vm_memory);
return 1;
}
@ -64,15 +64,22 @@ i32 main(const i32 argc, const char** argv){
VM_init(&vm);
i32 exit_code = 1;
if(VM_loadProgram(&vm, buffer, bytes_read)){
if(VM_loadProgram(&vm, vm_memory, bytes_read)){
exit_code = VM_executeProgram(&vm);
}
if(vm.error_message != NULL){
printfe("VM ERROR: %s", vm.error_message);
if(vm.state == VMState_InternalError){
if(vm.error_message){
printfe("VM ERROR: %s\n", vm.error_message);
free(vm.error_message);
}
else printfe("VM ERROR: unknown error (error_message is null)\n");
}
free(buffer);
if(exit_code != 0){
printfe("program exited with code %i\n", exit_code);
}
free(vm_memory);
return exit_code;
}