195 lines
3.8 KiB
C
195 lines
3.8 KiB
C
#include <common/fzl_extern.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <vm/fzl_vm_reader.h>
|
|
#include <vm/internals/reader.h>
|
|
|
|
char reader_err[512];
|
|
|
|
fzl_vm_reader_t *fzl_vm_mkreader(char *filepath)
|
|
{
|
|
if (!filepath)
|
|
{
|
|
snprintf(reader_err, sizeof(reader_err),
|
|
"init error - filepath is not defined");
|
|
return NULL;
|
|
}
|
|
|
|
fzl_vm_reader_t *reader = malloc(sizeof(fzl_vm_reader_t));
|
|
if (!reader)
|
|
{
|
|
snprintf(reader_err, sizeof(reader_err),
|
|
"init error - couldn't allocate memory for reader");
|
|
return NULL;
|
|
}
|
|
|
|
memset(reader, 0, sizeof(fzl_vm_reader_t));
|
|
reader->filepath = filepath;
|
|
|
|
return reader;
|
|
}
|
|
|
|
void wr_validation_err(char *section)
|
|
{
|
|
if (internal_error[0])
|
|
snprintf(reader_err, sizeof(reader_err), "init error - section '%s': %s",
|
|
section, internal_error);
|
|
else
|
|
snprintf(reader_err, sizeof(reader_err),
|
|
"init error - section '%s' is not valid", section);
|
|
}
|
|
|
|
bool fzl_vm_read(fzl_vm_reader_t *reader)
|
|
{
|
|
if (!reader)
|
|
{
|
|
snprintf(reader_err, sizeof(reader_err),
|
|
"init error - reader is not provided");
|
|
return false;
|
|
}
|
|
|
|
FILE *fd = fopen(reader->filepath, "rb");
|
|
if (!fd)
|
|
{
|
|
snprintf(reader_err, sizeof(reader_err),
|
|
"init error - couldn't open file '%s'", reader->filepath);
|
|
return false;
|
|
}
|
|
|
|
bool result = vm_rd_header(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("header");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_sections_sz(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("sizes");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_consts(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("constants table");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_extern_libs(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("extern libs");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_extern_types(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("extern types");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_extern_fns(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("extern functions");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
result = vm_rd_ops(reader, fd);
|
|
if (!result)
|
|
{
|
|
wr_validation_err("opcodes");
|
|
fclose(fd);
|
|
return false;
|
|
}
|
|
|
|
fclose(fd);
|
|
|
|
return true;
|
|
}
|
|
|
|
char *fzl_vm_getreadererror() { return reader_err; }
|
|
|
|
void fzl_vm_freereader(fzl_vm_reader_t *reader)
|
|
{
|
|
if (!reader)
|
|
return;
|
|
|
|
if (reader->consts)
|
|
{
|
|
for (uint16_t i = 0; i < reader->consts_count; i++)
|
|
if (reader->consts[i].as.s.value)
|
|
free((void *)reader->consts[i].as.s.value);
|
|
|
|
free(reader->consts);
|
|
}
|
|
|
|
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)
|
|
{
|
|
for (uint16_t i = 0; i < reader->extern_types_count; i++)
|
|
{
|
|
free(reader->extern_types[i].name);
|
|
|
|
if (reader->extern_types[i].kind == FZL_EXTERN_KIND_STRUCT)
|
|
{
|
|
fzl_extern_struct_field_t *fields =
|
|
reader->extern_types[i].structure.fields;
|
|
for (uint16_t j = 0; j < reader->extern_types[i].structure.fields_count;
|
|
j++)
|
|
{
|
|
if (fields[j].name)
|
|
free(fields[j].name);
|
|
}
|
|
|
|
free(fields);
|
|
}
|
|
}
|
|
|
|
free(reader->extern_types);
|
|
}
|
|
|
|
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);
|
|
|
|
free(reader);
|
|
}
|