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_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
@@ -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
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,6 +112,8 @@ bool fzl_vm_read(fzl_vm_reader_t *reader)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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>
|
||||||
|
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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,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,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,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,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,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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,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
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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