diff --git a/include/vm/internals/opcode.h b/include/vm/internals/opcode.h index 7dec73f..adc5d8b 100644 --- a/include/vm/internals/opcode.h +++ b/include/vm/internals/opcode.h @@ -7,7 +7,7 @@ // Opcode handler descriptor typedef int (*opcode_handler)(fzl_vm_t *); -extern char last_err[256]; +extern char last_err[512]; extern size_t last_jmp_ip; extern size_t total_jmp_on_same; diff --git a/src/vm/fzl_vm.c b/src/vm/fzl_vm.c index b3d2d0c..6bc7184 100644 --- a/src/vm/fzl_vm.c +++ b/src/vm/fzl_vm.c @@ -12,7 +12,7 @@ #include #include -char last_err[256]; +char last_err[512]; char internal_error[256]; size_t last_jmp_ip = 0; size_t total_jmp_on_same = 0; diff --git a/src/vm/fzl_vm_debug.c b/src/vm/fzl_vm_debug.c index 0b3334e..54fe3eb 100644 --- a/src/vm/fzl_vm_debug.c +++ b/src/vm/fzl_vm_debug.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include diff --git a/src/vm/fzl_vm_reader.c b/src/vm/fzl_vm_reader.c index 037c467..e49b486 100644 --- a/src/vm/fzl_vm_reader.c +++ b/src/vm/fzl_vm_reader.c @@ -8,7 +8,7 @@ #include #include -char reader_err[256]; +char reader_err[512]; fzl_vm_reader_t *fzl_vm_mkreader(char *filepath) { @@ -138,7 +138,12 @@ void fzl_vm_freereader(fzl_vm_reader_t *reader) } if (reader->extern_libs) + { + for (uint16_t i = 0; i < reader->extern_libs_count; i++) + free(reader->extern_libs[i]); + free(reader->extern_libs); + } if (reader->extern_types) { @@ -156,6 +161,8 @@ void fzl_vm_freereader(fzl_vm_reader_t *reader) if (fields[j].name) free(fields[j].name); } + + free(fields); } } @@ -163,7 +170,22 @@ void fzl_vm_freereader(fzl_vm_reader_t *reader) } if (reader->extern_fns) + { + for (uint16_t i = 0; i < reader->extern_fns_count; i++) + { + fzl_extern_fn_t *fn = &reader->extern_fns[i]; + if (fn->used_name) + free(fn->used_name); + + if (fn->symbol_name) + free(fn->symbol_name); + + if (fn->args_count > 0) + free(fn->args); + } + free(reader->extern_fns); + } if (reader->ops) free(reader->ops); diff --git a/src/vm/main.c b/src/vm/main.c index 2b55e0a..1cea6f8 100644 --- a/src/vm/main.c +++ b/src/vm/main.c @@ -155,6 +155,7 @@ int main(int argc, char **argv) printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, err); free(args); + fzl_vm_freereader(reader); fzl_freevm(vm); return -1; } diff --git a/src/vm/reader/vm_rd_extern_fns.c b/src/vm/reader/vm_rd_extern_fns.c index 1975eec..bb0f792 100644 --- a/src/vm/reader/vm_rd_extern_fns.c +++ b/src/vm/reader/vm_rd_extern_fns.c @@ -1,6 +1,11 @@ +#include +#include #include +#include #include #include +#include +#include #include #include @@ -14,7 +19,216 @@ bool vm_rd_extern_fns(fzl_vm_reader_t *reader, FILE *fd) if (!fns_count) return true; - // TODO: fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuck + reader->extern_fns = malloc(sizeof(fzl_extern_fn_t) * fns_count); + if (!reader->extern_fns) + { + snprintf(internal_error, sizeof(internal_error), "out of memory"); + return false; + } + + memset(reader->extern_fns, 0, sizeof(fzl_extern_fn_t) * fns_count); + + for (uint16_t i = 0; i < fns_count; i++) + { + fzl_extern_fn_t *fn = &reader->extern_fns[i]; + + uint16_t lib_slot; + if (!vm_rd_u16(fd, 1, &lib_slot)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u lib slot", i); + return false; + } + + fn->lib_slot = lib_slot; + + uint16_t used_name_sz; + if (!vm_rd_u16(fd, 1, &used_name_sz)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u used name size", i); + return false; + } + + char used_name_buf[256]; + memset(used_name_buf, 0, sizeof(used_name_buf)); + if (!vm_rd_char(fd, used_name_sz, used_name_buf)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u used name", i); + return false; + } + + char *val = malloc(sizeof(char) * used_name_sz + 1); + if (!val) + { + snprintf(internal_error, sizeof(internal_error), + "out of memory on fn #%u used name allocation", i); + return false; + } + + memset(val, 0, sizeof(char) * used_name_sz + 1); + memcpy(val, used_name_buf, sizeof(char) * used_name_sz); + fn->used_name = val; + + char has_symbol_name; + if (!vm_rd_char(fd, 1, &has_symbol_name)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u symbol name existing flag", i); + return false; + } + + if ((bool)has_symbol_name) + { + if (!vm_rd_u16(fd, 1, &used_name_sz)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u symbol name size", i); + return false; + } + + if (!vm_rd_char(fd, used_name_sz, used_name_buf)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u symbol name", i); + return false; + } + + char *symval = malloc(sizeof(char) * used_name_sz + 1); + if (!symval) + { + snprintf(internal_error, sizeof(internal_error), + "out of memory on fn #%u symbol name allocation", i); + return false; + } + + memset(symval, 0, sizeof(char) * used_name_sz + 1); + memcpy(symval, used_name_buf, sizeof(char) * used_name_sz); + fn->symbol_name = symval; + } + + char has_return; + if (!vm_rd_char(fd, 1, &has_return)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u return existing flag", i); + return false; + } + + fn->has_return = (bool)has_return; + if ((bool)has_return) + { + char is_primitive; + if (!vm_rd_char(fd, 1, &is_primitive)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u return type primitivity flag", i); + return false; + } + + fn->ret_type.is_primitive = (bool)is_primitive; + + if (is_primitive) + { + char primitive; + if (!vm_rd_char(fd, 1, &primitive)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u return primitive", i); + return false; + } + + fn->ret_type.primitive = (fzl_type_t)primitive; + } + else + { + uint16_t type_slot; + if (!vm_rd_u16(fd, 1, &type_slot)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u return type slot", i); + return false; + } + + fn->ret_type.type_slot = (size_t)type_slot; + } + } + + uint16_t args_count; + if (!vm_rd_u16(fd, 1, &args_count)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u arguments count", i); + return false; + } + + fn->args_count = (size_t)args_count; + if (args_count > 0) + { + fzl_extern_arg_t *args = malloc(sizeof(fzl_extern_arg_t) * args_count); + if (!args) + { + snprintf(internal_error, sizeof(internal_error), + "out of memory on fn #%u arguments array allocation", i); + return false; + } + + memset(args, 0, sizeof(fzl_extern_arg_t) * args_count); + fn->args = args; + + for (uint16_t j = 0; j < args_count; j++) + { + fzl_extern_arg_t *arg = &args[j]; + + char arg_is_out; + if (!vm_rd_char(fd, 1, &arg_is_out)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u arg #%u out flag", i, j); + return false; + } + + arg->is_out = (bool)arg_is_out; + + char arg_is_primitive; + if (!vm_rd_char(fd, 1, &arg_is_primitive)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u arg #%u return type primitivity flag", + i, j); + return false; + } + + arg->type.is_primitive = (bool)arg_is_primitive; + + if (arg_is_primitive) + { + char primitive; + if (!vm_rd_char(fd, 1, &primitive)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u #%u return primitive", i, j); + return false; + } + + arg->type.primitive = (fzl_type_t)primitive; + } + else + { + uint16_t type_slot; + if (!vm_rd_u16(fd, 1, &type_slot)) + { + snprintf(internal_error, sizeof(internal_error), + "failed to read fn #%u #%u return type slot", i, j); + return false; + } + + arg->type.type_slot = (size_t)type_slot; + } + } + } + } return true; } diff --git a/src/vm/reader/vm_rd_extern_libs.c b/src/vm/reader/vm_rd_extern_libs.c index a6698db..66087d0 100644 --- a/src/vm/reader/vm_rd_extern_libs.c +++ b/src/vm/reader/vm_rd_extern_libs.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -25,14 +26,14 @@ bool vm_rd_extern_libs(fzl_vm_reader_t *reader, FILE *fd) memset(reader->extern_libs, 0, sizeof(char *) * libs_count); - bool ok = false; - uint16_t name_sz = 0; + bool ok = false; + size_t name_sz = 0; char name[256]; for (uint16_t i = 0; i < libs_count; i++) { memset(name, 0, sizeof(name)); - ok = vm_rd_u16(fd, 1, &name_sz); + ok = vm_rd_word(fd, 1, &name_sz); if (!ok || name_sz < 1) { snprintf(internal_error, sizeof(internal_error), diff --git a/src/vm/reader/vm_rd_extern_types.c b/src/vm/reader/vm_rd_extern_types.c index f1a1728..891c9a5 100644 --- a/src/vm/reader/vm_rd_extern_types.c +++ b/src/vm/reader/vm_rd_extern_types.c @@ -158,7 +158,7 @@ bool vm_rd_extern_types(fzl_vm_reader_t *reader, FILE *fd) for (uint16_t j = 0; j < fields_count; j++) { - fzl_extern_struct_field_t *f = &fields[i]; + fzl_extern_struct_field_t *f = &fields[j]; char has_name; if (!vm_rd_char(fd, 1, &has_name)) diff --git a/src/vm/reader/vm_rd_ops.c b/src/vm/reader/vm_rd_ops.c index 30126bb..ed9ce8d 100644 --- a/src/vm/reader/vm_rd_ops.c +++ b/src/vm/reader/vm_rd_ops.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -22,7 +23,7 @@ bool vm_rd_ops(fzl_vm_reader_t *reader, FILE *fd) for (size_t i = 0; i < ops_count; i++) { - size_t opcode; + size_t opcode = 0; if (!vm_rd_word(fd, 1, &opcode)) { snprintf(internal_error, sizeof(internal_error),