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

View File

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

View File

@ -10,6 +10,7 @@ i32 PUSH_impl(VM* vm){
vm->registers[dst_register_i].u32v = 0; vm->registers[dst_register_i].u32v = 0;
if(!VM_dataRead(vm, &vm->registers[dst_register_i].u32v, vm->current_pos, value_size)) if(!VM_dataRead(vm, &vm->registers[dst_register_i].u32v, vm->current_pos, value_size))
return -1; return -1;
vm->current_pos += value_size;
return sizeof(dst_register_i) + sizeof(value_size) + 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")){ else if(arg_is("-i") || arg_is("--image")){
if(++argi >= argc){ if(++argi >= argc){
printfe("ERROR: no image file specified"); printfe("ERROR: no image file specified\n");
return 1; return 1;
} }
filename = argv[argi]; filename = argv[argi];
} }
else { else {
printfe("ERROR: unknown argument '%s'", argv[argi]); printfe("ERROR: unknown argument '%s'\n", argv[argi]);
return 1; return 1;
} }
} }
if(filename == NULL){ 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; return 1;
} }
FILE* file = fopen(filename, "rb"); FILE* file = fopen(filename, "rb");
if(file == NULL){ if(file == NULL){
printfe("ERROR: can't open file '%s'", filename); printfe("ERROR: can't open file '%s'\n", filename);
return 1; return 1;
} }
const size_t buffer_size = 1024*1024; const size_t buffer_size = 1024*1024;
u8* buffer = malloc(buffer_size); u8* vm_memory = malloc(buffer_size);
memset(buffer, 0, 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); fclose(file);
if(bytes_read == (size_t)EOF){ if(bytes_read == (size_t)EOF){
printfe("ERROR: can't read file '%s'", filename); printfe("ERROR: can't read file '%s'\n", filename);
free(buffer); free(vm_memory);
return 1; return 1;
} }
@ -64,15 +64,22 @@ i32 main(const i32 argc, const char** argv){
VM_init(&vm); VM_init(&vm);
i32 exit_code = 1; i32 exit_code = 1;
if(VM_loadProgram(&vm, buffer, bytes_read)){ if(VM_loadProgram(&vm, vm_memory, bytes_read)){
exit_code = VM_executeProgram(&vm); exit_code = VM_executeProgram(&vm);
} }
if(vm.error_message != NULL){ if(vm.state == VMState_InternalError){
printfe("VM ERROR: %s", vm.error_message); if(vm.error_message){
free(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; return exit_code;
} }