From 71b0b793af077ca757f9ce6775a5c63463f782a5 Mon Sep 17 00:00:00 2001 From: Aryadev Chavali Date: Thu, 25 Apr 2024 01:19:43 +0530 Subject: [PATCH] prog_t no longer has a header This "header" is now embedded directly into the struct. The semantic of a header never really matters in the actual runtime anyway, it's only for bytecode (de)serialising. --- lib/inst.c | 49 +++++++++++++++++++++---------------------------- lib/inst.h | 5 +++++ lib/prog.h | 5 ----- vm/runtime.c | 10 +++++----- 4 files changed, 31 insertions(+), 38 deletions(-) diff --git a/lib/inst.c b/lib/inst.c index 4219d79..3c8f3c5 100644 --- a/lib/inst.c +++ b/lib/inst.c @@ -436,61 +436,54 @@ void insts_write_bytecode_file(inst_t *instructions, size_t size, FILE *fp) free(darr.data); } -void prog_header_write_bytecode(prog_header_t header, darr_t *buffer) -{ - word start = word_htobc(header.start_address); - darr_append_bytes(buffer, (byte *)&start, sizeof(start)); - word count = word_htobc(header.count); - darr_append_bytes(buffer, (byte *)&count, sizeof(count)); -} - +static_assert(sizeof(prog_t) == WORD_SIZE * 2, + "prog_{write|read}_* is out of date"); void prog_write_bytecode(prog_t *program, darr_t *buffer) { - // Write program header - prog_header_write_bytecode(program->header, buffer); + // Write program header i.e. the start and count + word start = word_htobc(program->start_address); + darr_append_bytes(buffer, (byte *)&start, sizeof(start)); + word count = word_htobc(program->count); + darr_append_bytes(buffer, (byte *)&count, sizeof(count)); + // Write instructions - insts_write_bytecode(program->instructions, program->header.count, buffer); + insts_write_bytecode(program->instructions, program->count, buffer); } void prog_append_bytecode(prog_t *program, darr_t *buffer) { - insts_write_bytecode(program->instructions, program->header.count, buffer); -} - -prog_header_t prog_header_read_bytecode(darr_t *buffer) -{ - prog_header_t header = {0}; - header.start_address = convert_bytes_to_word(buffer->data + buffer->used); - buffer->used += sizeof(header.start_address); - header.count = convert_bytes_to_word(buffer->data + buffer->used); - buffer->used += sizeof(header.count); - return header; + insts_write_bytecode(program->instructions, program->count, buffer); } prog_t *prog_read_bytecode(darr_t *buffer) { // TODO: Error (not enough space for program header) - if ((buffer->available - buffer->used) < sizeof(prog_header_t)) + if ((buffer->available - buffer->used) < sizeof(prog_t)) return NULL; // Read program header - prog_header_t header = prog_header_read_bytecode(buffer); + word start_address = convert_bytes_to_word(buffer->data + buffer->used); + buffer->used += sizeof(start_address); + word count = convert_bytes_to_word(buffer->data + buffer->used); + buffer->used += sizeof(word); + // TODO: Error (not enough space for program instruction count) if ((buffer->available - buffer->used) < WORD_SIZE) return NULL; - prog_t *program = malloc(sizeof(*program) + (sizeof(inst_t) * header.count)); + prog_t *program = malloc(sizeof(*program) + (sizeof(inst_t) * count)); size_t i; - for (i = 0; i < header.count && (buffer->used < buffer->available); ++i) + for (i = 0; i < count && (buffer->used < buffer->available); ++i) program->instructions[i] = inst_read_bytecode(buffer); // TODO: Error (Expected more instructions) - if (i < header.count - 1) + if (i < count - 1) { free(program); return NULL; } - program->header = header; + program->start_address = start_address; + program->count = count; return program; } diff --git a/lib/inst.h b/lib/inst.h index fd694a9..239a968 100644 --- a/lib/inst.h +++ b/lib/inst.h @@ -29,6 +29,11 @@ const char *opcode_as_cstr(opcode_t); : ((OPCODE) == OP_TYPE##_HWORD) ? DATA_TYPE_HWORD \ : DATA_TYPE_WORD) +// OPCODE_DATA_TYPE: opcode_t -> data_type_t. data_type_t acts as +// a map between types and their offsets from the first type of +// instruction. That means for opcode_type A and data_type u, +// OP__BYTE + u = OP__. + void inst_print(inst_t, FILE *); size_t inst_bytecode_size(inst_t); diff --git a/lib/prog.h b/lib/prog.h index 9195b4e..c824476 100644 --- a/lib/prog.h +++ b/lib/prog.h @@ -165,11 +165,6 @@ typedef struct { word start_address; word count; -} prog_header_t; - -typedef struct -{ - prog_header_t header; inst_t instructions[]; } prog_t; diff --git a/vm/runtime.c b/vm/runtime.c index 6a91167..77cb8aa 100644 --- a/vm/runtime.c +++ b/vm/runtime.c @@ -59,7 +59,7 @@ err_t vm_execute(vm_t *vm) static_assert(NUMBER_OF_OPCODES == 98, "vm_execute: Out of date"); struct Program *prog = &vm->program; prog_t *program_data = prog->data; - if (prog->ptr >= program_data->header.count) + if (prog->ptr >= program_data->count) return ERR_END_OF_PROGRAM; inst_t instruction = program_data->instructions[prog->ptr]; @@ -279,10 +279,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->header.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->header.start_address; + program->ptr = program->data->start_address; #if VERBOSE >= 1 size_t cycles = 0; #endif @@ -495,7 +495,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->header.count; + const size_t count = program.data->count; fprintf(fp, "Program.max = %lu\nProgram.ptr = " "%lu\nProgram.instructions = [\n", @@ -607,7 +607,7 @@ void vm_print_all(vm_t *vm, FILE *fp) err_t vm_jump(vm_t *vm, word w) { - if (w >= vm->program.data->header.count) + if (w >= vm->program.data->count) return ERR_INVALID_PROGRAM_ADDRESS; vm->program.ptr = w; return ERR_OK;