From 4255c44a6a69a9b1a9928078e71fb583f2302f44 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Sat, 27 Apr 2024 17:43:24 +0530 Subject: [PATCH] Propagated change in prog_t into vm main now does error reporting for read errors --- vm/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- vm/runtime.c | 14 +++++++------- vm/struct.c | 8 ++++---- vm/struct.h | 4 ++-- 4 files changed, 60 insertions(+), 15 deletions(-) diff --git a/vm/main.c b/vm/main.c index 8b4d09c..31404cb 100644 --- a/vm/main.c +++ b/vm/main.c @@ -43,12 +43,57 @@ int main(int argc, char *argv[]) #endif FILE *fp = fopen(filename, "rb"); - prog_t *program = prog_read_file(fp); + darr_t fp_bytes = darr_read_file(fp); fclose(fp); + prog_t program = {0}; + size_t header_read = + prog_read_header(&program, fp_bytes.data, fp_bytes.available); + + if (!header_read) + { + fprintf(stderr, "[ERROR]: Could not deserialise program header in `%s`\n", + filename); + return 1; + } + // Ensure that we MUST have something to read + else if (program.count == 0) + return 0; + + // After reading header, we can allocate the buffer of instrutions + // exactly + program.instructions = calloc(program.count, sizeof(*program.instructions)); + size_t bytes_read = 0; + read_err_prog_t read_err = + prog_read_instructions(&program, &bytes_read, fp_bytes.data + header_read, + fp_bytes.available - header_read); + + if (bytes_read == 0) + { + fprintf(stderr, "[ERROR]:%s [%lu]:", filename, read_err.index); + switch (read_err.type) + { + case READ_ERR_INVALID_OPCODE: + fprintf(stderr, "INVALID_OPCODE"); + break; + case READ_ERR_OPERAND_NO_FIT: + fprintf(stderr, "OPERAND_NO_FIT"); + break; + case READ_ERR_EXPECTED_MORE: + fprintf(stderr, "EXPECTED_MORE"); + break; + case READ_ERR_END: + default: + fprintf(stderr, "UNKNOWN"); + break; + } + fprintf(stderr, "\n"); + return 1; + } + #if VERBOSE >= 1 printf("\t[" TERM_GREEN "SETUP" TERM_RESET "]: Read %lu instructions\n", - program->count); + program.count); #endif size_t stack_size = 256; diff --git a/vm/runtime.c b/vm/runtime.c index 553fa8e..3ad369c 100644 --- a/vm/runtime.c +++ b/vm/runtime.c @@ -66,10 +66,10 @@ static_assert(OP_PRINT_LONG - OP_PRINT_BYTE == 5, err_t vm_execute(vm_t *vm) { struct Program *prog = &vm->program; - prog_t *program_data = prog->data; - if (prog->ptr >= program_data->count) + prog_t program_data = prog->data; + if (prog->ptr >= program_data.count) return ERR_END_OF_PROGRAM; - inst_t instruction = program_data->instructions[prog->ptr]; + inst_t instruction = program_data.instructions[prog->ptr]; if (UNSIGNED_OPCODE_IS_TYPE(instruction.opcode, OP_PUSH)) { @@ -244,10 +244,10 @@ err_t vm_execute(vm_t *vm) err_t vm_execute_all(vm_t *vm) { struct Program *program = &vm->program; - const size_t count = program->data->count; + const size_t count = program->data.count; err_t err = ERR_OK; // Setup the initial address according to the program - program->ptr = program->data->start_address; + program->ptr = program->data.start_address; #if VERBOSE >= 1 size_t cycles = 0; #endif @@ -258,7 +258,7 @@ err_t vm_execute_all(vm_t *vm) size_t prev_cptr = 0; #endif while (program->ptr < count && - program->data->instructions[program->ptr].opcode != OP_HALT) + program->data.instructions[program->ptr].opcode != OP_HALT) { #if VERBOSE >= 2 fprintf(stdout, "[vm_execute_all]: Trace(Cycle %lu)\n", cycles); @@ -326,7 +326,7 @@ err_t vm_execute_all(vm_t *vm) err_t vm_jump(vm_t *vm, word_t w) { - if (w >= vm->program.data->count) + if (w >= vm->program.data.count) return ERR_INVALID_PROGRAM_ADDRESS; vm->program.ptr = w; return ERR_OK; diff --git a/vm/struct.c b/vm/struct.c index 89f67b7..2a49b39 100644 --- a/vm/struct.c +++ b/vm/struct.c @@ -22,7 +22,7 @@ void vm_load_stack(vm_t *vm, byte_t *bytes, size_t size) vm->stack.ptr = 0; } -void vm_load_program(vm_t *vm, prog_t *program) +void vm_load_program(vm_t *vm, prog_t program) { vm->program.ptr = 0; vm->program.data = program; @@ -95,7 +95,7 @@ void vm_stop(vm_t *vm) #endif free(vm->registers.data); - free(vm->program.data); + free(vm->program.data.instructions); free(vm->stack.data); heap_stop(&vm->heap); free(vm->call_stack.address_pointers); @@ -151,7 +151,7 @@ void vm_print_stack(vm_t *vm, FILE *fp) void vm_print_program(vm_t *vm, FILE *fp) { struct Program program = vm->program; - const size_t count = program.data->count; + const size_t count = program.data.count; fprintf(fp, "Program.max = %lu\nProgram.ptr = " "%lu\nProgram.instructions = [\n", @@ -168,7 +168,7 @@ void vm_print_program(vm_t *vm, FILE *fp) for (size_t i = beg; i < end; ++i) { fprintf(fp, "\t%lu: ", i); - inst_print(program.data->instructions[i], fp); + inst_print(program.data.instructions[i], fp); if (i == program.ptr) fprintf(fp, " <---"); fprintf(fp, "\n"); diff --git a/vm/struct.h b/vm/struct.h index ac17260..f4bbd58 100644 --- a/vm/struct.h +++ b/vm/struct.h @@ -29,7 +29,7 @@ struct Stack struct Program { - prog_t *data; + prog_t data; word_t ptr; }; @@ -53,7 +53,7 @@ typedef struct void vm_load_stack(vm_t *, byte_t *, size_t); void vm_load_registers(vm_t *, registers_t); void vm_load_heap(vm_t *, heap_t); -void vm_load_program(vm_t *, prog_t *); +void vm_load_program(vm_t *, prog_t); void vm_load_call_stack(vm_t *, word_t *, size_t); void vm_stop(vm_t *);