wip: working on extern in VM
- Feat: add usage of vm reader instead of old way in vm.c - Ref: update debug opcodes printing
This commit is contained in:
@@ -165,9 +165,11 @@ if (NOT FZL_SKIP_VM)
|
||||
src/vm/reader/vm_rd_extern_libs.c
|
||||
src/vm/reader/vm_rd_extern_types.c
|
||||
src/vm/reader/vm_rd_header.c
|
||||
src/vm/reader/vm_rd_ops.c
|
||||
src/vm/reader/vm_rd_sections_sz.c
|
||||
src/vm/fzl_vm.c
|
||||
src/vm/fzl_vm_env.c
|
||||
src/vm/fzl_vm_reader.c
|
||||
src/vm/fzl_vm_debug.c
|
||||
src/vm/main.c)
|
||||
|
||||
|
||||
+3
-13
@@ -1,26 +1,16 @@
|
||||
#ifndef FZL_VM_H
|
||||
#define FZL_VM_H
|
||||
|
||||
#include <common/fzl_value.h>
|
||||
#include <compiler/utils/fzl_const_pool.h> // NOTE: move outside compiler scope to common
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <vm/fzl_vm_env.h>
|
||||
#include <vm/fzl_vm_extern.h>
|
||||
#include <vm/fzl_vm_object.h>
|
||||
#include <vm/fzl_vm_reader.h>
|
||||
|
||||
// VM descriptor
|
||||
typedef struct
|
||||
{
|
||||
fzl_const_t *consts;
|
||||
size_t consts_count;
|
||||
|
||||
fzl_vm_extern_t *externs;
|
||||
size_t externs_count;
|
||||
|
||||
uint64_t *ops;
|
||||
size_t ops_count;
|
||||
fzl_vm_reader_t *reader;
|
||||
|
||||
size_t ip;
|
||||
|
||||
@@ -41,7 +31,7 @@ typedef struct
|
||||
} fzl_vm_t;
|
||||
|
||||
// Allocate FZL VM
|
||||
fzl_vm_t *fzl_mkvm(const char *filepath);
|
||||
fzl_vm_t *fzl_mkvm(fzl_vm_reader_t *reader);
|
||||
|
||||
// Load and run code
|
||||
int fzl_vm_run(fzl_vm_t *vm);
|
||||
|
||||
+11
-91
@@ -12,6 +12,7 @@
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/fzl_vm_env.h>
|
||||
#include <vm/fzl_vm_object.h>
|
||||
#include <vm/fzl_vm_reader.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
char last_err[256];
|
||||
@@ -20,8 +21,14 @@ size_t total_jmp_on_same = 0;
|
||||
|
||||
static char *expect_hdr = "FZL\0\2";
|
||||
|
||||
fzl_vm_t *fzl_mkvm(const char *filepath)
|
||||
fzl_vm_t *fzl_mkvm(fzl_vm_reader_t *reader)
|
||||
{
|
||||
if (!reader)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "reader is not provided");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fzl_vm_t *vm = malloc(sizeof(fzl_vm_t));
|
||||
if (!vm)
|
||||
{
|
||||
@@ -30,86 +37,7 @@ fzl_vm_t *fzl_mkvm(const char *filepath)
|
||||
}
|
||||
|
||||
memset(vm, 0, sizeof(fzl_vm_t));
|
||||
|
||||
FILE *fd = fopen(filepath, "rb");
|
||||
if (!fd)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "failed to open file '%s'", filepath);
|
||||
free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char hdr[5];
|
||||
fread(hdr, sizeof(char), 5,
|
||||
fd); // NOTE: add red bytes check (also for freads below)
|
||||
if (memcmp(hdr, expect_hdr, 5) != 0)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "magic check error");
|
||||
fclose(fd);
|
||||
free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t consts_count, ops_count;
|
||||
fread(&consts_count, sizeof(size_t), 1, fd);
|
||||
fread(&ops_count, sizeof(size_t), 1, fd);
|
||||
// TODO: read externs count
|
||||
|
||||
if (ops_count < 1)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "there is nothing to do (0 ops)");
|
||||
fclose(fd);
|
||||
free(vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (consts_count > 0)
|
||||
{
|
||||
vm->consts_count = consts_count;
|
||||
vm->consts = malloc(consts_count * sizeof(fzl_value_t));
|
||||
|
||||
for (size_t i = 0; i < consts_count; i++)
|
||||
{
|
||||
fzl_consttype_t type;
|
||||
fread(&type, sizeof(fzl_consttype_t), 1, fd);
|
||||
|
||||
if (type == FZL_CONSTTYPE_STRING)
|
||||
{
|
||||
size_t length;
|
||||
char *chars;
|
||||
|
||||
fread(&length, sizeof(size_t), 1, fd);
|
||||
|
||||
chars = malloc(length * sizeof(char) + 1);
|
||||
fread(chars, sizeof(char), length, fd);
|
||||
chars[length] = 0;
|
||||
|
||||
vm->consts[i] = (fzl_const_t){
|
||||
.type = type, .as.string.length = length, .as.string.chars = chars};
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(fd);
|
||||
free(vm->consts);
|
||||
free(vm);
|
||||
snprintf(last_err, sizeof(last_err), "unknown const type at index %ld",
|
||||
i);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vm->ops_count = ops_count;
|
||||
vm->ops = malloc(ops_count * sizeof(uint64_t));
|
||||
for (size_t i = 0; i < ops_count; i++)
|
||||
{
|
||||
uint64_t op;
|
||||
fread(&op, sizeof(uint64_t), 1, fd);
|
||||
vm->ops[i] = op;
|
||||
}
|
||||
|
||||
// TODO: read externs
|
||||
fclose(fd);
|
||||
vm->reader = reader;
|
||||
|
||||
return vm;
|
||||
}
|
||||
@@ -229,9 +157,9 @@ int fzl_vm_run(fzl_vm_t *vm)
|
||||
|
||||
vm->ip = 0;
|
||||
int result = 0;
|
||||
while (vm->ip < vm->ops_count)
|
||||
while (vm->ip < vm->reader->ops_count)
|
||||
{
|
||||
fzl_opcode_t opcode = vm->ops[vm->ip];
|
||||
fzl_opcode_t opcode = vm->reader->ops[vm->ip];
|
||||
size_t op_group = (opcode >> 16) & 0xFF;
|
||||
size_t op_fnnum = (opcode & 0xFF);
|
||||
|
||||
@@ -265,13 +193,5 @@ void fzl_freevm(fzl_vm_t *vm)
|
||||
while (vm->etop > 0)
|
||||
fzl_freeenv(vm->estack[--vm->etop]);
|
||||
|
||||
for (size_t i = 0; i < vm->consts_count; i++)
|
||||
{
|
||||
if (vm->consts[i].type == FZL_CONSTTYPE_STRING)
|
||||
free((void *)vm->consts[i].as.string.chars);
|
||||
}
|
||||
|
||||
free(vm->consts);
|
||||
free(vm->ops);
|
||||
free(vm);
|
||||
}
|
||||
|
||||
+21
-20
@@ -1,4 +1,5 @@
|
||||
#include <common/fzl_opcodes.h>
|
||||
#include <common/fzl_value.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
@@ -8,36 +9,36 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
if (!vm)
|
||||
return;
|
||||
|
||||
if (vm->ops_count < 1)
|
||||
if (vm->reader->ops_count < 1)
|
||||
{
|
||||
printf("no opcodes\n");
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < vm->ops_count; i++)
|
||||
for (size_t i = 0; i < vm->reader->ops_count; i++)
|
||||
{
|
||||
printf("%04ld: ", i);
|
||||
|
||||
switch (vm->ops[i])
|
||||
switch (vm->reader->ops[i])
|
||||
{
|
||||
case FZL_OPCODE_STORE_LOCAL:
|
||||
{
|
||||
size_t depth = vm->ops[++i];
|
||||
size_t slot = vm->ops[++i];
|
||||
size_t depth = vm->reader->ops[++i];
|
||||
size_t slot = vm->reader->ops[++i];
|
||||
printf("STORE_LOCAL D=%zu S=%zu\n", depth, slot);
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_LOAD_LOCAL:
|
||||
{
|
||||
size_t depth = vm->ops[++i];
|
||||
size_t slot = vm->ops[++i];
|
||||
size_t depth = vm->reader->ops[++i];
|
||||
size_t slot = vm->reader->ops[++i];
|
||||
printf("LOAD_LOCAL D=%zu S=%zu\n", depth, slot);
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_BUILD_STR:
|
||||
printf("BUILD_STR %zu\n", vm->ops[++i]);
|
||||
printf("BUILD_STR %zu\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_DEREFERENCE:
|
||||
@@ -65,20 +66,20 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_ALLOC_OBJECT:
|
||||
printf("ALLOC_OBJECT: %lu fields\n", vm->ops[++i]);
|
||||
printf("ALLOC_OBJECT: %lu fields\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_GET_FIELD:
|
||||
printf("GET_FIELD #%lu\n", vm->ops[++i]);
|
||||
printf("GET_FIELD #%lu\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_SET_FIELD:
|
||||
printf("SET_FIELD #%lu\n", vm->ops[++i]);
|
||||
printf("SET_FIELD #%lu\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_CALL:
|
||||
{
|
||||
size_t ip = vm->ops[++i];
|
||||
size_t ip = vm->reader->ops[++i];
|
||||
printf("CALL IP: %lu\n", ip);
|
||||
break;
|
||||
}
|
||||
@@ -89,22 +90,22 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
|
||||
case FZL_OPCODE_LOADCONST:
|
||||
{
|
||||
size_t const_n = vm->ops[++i];
|
||||
fzl_const_t c = vm->consts[const_n];
|
||||
printf("LOADCONST #%lu ('%s')\n", const_n, c.as.string.chars);
|
||||
size_t const_n = vm->reader->ops[++i];
|
||||
fzl_value_t c = vm->reader->consts[const_n];
|
||||
printf("LOADCONST #%lu ('%s')\n", const_n, c.as.s.value);
|
||||
break;
|
||||
}
|
||||
|
||||
case FZL_OPCODE_CALL_BUILTIN:
|
||||
printf("CALL_BUILTIN #%lu\n", vm->ops[++i]);
|
||||
printf("CALL_BUILTIN #%lu\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_PUSHNUM:
|
||||
printf("PUSHNUM %lu\n", vm->ops[++i]);
|
||||
printf("PUSHNUM %lu\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_PUSHBOOL:
|
||||
printf("PUSHBOOL %s\n", vm->ops[++i] ? "true" : "false");
|
||||
printf("PUSHBOOL %s\n", vm->reader->ops[++i] ? "true" : "false");
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_MK_ENVTABLE:
|
||||
@@ -177,11 +178,11 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_JZ:
|
||||
printf("JZ IP: %ld\n", vm->ops[++i]);
|
||||
printf("JZ IP: %ld\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
|
||||
case FZL_OPCODE_JMP:
|
||||
printf("JMP IP: %ld\n", vm->ops[++i]);
|
||||
printf("JMP IP: %ld\n", vm->reader->ops[++i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,8 @@ bool fzl_vm_read(fzl_vm_reader_t *reader)
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
|
||||
@@ -132,8 +132,8 @@ int op_write(fzl_vm_t *vm)
|
||||
|
||||
int op_load_local(fzl_vm_t *vm)
|
||||
{
|
||||
size_t depth = vm->ops[++vm->ip];
|
||||
size_t slot = vm->ops[++vm->ip];
|
||||
size_t depth = vm->reader->ops[++vm->ip];
|
||||
size_t slot = vm->reader->ops[++vm->ip];
|
||||
|
||||
if (depth >= vm->etop)
|
||||
{
|
||||
@@ -168,8 +168,8 @@ int op_store_local(fzl_vm_t *vm)
|
||||
|
||||
fzl_value_t value = vm->dstack[--vm->dtop];
|
||||
|
||||
size_t depth = vm->ops[++vm->ip];
|
||||
size_t slot = vm->ops[++vm->ip];
|
||||
size_t depth = vm->reader->ops[++vm->ip];
|
||||
size_t slot = vm->reader->ops[++vm->ip];
|
||||
|
||||
if (depth >= vm->etop)
|
||||
{
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
// Jump at specified address
|
||||
int op_jmp(fzl_vm_t *vm)
|
||||
{
|
||||
if (vm->ops_count <= vm->ip)
|
||||
if (vm->reader->ops_count <= vm->ip)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "runtime error - expected JMP addr");
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t jmp_ip = vm->ops[++vm->ip];
|
||||
uint64_t jmp_ip = vm->reader->ops[++vm->ip];
|
||||
if (!vm->allow_infinite)
|
||||
{
|
||||
if (jmp_ip == last_jmp_ip)
|
||||
@@ -46,7 +47,7 @@ int op_jz(fzl_vm_t *vm)
|
||||
}
|
||||
|
||||
fzl_value_t jzval = vm->dstack[--vm->dtop];
|
||||
uint64_t jzip = vm->ops[++vm->ip] - 1;
|
||||
uint64_t jzip = vm->reader->ops[++vm->ip] - 1;
|
||||
if (jzval.as.b == 0)
|
||||
vm->ip = jzip;
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
// Call function (store return address and jump into function init)
|
||||
int op_call(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t ip = vm->ops[++vm->ip];
|
||||
uint64_t ip = vm->reader->ops[++vm->ip];
|
||||
vm->cstack[vm->ctop++] = vm->ip;
|
||||
vm->ip = ip - 1;
|
||||
return 0;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
@@ -57,7 +58,7 @@ void escape_recursive(fzl_vm_env_t *current, fzl_vm_env_t *parent,
|
||||
// Allocate specified count of fields and create object
|
||||
int op_alloc_object(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t values_count = vm->ops[++vm->ip];
|
||||
uint64_t values_count = vm->reader->ops[++vm->ip];
|
||||
fzl_vm_object_t *obj = malloc(sizeof(fzl_vm_object_t));
|
||||
|
||||
if (values_count < 1)
|
||||
@@ -94,7 +95,7 @@ int op_get_field(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t field_slot = vm->ops[++vm->ip];
|
||||
uint64_t field_slot = vm->reader->ops[++vm->ip];
|
||||
fzl_value_t val = vm->dstack[--vm->dtop];
|
||||
if (val.type != FZL_TYPE_OBJECT)
|
||||
{
|
||||
@@ -130,7 +131,7 @@ int op_set_field(fzl_vm_t *vm)
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t field_slot = vm->ops[++vm->ip];
|
||||
uint64_t field_slot = vm->reader->ops[++vm->ip];
|
||||
fzl_value_t objval = vm->dstack[--vm->dtop];
|
||||
fzl_value_t wrval = vm->dstack[--vm->dtop];
|
||||
if (objval.type != FZL_TYPE_OBJECT)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
#include <common/fzl_builtins.h>
|
||||
#include <common/fzl_value.h>
|
||||
#include <stdio.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
// Load constant onto stack
|
||||
int op_loadconst(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t cn = vm->ops[++vm->ip];
|
||||
if (vm->consts_count <= cn)
|
||||
uint64_t cn = vm->reader->ops[++vm->ip];
|
||||
if (vm->reader->consts_count <= cn)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err), "runtime error - unknown const");
|
||||
print_err_data(vm);
|
||||
return -1;
|
||||
}
|
||||
fzl_const_t c = vm->consts[cn];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_STRING,
|
||||
.as.s.length = c.as.string.length,
|
||||
.as.s.value = c.as.string.chars};
|
||||
vm->dstack[vm->dtop++] = vm->reader->consts[cn];
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -23,7 +22,7 @@ int op_loadconst(fzl_vm_t *vm)
|
||||
// Call builtin function
|
||||
int op_call_builtin(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t fn_id = vm->ops[++vm->ip];
|
||||
uint64_t fn_id = vm->reader->ops[++vm->ip];
|
||||
if (fn_id == FZL_BUILTIN_PRINTLINE)
|
||||
{
|
||||
fzl_value_t arg = vm->dstack[--vm->dtop];
|
||||
@@ -64,7 +63,7 @@ int op_call_builtin(fzl_vm_t *vm)
|
||||
// Push number onto stack
|
||||
int op_pushnum(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t push_n = vm->ops[++vm->ip];
|
||||
uint64_t push_n = vm->reader->ops[++vm->ip];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_UINT, .as.u = push_n};
|
||||
return 0;
|
||||
}
|
||||
@@ -72,7 +71,7 @@ int op_pushnum(fzl_vm_t *vm)
|
||||
// Push boolean onto stack
|
||||
int op_pushbool(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t push_b = vm->ops[++vm->ip];
|
||||
uint64_t push_b = vm->reader->ops[++vm->ip];
|
||||
vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = push_b};
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#include <common/fzl_extern.h>
|
||||
#include <common/fzl_types.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
@@ -8,7 +10,7 @@ char build_result[512];
|
||||
// Build string from specified count using stack values
|
||||
int op_build_str(fzl_vm_t *vm)
|
||||
{
|
||||
uint64_t n = vm->ops[++vm->ip];
|
||||
uint64_t n = vm->reader->ops[++vm->ip];
|
||||
if (vm->dtop < n)
|
||||
{
|
||||
snprintf(last_err, sizeof(last_err),
|
||||
@@ -34,6 +36,19 @@ int op_build_str(fzl_vm_t *vm)
|
||||
|
||||
switch (val.type)
|
||||
{
|
||||
case FZL_TYPE_HANDLE:
|
||||
snprintf(temp, sizeof(temp), "pointer<%p>", val.as.obj);
|
||||
strcpy(build_result + gi, temp);
|
||||
gi += strlen(temp);
|
||||
break;
|
||||
|
||||
case FZL_TYPE_STRUCT:
|
||||
snprintf(temp, sizeof(temp), "field(values: %zu)",
|
||||
((fzl_extern_type_t *)val.as.obj)->structure.fields_count);
|
||||
strcpy(build_result + gi, temp);
|
||||
gi += strlen(temp);
|
||||
break;
|
||||
|
||||
case FZL_TYPE_UINT:
|
||||
snprintf(temp, sizeof(temp), "%zu", val.as.u);
|
||||
strcpy(build_result + gi, temp);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/internals/opcode.h>
|
||||
|
||||
+20
-1
@@ -6,6 +6,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <vm/fzl_vm.h>
|
||||
#include <vm/fzl_vm_reader.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -113,10 +114,28 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
fzl_vm_t *vm = fzl_mkvm(args->filepath);
|
||||
fzl_vm_reader_t *reader = fzl_vm_mkreader(args->filepath);
|
||||
if (!reader)
|
||||
{
|
||||
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_vm_getreadererror());
|
||||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool result = fzl_vm_read(reader);
|
||||
if (!result)
|
||||
{
|
||||
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_vm_getreadererror());
|
||||
fzl_vm_freereader(reader);
|
||||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fzl_vm_t *vm = fzl_mkvm(reader);
|
||||
if (!vm)
|
||||
{
|
||||
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_vm_geterror());
|
||||
fzl_vm_freereader(reader);
|
||||
free(args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <vm/internals/reader.h>
|
||||
|
||||
// Read opcodes
|
||||
bool vm_rd_ops(fzl_vm_reader_t *reader, FILE *fd)
|
||||
{
|
||||
if (!reader || !fd)
|
||||
return false;
|
||||
|
||||
size_t ops_count = reader->ops_count;
|
||||
if (!ops_count)
|
||||
return false;
|
||||
|
||||
reader->ops = malloc(sizeof(size_t) * ops_count);
|
||||
if (!reader->ops)
|
||||
return false;
|
||||
|
||||
for (size_t i = 0; i < ops_count; i++)
|
||||
{
|
||||
size_t opcode;
|
||||
if (!vm_rd_word(fd, 1, &opcode))
|
||||
return false;
|
||||
|
||||
reader->ops[i] = opcode;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user