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:
samsonium
2026-11-05 23:23:38 +03:00
parent 1db42c1e8e
commit d95ff88b66
19 changed files with 133 additions and 146 deletions
+2
View File
@@ -165,9 +165,11 @@ if (NOT FZL_SKIP_VM)
src/vm/reader/vm_rd_extern_libs.c src/vm/reader/vm_rd_extern_libs.c
src/vm/reader/vm_rd_extern_types.c src/vm/reader/vm_rd_extern_types.c
src/vm/reader/vm_rd_header.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/reader/vm_rd_sections_sz.c
src/vm/fzl_vm.c src/vm/fzl_vm.c
src/vm/fzl_vm_env.c src/vm/fzl_vm_env.c
src/vm/fzl_vm_reader.c
src/vm/fzl_vm_debug.c src/vm/fzl_vm_debug.c
src/vm/main.c) src/vm/main.c)
+3 -13
View File
@@ -1,26 +1,16 @@
#ifndef FZL_VM_H #ifndef FZL_VM_H
#define 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 <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <vm/fzl_vm_env.h> #include <vm/fzl_vm_env.h>
#include <vm/fzl_vm_extern.h> #include <vm/fzl_vm_reader.h>
#include <vm/fzl_vm_object.h>
// VM descriptor // VM descriptor
typedef struct typedef struct
{ {
fzl_const_t *consts; fzl_vm_reader_t *reader;
size_t consts_count;
fzl_vm_extern_t *externs;
size_t externs_count;
uint64_t *ops;
size_t ops_count;
size_t ip; size_t ip;
@@ -41,7 +31,7 @@ typedef struct
} fzl_vm_t; } fzl_vm_t;
// Allocate FZL VM // 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 // Load and run code
int fzl_vm_run(fzl_vm_t *vm); int fzl_vm_run(fzl_vm_t *vm);
+11 -91
View File
@@ -12,6 +12,7 @@
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/fzl_vm_env.h> #include <vm/fzl_vm_env.h>
#include <vm/fzl_vm_object.h> #include <vm/fzl_vm_object.h>
#include <vm/fzl_vm_reader.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
char last_err[256]; char last_err[256];
@@ -20,8 +21,14 @@ size_t total_jmp_on_same = 0;
static char *expect_hdr = "FZL\0\2"; 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)); fzl_vm_t *vm = malloc(sizeof(fzl_vm_t));
if (!vm) if (!vm)
{ {
@@ -30,86 +37,7 @@ fzl_vm_t *fzl_mkvm(const char *filepath)
} }
memset(vm, 0, sizeof(fzl_vm_t)); memset(vm, 0, sizeof(fzl_vm_t));
vm->reader = reader;
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);
return vm; return vm;
} }
@@ -229,9 +157,9 @@ int fzl_vm_run(fzl_vm_t *vm)
vm->ip = 0; vm->ip = 0;
int result = 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_group = (opcode >> 16) & 0xFF;
size_t op_fnnum = (opcode & 0xFF); size_t op_fnnum = (opcode & 0xFF);
@@ -265,13 +193,5 @@ void fzl_freevm(fzl_vm_t *vm)
while (vm->etop > 0) while (vm->etop > 0)
fzl_freeenv(vm->estack[--vm->etop]); 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); free(vm);
} }
+21 -20
View File
@@ -1,4 +1,5 @@
#include <common/fzl_opcodes.h> #include <common/fzl_opcodes.h>
#include <common/fzl_value.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
@@ -8,36 +9,36 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
if (!vm) if (!vm)
return; return;
if (vm->ops_count < 1) if (vm->reader->ops_count < 1)
{ {
printf("no opcodes\n"); printf("no opcodes\n");
return; 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); printf("%04ld: ", i);
switch (vm->ops[i]) switch (vm->reader->ops[i])
{ {
case FZL_OPCODE_STORE_LOCAL: case FZL_OPCODE_STORE_LOCAL:
{ {
size_t depth = vm->ops[++i]; size_t depth = vm->reader->ops[++i];
size_t slot = vm->ops[++i]; size_t slot = vm->reader->ops[++i];
printf("STORE_LOCAL D=%zu S=%zu\n", depth, slot); printf("STORE_LOCAL D=%zu S=%zu\n", depth, slot);
break; break;
} }
case FZL_OPCODE_LOAD_LOCAL: case FZL_OPCODE_LOAD_LOCAL:
{ {
size_t depth = vm->ops[++i]; size_t depth = vm->reader->ops[++i];
size_t slot = vm->ops[++i]; size_t slot = vm->reader->ops[++i];
printf("LOAD_LOCAL D=%zu S=%zu\n", depth, slot); printf("LOAD_LOCAL D=%zu S=%zu\n", depth, slot);
break; break;
} }
case FZL_OPCODE_BUILD_STR: case FZL_OPCODE_BUILD_STR:
printf("BUILD_STR %zu\n", vm->ops[++i]); printf("BUILD_STR %zu\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_DEREFERENCE: case FZL_OPCODE_DEREFERENCE:
@@ -65,20 +66,20 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
break; break;
case FZL_OPCODE_ALLOC_OBJECT: 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; break;
case FZL_OPCODE_GET_FIELD: case FZL_OPCODE_GET_FIELD:
printf("GET_FIELD #%lu\n", vm->ops[++i]); printf("GET_FIELD #%lu\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_SET_FIELD: case FZL_OPCODE_SET_FIELD:
printf("SET_FIELD #%lu\n", vm->ops[++i]); printf("SET_FIELD #%lu\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_CALL: case FZL_OPCODE_CALL:
{ {
size_t ip = vm->ops[++i]; size_t ip = vm->reader->ops[++i];
printf("CALL IP: %lu\n", ip); printf("CALL IP: %lu\n", ip);
break; break;
} }
@@ -89,22 +90,22 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
case FZL_OPCODE_LOADCONST: case FZL_OPCODE_LOADCONST:
{ {
size_t const_n = vm->ops[++i]; size_t const_n = vm->reader->ops[++i];
fzl_const_t c = vm->consts[const_n]; fzl_value_t c = vm->reader->consts[const_n];
printf("LOADCONST #%lu ('%s')\n", const_n, c.as.string.chars); printf("LOADCONST #%lu ('%s')\n", const_n, c.as.s.value);
break; break;
} }
case FZL_OPCODE_CALL_BUILTIN: case FZL_OPCODE_CALL_BUILTIN:
printf("CALL_BUILTIN #%lu\n", vm->ops[++i]); printf("CALL_BUILTIN #%lu\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_PUSHNUM: case FZL_OPCODE_PUSHNUM:
printf("PUSHNUM %lu\n", vm->ops[++i]); printf("PUSHNUM %lu\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_PUSHBOOL: case FZL_OPCODE_PUSHBOOL:
printf("PUSHBOOL %s\n", vm->ops[++i] ? "true" : "false"); printf("PUSHBOOL %s\n", vm->reader->ops[++i] ? "true" : "false");
break; break;
case FZL_OPCODE_MK_ENVTABLE: case FZL_OPCODE_MK_ENVTABLE:
@@ -177,11 +178,11 @@ void fzl_vm_print_ops(fzl_vm_t *vm)
break; break;
case FZL_OPCODE_JZ: case FZL_OPCODE_JZ:
printf("JZ IP: %ld\n", vm->ops[++i]); printf("JZ IP: %ld\n", vm->reader->ops[++i]);
break; break;
case FZL_OPCODE_JMP: case FZL_OPCODE_JMP:
printf("JMP IP: %ld\n", vm->ops[++i]); printf("JMP IP: %ld\n", vm->reader->ops[++i]);
break; break;
} }
} }
+2
View File
@@ -112,6 +112,8 @@ bool fzl_vm_read(fzl_vm_reader_t *reader)
return false; return false;
} }
fclose(fd);
return true; return true;
} }
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+4 -4
View File
@@ -132,8 +132,8 @@ int op_write(fzl_vm_t *vm)
int op_load_local(fzl_vm_t *vm) int op_load_local(fzl_vm_t *vm)
{ {
size_t depth = vm->ops[++vm->ip]; size_t depth = vm->reader->ops[++vm->ip];
size_t slot = vm->ops[++vm->ip]; size_t slot = vm->reader->ops[++vm->ip];
if (depth >= vm->etop) if (depth >= vm->etop)
{ {
@@ -168,8 +168,8 @@ int op_store_local(fzl_vm_t *vm)
fzl_value_t value = vm->dstack[--vm->dtop]; fzl_value_t value = vm->dstack[--vm->dtop];
size_t depth = vm->ops[++vm->ip]; size_t depth = vm->reader->ops[++vm->ip];
size_t slot = vm->ops[++vm->ip]; size_t slot = vm->reader->ops[++vm->ip];
if (depth >= vm->etop) if (depth >= vm->etop)
{ {
+4 -3
View File
@@ -1,16 +1,17 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
// Jump at specified address // Jump at specified address
int op_jmp(fzl_vm_t *vm) 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"); snprintf(last_err, sizeof(last_err), "runtime error - expected JMP addr");
return -1; return -1;
} }
uint64_t jmp_ip = vm->ops[++vm->ip]; uint64_t jmp_ip = vm->reader->ops[++vm->ip];
if (!vm->allow_infinite) if (!vm->allow_infinite)
{ {
if (jmp_ip == last_jmp_ip) 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]; 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) if (jzval.as.b == 0)
vm->ip = jzip; vm->ip = jzip;
+2 -1
View File
@@ -1,10 +1,11 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
// Call function (store return address and jump into function init) // Call function (store return address and jump into function init)
int op_call(fzl_vm_t *vm) 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->cstack[vm->ctop++] = vm->ip;
vm->ip = ip - 1; vm->ip = ip - 1;
return 0; return 0;
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+4 -3
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <vm/fzl_vm.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 // Allocate specified count of fields and create object
int op_alloc_object(fzl_vm_t *vm) 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)); fzl_vm_object_t *obj = malloc(sizeof(fzl_vm_object_t));
if (values_count < 1) if (values_count < 1)
@@ -94,7 +95,7 @@ int op_get_field(fzl_vm_t *vm)
return -1; 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]; fzl_value_t val = vm->dstack[--vm->dtop];
if (val.type != FZL_TYPE_OBJECT) if (val.type != FZL_TYPE_OBJECT)
{ {
@@ -130,7 +131,7 @@ int op_set_field(fzl_vm_t *vm)
return -1; 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 objval = vm->dstack[--vm->dtop];
fzl_value_t wrval = vm->dstack[--vm->dtop]; fzl_value_t wrval = vm->dstack[--vm->dtop];
if (objval.type != FZL_TYPE_OBJECT) if (objval.type != FZL_TYPE_OBJECT)
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+8 -9
View File
@@ -1,21 +1,20 @@
#include <common/fzl_builtins.h> #include <common/fzl_builtins.h>
#include <common/fzl_value.h>
#include <stdio.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
// Load constant onto stack // Load constant onto stack
int op_loadconst(fzl_vm_t *vm) int op_loadconst(fzl_vm_t *vm)
{ {
uint64_t cn = vm->ops[++vm->ip]; uint64_t cn = vm->reader->ops[++vm->ip];
if (vm->consts_count <= cn) if (vm->reader->consts_count <= cn)
{ {
snprintf(last_err, sizeof(last_err), "runtime error - unknown const"); snprintf(last_err, sizeof(last_err), "runtime error - unknown const");
print_err_data(vm); print_err_data(vm);
return -1; return -1;
} }
fzl_const_t c = vm->consts[cn]; vm->dstack[vm->dtop++] = vm->reader->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};
return 0; return 0;
} }
@@ -23,7 +22,7 @@ int op_loadconst(fzl_vm_t *vm)
// Call builtin function // Call builtin function
int op_call_builtin(fzl_vm_t *vm) 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) if (fn_id == FZL_BUILTIN_PRINTLINE)
{ {
fzl_value_t arg = vm->dstack[--vm->dtop]; fzl_value_t arg = vm->dstack[--vm->dtop];
@@ -64,7 +63,7 @@ int op_call_builtin(fzl_vm_t *vm)
// Push number onto stack // Push number onto stack
int op_pushnum(fzl_vm_t *vm) 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}; vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_UINT, .as.u = push_n};
return 0; return 0;
} }
@@ -72,7 +71,7 @@ int op_pushnum(fzl_vm_t *vm)
// Push boolean onto stack // Push boolean onto stack
int op_pushbool(fzl_vm_t *vm) 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}; vm->dstack[vm->dtop++] = (fzl_value_t){.type = FZL_TYPE_BOOL, .as.b = push_b};
return 0; return 0;
} }
+16 -1
View File
@@ -1,3 +1,5 @@
#include <common/fzl_extern.h>
#include <common/fzl_types.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
@@ -8,7 +10,7 @@ char build_result[512];
// Build string from specified count using stack values // Build string from specified count using stack values
int op_build_str(fzl_vm_t *vm) 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) if (vm->dtop < n)
{ {
snprintf(last_err, sizeof(last_err), snprintf(last_err, sizeof(last_err),
@@ -34,6 +36,19 @@ int op_build_str(fzl_vm_t *vm)
switch (val.type) 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: case FZL_TYPE_UINT:
snprintf(temp, sizeof(temp), "%zu", val.as.u); snprintf(temp, sizeof(temp), "%zu", val.as.u);
strcpy(build_result + gi, temp); strcpy(build_result + gi, temp);
+1
View File
@@ -1,3 +1,4 @@
#include <stdio.h>
#include <string.h> #include <string.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/internals/opcode.h> #include <vm/internals/opcode.h>
+20 -1
View File
@@ -6,6 +6,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <vm/fzl_vm.h> #include <vm/fzl_vm.h>
#include <vm/fzl_vm_reader.h>
typedef struct typedef struct
{ {
@@ -113,10 +114,28 @@ int main(int argc, char **argv)
return 0; 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) if (!vm)
{ {
printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_vm_geterror()); printf("%sError%s: %s\n", FZL_CERROR, FZL_CRST, fzl_vm_geterror());
fzl_vm_freereader(reader);
free(args); free(args);
return -1; return -1;
} }
+30
View File
@@ -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;
}