#include #include #include #include #include #include #include #include #include #include // Read external functions definitions bool vm_rd_extern_fns(fzl_vm_reader_t *reader, FILE *fd) { if (!reader || !fd) return false; uint16_t fns_count = reader->extern_fns_count; if (!fns_count) return true; 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; }