fixed some bugs and added VMState_InternalError
This commit is contained in:
parent
bc54f34a4d
commit
a073d0ebd9
@ -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){
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
33
src/main.c
33
src/main.c
@ -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){
|
||||||
|
printfe("VM ERROR: %s\n", vm.error_message);
|
||||||
free(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user