diff --git a/stage0/spl_cli.c b/stage0/spl_cli.c index 446cc46..21655cb 100644 --- a/stage0/spl_cli.c +++ b/stage0/spl_cli.c @@ -189,7 +189,7 @@ typedef struct { static const char *fn_name_at(spl_prog_t *prog, usize ip) { for (usize i = 0; i < vec_size(prog->funcs); i++) { - spl_func_t *f = &vec_at(prog->funcs, i); + spl_vm_func_t *f = &vec_at(prog->funcs, i); if (ip >= f->address && ip < f->address + f->ninsns) return f->name ? f->name : "?"; } @@ -201,7 +201,7 @@ static void cur_func_bounds(spl_prog_t *prog, usize ip, usize *start, usize *end *start = 0; *end = vec_size(prog->insns); for (usize i = 0; i < vec_size(prog->funcs); i++) { - spl_func_t *f = &vec_at(prog->funcs, i); + spl_vm_func_t *f = &vec_at(prog->funcs, i); if (ip >= f->address && ip < f->address + f->ninsns) { *start = f->address; *end = f->address + f->ninsns; @@ -211,9 +211,9 @@ static void cur_func_bounds(spl_prog_t *prog, usize ip, usize *start, usize *end } /* 格式化一条指令(不含行号前缀) */ -static void fmt_insn(const spl_ins_t *ins, char *buf, size_t n) { - snprintf(buf, n, "%-11s %-5s %zu", spl_opcode_name(ins->opcode), spl_type_tag_name(ins->type), - ins->imm); +static void fmt_insn(const spl_vm_ins_t *ins, char *buf, size_t n) { + snprintf(buf, n, "%-11s %-5s %zu", spl_vm_opcode_name(ins->opcode), + spl_vm_type_kind_name(ins->type), ins->imm); } static void dbg_show_location(dbg_t *d) { @@ -539,7 +539,7 @@ static int cmd_x(dbg_t *d, const char *args) { return 0; } unsigned char *sbase = (unsigned char *)d->vm->stacks.data; - usize slen = d->vm->config.max_stack_depth * sizeof(spl_val_t); + usize slen = d->vm->config.max_stack_depth * sizeof(spl_vm_val_t); printf(" addr=%#llx stack=[%p,+%zu) in=%d\n", addr, sbase, slen, addr >= (uintptr_t)sbase && addr < (uintptr_t)(sbase + slen)); unsigned char *p = (unsigned char *)(uintptr_t)addr; @@ -567,7 +567,7 @@ static int cmd_p(dbg_t *d, const char *args) { printf(" no variable '%s' in %s\n", args, fn); return 0; } - spl_val_t *addr = (spl_val_t *)((char *)&d->vm->stacks.data[d->vm->fp] + v->offset); + spl_vm_val_t *addr = (spl_vm_val_t *)((char *)&d->vm->stacks.data[d->vm->fp] + v->offset); printf(" %s = %zu (0x%zx) @ fp+%zu\n", v->name, *addr, *addr, v->offset); d->last_ptr = (usize)*addr; /* 供 x 无参重读 */ return 0; diff --git a/stage0/spl_disasm.c b/stage0/spl_disasm.c index de59f66..f4a4cd1 100644 --- a/stage0/spl_disasm.c +++ b/stage0/spl_disasm.c @@ -25,7 +25,7 @@ int main(int argc, const char **argv) { if (vec_size(prog.funcs) > 0) { printf(";; --- functions ---\n"); for (usize i = 0; i < vec_size(prog.funcs); i++) { - spl_func_t *f = &vec_at(prog.funcs, i); + spl_vm_func_t *f = &vec_at(prog.funcs, i); printf(" %s nargs=%zu ninsns=%zu addr=%zu\n", f->name ? f->name : "(anon)", f->nargs, f->ninsns, f->address); } @@ -35,7 +35,7 @@ int main(int argc, const char **argv) { if (vec_size(prog.natives) > 0) { printf(";; --- natives ---\n"); for (int i = 0; i < (int)vec_size(prog.natives); i++) { - spl_native_t *n = &vec_at(prog.natives, i); + spl_vm_native_t *n = &vec_at(prog.natives, i); printf(" %s\n", n->name ? n->name : "(anon)"); } printf("\n"); @@ -51,10 +51,10 @@ int main(int argc, const char **argv) { printf(";; --- instructions ---\n"); for (usize i = 0; i < vec_size(prog.insns); i++) { - spl_ins_t *ins = &vec_at(prog.insns, i); - printf("%4zd: %s", i, spl_opcode_name((spl_opcode_t)ins->opcode)); + spl_vm_ins_t *ins = &vec_at(prog.insns, i); + printf("%4zd: %s", i, spl_vm_opcode_name((spl_vm_opcode_t)ins->opcode)); if (ins->type != SPL_VOID) - printf(" %s", spl_type_tag_name((spl_type_t)ins->type)); + printf(" %s", spl_vm_type_kind_name((spl_type_t)ins->type)); printf(" %zd", ins->imm); /* annotate jumps / calls */ diff --git a/stage0/spl_mcode.c b/stage0/spl_mcode.c index 54b9dda..22fb91f 100644 --- a/stage0/spl_mcode.c +++ b/stage0/spl_mcode.c @@ -45,16 +45,16 @@ void spl_prog_drop(spl_prog_t *prog) { /* ---- LE read/write helpers ---- */ -static inline spl_val_t rd64(const unsigned char **p) { - spl_val_t v = (spl_val_t)(*p)[0] | ((spl_val_t)(*p)[1] << 8) | ((spl_val_t)(*p)[2] << 16) | - ((spl_val_t)(*p)[3] << 24) | ((spl_val_t)(*p)[4] << 32) | - ((spl_val_t)(*p)[5] << 40) | ((spl_val_t)(*p)[6] << 48) | - ((spl_val_t)(*p)[7] << 56); +static inline spl_vm_val_t rd64(const unsigned char **p) { + spl_vm_val_t v = (spl_vm_val_t)(*p)[0] | ((spl_vm_val_t)(*p)[1] << 8) | + ((spl_vm_val_t)(*p)[2] << 16) | ((spl_vm_val_t)(*p)[3] << 24) | + ((spl_vm_val_t)(*p)[4] << 32) | ((spl_vm_val_t)(*p)[5] << 40) | + ((spl_vm_val_t)(*p)[6] << 48) | ((spl_vm_val_t)(*p)[7] << 56); *p += 8; return v; } -static inline void wr64(unsigned char **p, spl_val_t v) { +static inline void wr64(unsigned char **p, spl_vm_val_t v) { *(*p)++ = (unsigned char)(v); *(*p)++ = (unsigned char)(v >> 8); *(*p)++ = (unsigned char)(v >> 16); @@ -73,7 +73,7 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { unsigned char *data; long len; const unsigned char *p; - spl_val_t nfuncs, ninsns, nnatives, nstrs, ndata; + spl_vm_val_t nfuncs, ninsns, nnatives, nstrs, ndata; if (!fname || !prog) return -1; @@ -120,9 +120,9 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { ndata = rd64(&p); /* ---- function table ---- */ - for (spl_val_t i = 0; i < nfuncs; i++) { - spl_func_t func = {0}; - spl_val_t nlen = rd64(&p); + for (spl_vm_val_t i = 0; i < nfuncs; i++) { + spl_vm_func_t func = {0}; + spl_vm_val_t nlen = rd64(&p); usize pad = ALIGN8((usize)nlen) - (usize)nlen; func.name = (char *)malloc((usize)nlen); @@ -141,12 +141,12 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { } /* ---- instructions ---- */ - for (spl_val_t i = 0; i < ninsns; i++) { + for (spl_vm_val_t i = 0; i < ninsns; i++) { if ((size_t)(p - data) + 12 > (size_t)len) { free(data); return -1; } - spl_ins_t ins; + spl_vm_ins_t ins; ins.opcode = (uint16_t)p[0] | ((uint16_t)p[1] << 8); ins.type = (uint16_t)p[2] | ((uint16_t)p[3] << 8); p += 4; @@ -155,9 +155,9 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { } /* ---- native table ---- */ - for (spl_val_t i = 0; i < nnatives; i++) { - spl_native_t nat = {0}; - spl_val_t nlen = rd64(&p); + for (spl_vm_val_t i = 0; i < nnatives; i++) { + spl_vm_native_t nat = {0}; + spl_vm_val_t nlen = rd64(&p); usize pad = ALIGN8((usize)nlen) - (usize)nlen; nat.name = (char *)malloc((usize)nlen); @@ -174,8 +174,8 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { } /* ---- string table ---- */ - for (spl_val_t i = 0; i < nstrs; i++) { - spl_val_t slen = rd64(&p); + for (spl_vm_val_t i = 0; i < nstrs; i++) { + spl_vm_val_t slen = rd64(&p); usize pad = ALIGN8((usize)slen) - (usize)slen; char *s = (char *)malloc((usize)slen + 1); if (!s) { @@ -189,8 +189,8 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { } /* ---- global data ---- */ - for (spl_val_t i = 0; i < ndata; i++) { - spl_gdata_t entry; + for (spl_vm_val_t i = 0; i < ndata; i++) { + spl_vm_gdata_t entry; entry.size = rd64(&p); usize pad = ALIGN8(entry.size) - entry.size; entry.data = (unsigned char *)malloc(entry.size); @@ -226,9 +226,9 @@ int spl_prog_load_from_file(const char *fname, spl_prog_t *prog) { int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) { unsigned char *buf, *p; - spl_val_t i; + spl_vm_val_t i; size_t total; - spl_val_t nfuncs, ninsns, nnatives, nstrs, ndata; + spl_vm_val_t nfuncs, ninsns, nnatives, nstrs, ndata; usize nlen, pad; if (!fname || !prog) @@ -306,7 +306,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) { /* ---- instructions ---- */ for (i = 0; i < ninsns; i++) { - spl_ins_t *ins = &vec_at(prog->insns, i); + spl_vm_ins_t *ins = &vec_at(prog->insns, i); *p++ = (unsigned char)(ins->opcode); *p++ = (unsigned char)(ins->opcode >> 8); *p++ = (unsigned char)(ins->type); @@ -341,7 +341,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) { /* ---- global data ---- */ for (i = 0; i < ndata; i++) { - spl_gdata_t *entry = &vec_at(prog->gdata, i); + spl_vm_gdata_t *entry = &vec_at(prog->gdata, i); pad = ALIGN8(entry->size) - entry->size; wr64(&p, entry->size); memcpy(p, entry->data, entry->size); @@ -362,22 +362,22 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) { return 0; } -int spl_prog_add_instr(spl_prog_t *prog, uint8_t opcode, uint8_t type, spl_val_t imm) { +int spl_prog_add_instr(spl_prog_t *prog, uint8_t opcode, uint8_t type, spl_vm_val_t imm) { if (!prog) return 0; - spl_ins_t ins = (spl_ins_t){.opcode = opcode, .type = type, .imm = imm}; + spl_vm_ins_t ins = (spl_vm_ins_t){.opcode = opcode, .type = type, .imm = imm}; vec_push(prog->insns, ins); return vec_size(prog->insns); } -int spl_prog_add_func(spl_prog_t *prog, spl_func_t *func) { +int spl_prog_add_func(spl_prog_t *prog, spl_vm_func_t *func) { if (!prog || !func) return 0; vec_push(prog->funcs, *func); return vec_size(prog->funcs); } -int spl_prog_add_native(spl_prog_t *prog, spl_native_t *native) { +int spl_prog_add_native(spl_prog_t *prog, spl_vm_native_t *native) { if (!prog || !native) return 0; vec_push(prog->natives, *native); @@ -385,7 +385,7 @@ int spl_prog_add_native(spl_prog_t *prog, spl_native_t *native) { } int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size) { - spl_gdata_t entry; + spl_vm_gdata_t entry; if (!prog) return 0; entry.data = (unsigned char *)malloc(size); @@ -397,7 +397,7 @@ int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size) { return vec_size(prog->gdata); } -spl_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name) { +spl_vm_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name) { if (!prog || !name) return NULL; vec_for(prog->funcs, i) { @@ -409,7 +409,7 @@ spl_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name) { return NULL; } -spl_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name) { +spl_vm_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name) { if (!prog || !name) return NULL; vec_for(prog->natives, i) { @@ -426,8 +426,8 @@ const char *opcode_name[] = { SPL_OPCODES(X) #undef X }; -const char *spl_opcode_name(spl_opcode_t opcode) { return opcode_name[opcode]; } -const char *spl_type_tag_name(spl_type_t type) { +const char *spl_vm_opcode_name(spl_vm_opcode_t opcode) { return opcode_name[opcode]; } +const char *spl_vm_type_kind_name(spl_type_t type) { switch (type) { case SPL_VOID: return "void"; @@ -464,10 +464,10 @@ const char *spl_type_tag_name(spl_type_t type) { } } -void spl_ins_dump(spl_ins_t *ins, spl_val_t addr) { - printf("%4zu: %s", addr, spl_opcode_name((spl_opcode_t)ins->opcode)); +void spl_vm_ins_dump(spl_vm_ins_t *ins, spl_vm_val_t addr) { + printf("%4zu: %s", addr, spl_vm_opcode_name((spl_vm_opcode_t)ins->opcode)); if (ins->type != SPL_VOID) - printf(" %s", spl_type_tag_name((spl_type_t)ins->type)); + printf(" %s", spl_vm_type_kind_name((spl_type_t)ins->type)); printf(" %zd:%zx", ins->imm, ins->imm); printf("\n"); } diff --git a/stage0/spl_mcode.h b/stage0/spl_mcode.h index 78140f0..67e6e99 100644 --- a/stage0/spl_mcode.h +++ b/stage0/spl_mcode.h @@ -103,7 +103,7 @@ typedef enum { #define X(opcode, name, argc, pop, push, desc) opcode, SPL_OPCODES(X) #undef X -} spl_opcode_t; +} spl_vm_opcode_t; /* * Binary format (all metadata fields spl_val_t LE): @@ -151,48 +151,48 @@ typedef enum { #define SPL_BINFMT_MAGIC "SPLBIN\0\0" // All SIR stack values are ptr-bit unsigned integers -typedef usize spl_val_t; +typedef usize spl_vm_val_t; -typedef struct spl_ins { +typedef struct spl_vm_ins { uint8_t opcode; uint8_t type; - spl_val_t imm; -} spl_ins_t; -typedef VEC(spl_ins_t) spl_ins_vec_t; + spl_vm_val_t imm; +} spl_vm_ins_t; +typedef VEC(spl_vm_ins_t) spl_vm_ins_vec_t; -typedef struct spl_func { +typedef struct spl_vm_func { char *name; - spl_val_t idx_of_strtab; - spl_val_t nargs; - spl_val_t ninsns; - spl_val_t address; -} spl_func_t; -typedef VEC(spl_func_t) spl_func_vec_t; + spl_vm_val_t idx_of_strtab; + spl_vm_val_t nargs; + spl_vm_val_t ninsns; + spl_vm_val_t address; +} spl_vm_func_t; +typedef VEC(spl_vm_func_t) spl_vm_func_vec_t; /* Native function pointer type */ -typedef spl_val_t (*spl_fn_t)(int nargs, spl_val_t *args); -typedef struct spl_native { +typedef spl_vm_val_t (*spl_vm_fn_t)(int nargs, spl_vm_val_t *args); +typedef struct spl_vm_native { char *name; - spl_val_t idx_of_strtab; - spl_fn_t impl_fn; -} spl_native_t; -typedef VEC(spl_native_t) spl_native_vec_t; + spl_vm_val_t idx_of_strtab; + spl_vm_fn_t impl_fn; +} spl_vm_native_t; +typedef VEC(spl_vm_native_t) spl_vm_native_vec_t; typedef struct { unsigned char *data; usize size; -} spl_gdata_t; -typedef VEC(spl_gdata_t) spl_data_t; -typedef VEC(const char *) spl_strtab_t; -typedef MAP(const char *, const char *) spl_symtab_t; +} spl_vm_gdata_t; +typedef VEC(spl_vm_gdata_t) spl_vm_data_t; +typedef VEC(const char *) spl_vm_strtab_t; +typedef MAP(const char *, const char *) spl_vm_symtab_t; /* Opaque handle for loaded program */ typedef struct spl_prog { - spl_ins_vec_t insns; - spl_func_vec_t funcs; - spl_native_vec_t natives; - spl_data_t gdata; - spl_strtab_t strtab; - spl_symtab_t symtab; + spl_vm_ins_vec_t insns; + spl_vm_func_vec_t funcs; + spl_vm_native_vec_t natives; + spl_vm_data_t gdata; + spl_vm_strtab_t strtab; + spl_vm_symtab_t symtab; char *debug; /* 文件尾部 debug 段(splc0 -g 追加的文本),无则 NULL */ usize debug_size; } spl_prog_t; @@ -203,18 +203,18 @@ void spl_prog_drop(spl_prog_t *prog); int spl_prog_load_from_file(const char *fname, spl_prog_t *prog); int spl_prog_store_to_file(const char *fname, spl_prog_t *prog); -int spl_prog_add_instr(spl_prog_t *prog, uint8_t opcode, uint8_t type, spl_val_t imm); +int spl_prog_add_instr(spl_prog_t *prog, uint8_t opcode, uint8_t type, spl_vm_val_t imm); int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size); -int spl_prog_add_func(spl_prog_t *prog, spl_func_t *func); -int spl_prog_add_native(spl_prog_t *prog, spl_native_t *native); +int spl_prog_add_func(spl_prog_t *prog, spl_vm_func_t *func); +int spl_prog_add_native(spl_prog_t *prog, spl_vm_native_t *native); -spl_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name); -spl_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name); +spl_vm_func_t *spl_prog_get_func(spl_prog_t *prog, const char *name); +spl_vm_native_t *spl_prog_get_native(spl_prog_t *prog, const char *name); /* Opcode name lookup for debugging/dumping */ -const char *spl_opcode_name(spl_opcode_t opcode); -const char *spl_type_tag_name(spl_type_t type); +const char *spl_vm_opcode_name(spl_vm_opcode_t opcode); +const char *spl_vm_type_kind_name(spl_type_t type); -void spl_ins_dump(spl_ins_t *ins, spl_val_t addr); +void spl_vm_ins_dump(spl_vm_ins_t *ins, spl_vm_val_t addr); #endif /* __SPL_MCODE_H__ */ diff --git a/stage0/spl_syscall.c b/stage0/spl_syscall.c index 14dfb08..ef0ceac 100644 --- a/stage0/spl_syscall.c +++ b/stage0/spl_syscall.c @@ -36,44 +36,44 @@ } while (0) #define SYSCALL_0(name, ret_expr) \ - static spl_val_t name(int nargs, spl_val_t *args) { \ + static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \ CHECK_NARGS(#name, 0); \ (void)args; \ - return (spl_val_t)(uintptr_t)(ret_expr); \ + return (spl_vm_val_t)(uintptr_t)(ret_expr); \ } #define SYSCALL_1(name, t1, ret_expr) \ - static spl_val_t name(int nargs, spl_val_t *args) { \ + static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \ CHECK_NARGS(#name, 1); \ t1 a1 = (t1)(uintptr_t)args[0]; \ - return (spl_val_t)(uintptr_t)(ret_expr); \ + return (spl_vm_val_t)(uintptr_t)(ret_expr); \ } #define SYSCALL_2(name, t1, t2, ret_expr) \ - static spl_val_t name(int nargs, spl_val_t *args) { \ + static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \ CHECK_NARGS(#name, 2); \ t1 a1 = (t1)(uintptr_t)args[0]; \ t2 a2 = (t2)(uintptr_t)args[1]; \ - return (spl_val_t)(uintptr_t)(ret_expr); \ + return (spl_vm_val_t)(uintptr_t)(ret_expr); \ } #define SYSCALL_3(name, t1, t2, t3, ret_expr) \ - static spl_val_t name(int nargs, spl_val_t *args) { \ + static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \ CHECK_NARGS(#name, 3); \ t1 a1 = (t1)(uintptr_t)args[0]; \ t2 a2 = (t2)(uintptr_t)args[1]; \ t3 a3 = (t3)(uintptr_t)args[2]; \ - return (spl_val_t)(uintptr_t)(ret_expr); \ + return (spl_vm_val_t)(uintptr_t)(ret_expr); \ } #define SYSCALL_4(name, t1, t2, t3, t4, ret_expr) \ - static spl_val_t name(int nargs, spl_val_t *args) { \ + static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \ CHECK_NARGS(#name, 4); \ t1 a1 = (t1)(uintptr_t)args[0]; \ t2 a2 = (t2)(uintptr_t)args[1]; \ t3 a3 = (t3)(uintptr_t)args[2]; \ t4 a4 = (t4)(uintptr_t)args[3]; \ - return (spl_val_t)(uintptr_t)(ret_expr); \ + return (spl_vm_val_t)(uintptr_t)(ret_expr); \ } /* ================================================================= @@ -81,7 +81,7 @@ * ================================================================= */ /* vm_exit - terminate process with the given exit code */ -SYSCALL_1(vm_exit, int, (exit(a1), (spl_val_t)0)) +SYSCALL_1(vm_exit, int, (exit(a1), (spl_vm_val_t)0)) /* vm_putchar - write a single character to stdout */ SYSCALL_1(vm_putchar, int, putchar(a1)) @@ -90,10 +90,10 @@ SYSCALL_1(vm_putchar, int, putchar(a1)) SYSCALL_0(vm_getchar, getchar()) /* vm_putint - print an integer to stdout */ -SYSCALL_1(vm_putint, int, (fprintf(stdout, "%d", a1), (spl_val_t)0)) +SYSCALL_1(vm_putint, int, (fprintf(stdout, "%d", a1), (spl_vm_val_t)0)) /* vm_putstr - print a string to stdout (no trailing newline) */ -SYSCALL_1(vm_putstr, const char *, (fputs(a1, stdout), (spl_val_t)0)) +SYSCALL_1(vm_putstr, const char *, (fputs(a1, stdout), (spl_vm_val_t)0)) /* vm_fopen - open a file, returns FILE* as spl_val_t */ SYSCALL_2(vm_fopen, const char *, const char *, (uintptr_t)fopen(a1, a2)) @@ -108,14 +108,14 @@ SYSCALL_4(vm_fread, void *, size_t, size_t, FILE *, fread(a1, a2, a3, a4)) SYSCALL_4(vm_fwrite, const void *, size_t, size_t, FILE *, fwrite(a1, a2, a3, a4)) /* vm_fsize - get file size in bytes */ -static spl_val_t vm_fsize(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_fsize(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_fsize", 1); FILE *f = (FILE *)(uintptr_t)args[0]; long cur = ftell(f); fseek(f, 0, SEEK_END); long sz = ftell(f); fseek(f, cur, SEEK_SET); - return (spl_val_t)(uintptr_t)sz; + return (spl_vm_val_t)(uintptr_t)sz; } SYSCALL_0(vm_stdin, stdin) @@ -123,7 +123,7 @@ SYSCALL_0(vm_stdout, stdout) SYSCALL_0(vm_stderr, stderr) /* vm_read_file - read entire file into a malloc'd, null-terminated buffer */ -static spl_val_t vm_read_file(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_read_file(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_read_file", 1); const char *path = (const char *)(uintptr_t)args[0]; if (path == nullptr) { @@ -146,14 +146,14 @@ static spl_val_t vm_read_file(int nargs, spl_val_t *args) { size_t nread = fread(buf, 1, (size_t)sz, f); fclose(f); buf[nread] = '\0'; - return (spl_val_t)(uintptr_t)buf; + return (spl_vm_val_t)(uintptr_t)buf; } /* vm_alloc - allocate memory (malloc) */ SYSCALL_1(vm_alloc, size_t, (uintptr_t)malloc(a1)) /* vm_free - free memory */ -SYSCALL_1(vm_free, void *, (free(a1), (spl_val_t)0)) +SYSCALL_1(vm_free, void *, (free(a1), (spl_vm_val_t)0)) /* vm_realloc - reallocate memory (realloc) */ SYSCALL_2(vm_realloc, void *, size_t, (uintptr_t)realloc(a1, a2)) @@ -167,7 +167,7 @@ SYSCALL_2(vm_strcmp, const char *, const char *, strcmp(a1, a2)) /* vm_memcpy - copy memory, returns dst */ SYSCALL_3(vm_memcpy, void *, const void *, size_t, (memcpy(a1, a2, a3), (uintptr_t)a1)) -static spl_val_t vm_printf(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_printf(int nargs, spl_vm_val_t *args) { (void)args; if (nargs <= 0) { return 0; @@ -235,18 +235,18 @@ static spl_val_t vm_printf(int nargs, spl_val_t *args) { * ================================================================= */ /* vm_new - create a new sub-VM instance, returns spl_vm_t* */ -static spl_val_t vm_new(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_new(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_new", 0); (void)args; spl_vm_t *vm = (spl_vm_t *)malloc(sizeof(spl_vm_t)); if (!vm) return 0; spl_vm_init(vm); - return (spl_val_t)(uintptr_t)vm; + return (spl_vm_val_t)(uintptr_t)vm; } /* vm_drop - destroy a sub-VM and its loaded program */ -static spl_val_t vm_drop(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_drop(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_drop", 1); spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0]; if (!vm) @@ -262,7 +262,7 @@ static spl_val_t vm_drop(int nargs, spl_val_t *args) { } /* vm_load - load a .sir file, register syscalls, return spl_prog_t* */ -static spl_val_t vm_load(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_load(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_load", 2); spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0]; const char *path = (const char *)(uintptr_t)args[1]; @@ -282,14 +282,14 @@ static spl_val_t vm_load(int nargs, spl_val_t *args) { free(prog); return -1; } - return (spl_val_t)(uintptr_t)prog; + return (spl_vm_val_t)(uintptr_t)prog; } /* vm_push - push a value onto the sub-VM's stack (for passing arguments) */ -static spl_val_t vm_push(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_push(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_push", 2); spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0]; - spl_val_t val = args[1]; + spl_vm_val_t val = args[1]; if (!vm) return -1; if (vm->sp >= vm->config.max_stack_depth) { @@ -311,15 +311,15 @@ static spl_val_t vm_push(int nargs, spl_val_t *args) { * - Sets fp = sp - nargs (so arg0 = data[fp], arg1 = data[fp+1], ...) * - Sets ip to the function address */ -static spl_val_t vm_call(int nargs, spl_val_t *args) { +static spl_vm_val_t vm_call(int nargs, spl_vm_val_t *args) { CHECK_NARGS("vm_call", 3); spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0]; const char *name = (const char *)(uintptr_t)args[1]; - spl_val_t call_nargs = args[2]; + spl_vm_val_t call_nargs = args[2]; if (!vm || !name) return -1; - spl_func_t *func = spl_prog_get_func(vm->prog, name); + spl_vm_func_t *func = spl_prog_get_func(vm->prog, name); if (!func) { fprintf(stderr, "vm_call: function '%s' not found\n", name); return -1; @@ -358,7 +358,7 @@ SYSCALL_1(vm_run, spl_vm_t *, spl_vm_run_until(a1, 0)) * ================================================================= */ void spl_syscall_register(spl_prog_t *prog) { - static spl_native_t table[] = { + static spl_vm_native_t table[] = { /* OS operations */ {"vm_exit", 0, vm_exit}, {"vm_putchar", 0, vm_putchar}, @@ -393,7 +393,7 @@ void spl_syscall_register(spl_prog_t *prog) { if (!prog) return; vec_for(prog->natives, i) { - spl_native_t *nat = &vec_at(prog->natives, i); + spl_vm_native_t *nat = &vec_at(prog->natives, i); if (!nat->name || nat->impl_fn) continue; for (int j = 0; j < n; j++) { diff --git a/stage0/spl_vm.c b/stage0/spl_vm.c index c002b79..1193abe 100644 --- a/stage0/spl_vm.c +++ b/stage0/spl_vm.c @@ -99,7 +99,7 @@ static int spl_type_size(spl_type_t t) { #define PUSH(v) \ do { \ - spl_val_t _pv = (spl_val_t)(v); \ + spl_vm_val_t _pv = (spl_vm_val_t)(v); \ if (vm->sp >= vm->config.max_stack_depth) \ VM_ERROR("stack overflow"); \ vm->stacks.data[(vm->sp)++] = _pv; \ @@ -121,8 +121,8 @@ static int spl_type_size(spl_type_t t) { #define ARITH_BINOP(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ - spl_val_t _r = 0; \ + spl_vm_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _r = 0; \ if (spl_is_float((spl_type_t)ins->type)) { \ double _da, _db, _dr; \ if (ins->type == SPL_F32) { \ @@ -145,25 +145,25 @@ static int spl_type_size(spl_type_t t) { } else { \ switch (ins->type) { \ case SPL_I8: \ - _r = (spl_val_t)((int8_t)_a OP(int8_t) _b); \ + _r = (spl_vm_val_t)((int8_t)_a OP(int8_t) _b); \ break; \ case SPL_U8: \ - _r = (spl_val_t)((uint8_t)_a OP(uint8_t) _b); \ + _r = (spl_vm_val_t)((uint8_t)_a OP(uint8_t) _b); \ break; \ case SPL_I16: \ - _r = (spl_val_t)((int16_t)_a OP(int16_t) _b); \ + _r = (spl_vm_val_t)((int16_t)_a OP(int16_t) _b); \ break; \ case SPL_U16: \ - _r = (spl_val_t)((uint16_t)_a OP(uint16_t) _b); \ + _r = (spl_vm_val_t)((uint16_t)_a OP(uint16_t) _b); \ break; \ case SPL_I32: \ - _r = (spl_val_t)((int32_t)_a OP(int32_t) _b); \ + _r = (spl_vm_val_t)((int32_t)_a OP(int32_t) _b); \ break; \ case SPL_U32: \ - _r = (spl_val_t)((uint32_t)_a OP(uint32_t) _b); \ + _r = (spl_vm_val_t)((uint32_t)_a OP(uint32_t) _b); \ break; \ case SPL_I64: \ - _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ + _r = (spl_vm_val_t)((int64_t)_a OP(int64_t) _b); \ break; \ case SPL_U64: \ case SPL_PTR: \ @@ -181,10 +181,10 @@ static int spl_type_size(spl_type_t t) { /* signed division / remainder - all types cast to signed */ #define DIV_REM_S(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _b = POP(), _a = POP(); \ if (_b == 0) \ VM_ERROR("division by zero"); \ - spl_val_t _r = 0; \ + spl_vm_val_t _r = 0; \ if (spl_is_float((spl_type_t)ins->type)) { \ double _da, _db, _dr; \ if (ins->type == SPL_F32) { \ @@ -207,31 +207,31 @@ static int spl_type_size(spl_type_t t) { } else { \ switch (ins->type) { \ case SPL_I8: \ - _r = (spl_val_t)((int8_t)_a OP(int8_t) _b); \ + _r = (spl_vm_val_t)((int8_t)_a OP(int8_t) _b); \ break; \ case SPL_U8: \ - _r = (spl_val_t)((int8_t)_a OP(int8_t) _b); \ + _r = (spl_vm_val_t)((int8_t)_a OP(int8_t) _b); \ break; \ case SPL_I16: \ - _r = (spl_val_t)((int16_t)_a OP(int16_t) _b); \ + _r = (spl_vm_val_t)((int16_t)_a OP(int16_t) _b); \ break; \ case SPL_U16: \ - _r = (spl_val_t)((int16_t)_a OP(int16_t) _b); \ + _r = (spl_vm_val_t)((int16_t)_a OP(int16_t) _b); \ break; \ case SPL_I32: \ - _r = (spl_val_t)((int32_t)_a OP(int32_t) _b); \ + _r = (spl_vm_val_t)((int32_t)_a OP(int32_t) _b); \ break; \ case SPL_U32: \ - _r = (spl_val_t)((int32_t)_a OP(int32_t) _b); \ + _r = (spl_vm_val_t)((int32_t)_a OP(int32_t) _b); \ break; \ case SPL_I64: \ - _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ + _r = (spl_vm_val_t)((int64_t)_a OP(int64_t) _b); \ break; \ case SPL_U64: \ case SPL_PTR: \ case SPL_USIZE: \ case SPL_ISIZE: \ - _r = (spl_val_t)((int64_t)_a OP(int64_t) _b); \ + _r = (spl_vm_val_t)((int64_t)_a OP(int64_t) _b); \ break; \ default: \ VM_ERROR("bad type for signed division"); \ @@ -243,31 +243,31 @@ static int spl_type_size(spl_type_t t) { /* unsigned division / remainder */ #define DIV_REM_U(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _b = POP(), _a = POP(); \ if (_b == 0) \ VM_ERROR("division by zero"); \ - spl_val_t _r = 0; \ + spl_vm_val_t _r = 0; \ switch (ins->type) { \ case SPL_I8: \ - _r = (spl_val_t)((uint8_t)_a OP(uint8_t) _b); \ + _r = (spl_vm_val_t)((uint8_t)_a OP(uint8_t) _b); \ break; \ case SPL_U8: \ - _r = (spl_val_t)((uint8_t)_a OP(uint8_t) _b); \ + _r = (spl_vm_val_t)((uint8_t)_a OP(uint8_t) _b); \ break; \ case SPL_I16: \ - _r = (spl_val_t)((uint16_t)_a OP(uint16_t) _b); \ + _r = (spl_vm_val_t)((uint16_t)_a OP(uint16_t) _b); \ break; \ case SPL_U16: \ - _r = (spl_val_t)((uint16_t)_a OP(uint16_t) _b); \ + _r = (spl_vm_val_t)((uint16_t)_a OP(uint16_t) _b); \ break; \ case SPL_I32: \ - _r = (spl_val_t)((uint32_t)_a OP(uint32_t) _b); \ + _r = (spl_vm_val_t)((uint32_t)_a OP(uint32_t) _b); \ break; \ case SPL_U32: \ - _r = (spl_val_t)((uint32_t)_a OP(uint32_t) _b); \ + _r = (spl_vm_val_t)((uint32_t)_a OP(uint32_t) _b); \ break; \ case SPL_I64: \ - _r = (spl_val_t)((uint64_t)_a OP(uint64_t) _b); \ + _r = (spl_vm_val_t)((uint64_t)_a OP(uint64_t) _b); \ break; \ case SPL_U64: \ case SPL_PTR: \ @@ -284,7 +284,7 @@ static int spl_type_size(spl_type_t t) { /* CMP_ALL - equality comparisons (all types, floats via memcpy) */ #define CMP_ALL(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _b = POP(), _a = POP(); \ intptr_t _r = 0; \ switch (ins->type) { \ case SPL_I8: \ @@ -338,7 +338,7 @@ static int spl_type_size(spl_type_t t) { /* CMP_S - signed ordering (all ints cast to signed, floats OK) */ #define CMP_S(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _b = POP(), _a = POP(); \ intptr_t _r = 0; \ switch (ins->type) { \ case SPL_I8: \ @@ -392,7 +392,7 @@ static int spl_type_size(spl_type_t t) { /* CMP_U - unsigned ordering (all ints cast to unsigned, no float) */ #define CMP_U(OP) \ do { \ - spl_val_t _b = POP(), _a = POP(); \ + spl_vm_val_t _b = POP(), _a = POP(); \ intptr_t _r = 0; \ switch (ins->type) { \ case SPL_I8: \ @@ -478,6 +478,7 @@ const char *ExceptionCodeToString(DWORD code) { } // 全局未处理异常过滤器 +#ifdef _WIN32 LONG WINAPI UnhandledExceptionFilterImpl(EXCEPTION_POINTERS *pExceptionInfo) { // 获取异常记录和上下文 PEXCEPTION_RECORD record = pExceptionInfo->ExceptionRecord; @@ -537,6 +538,7 @@ LONG WINAPI UnhandledExceptionFilterImpl(EXCEPTION_POINTERS *pExceptionInfo) { // 你可以在这里调用 exit(1) 或直接返回,进程会被终止 return EXCEPTION_EXECUTE_HANDLER; } +#endif /* ================================================================ * spl_vm_init / spl_vm_drop @@ -614,10 +616,10 @@ void spl_vm_skip_breakpoint(spl_vm_t *vm) { } /* 前向声明(定义在文件尾部 dump 区域) */ -static const char *func_name_by_ip(spl_prog_t *prog, spl_val_t ip); +static const char *func_name_by_ip(spl_prog_t *prog, spl_vm_val_t ip); /* 函数名断点命中:addr 所在函数名是否在断点表 */ -static int fn_breakpoint_hit(spl_vm_t *vm, spl_val_t addr) { +static int fn_breakpoint_hit(spl_vm_t *vm, spl_vm_val_t addr) { if (!vm || !vm->prog || !vec_size(vm->fn_breakpoints)) return 0; const char *fn = func_name_by_ip(vm->prog, addr); @@ -669,7 +671,7 @@ void spl_vm_set_debug(spl_vm_t *vm, int enabled) { #define STACK_CANARY(vm) (vm)->stacks.data[(vm)->fp - 1] -static inline int spl_vm_call(spl_vm_t *vm, spl_val_t addr, spl_val_t nargs) { +static inline int spl_vm_call(spl_vm_t *vm, spl_vm_val_t addr, spl_vm_val_t nargs) { if (vm->cp >= vm->config.max_call_depth) VM_ERROR("CALLI: call stack overflow"); // spl_vm_stackdump(vm, vm->sp); @@ -696,7 +698,7 @@ int spl_vm_prepare(spl_vm_t *vm, const char *entry, int argc, const char **argv, if (!vm || !vm->prog) { return -1; } - spl_func_t *fn = spl_prog_get_func(vm->prog, entry ? entry : "main"); + spl_vm_func_t *fn = spl_prog_get_func(vm->prog, entry ? entry : "main"); if (!fn) { fprintf(stderr, "vm: entry point '%s' not found\n", entry ? entry : "main"); return -1; @@ -733,7 +735,7 @@ int spl_vm_prepare(spl_vm_t *vm, const char *entry, int argc, const char **argv, * ================================================================ */ int spl_vm_run_once(spl_vm_t *vm) { - const spl_ins_t *ins; + const spl_vm_ins_t *ins; spl_prog_t *prog; if (!vm || !vm->prog) @@ -761,7 +763,7 @@ int spl_vm_run_once(spl_vm_t *vm) { if (vm->trace) { fprintf(stderr, "vm: ip=%zd op=%s type=%s imm=%zu sp=%zd fp=%zd\n", vm->ip - 1, - spl_opcode_name(ins->opcode), spl_type_tag_name(ins->type), ins->imm, vm->sp, + spl_vm_opcode_name(ins->opcode), spl_vm_type_kind_name(ins->type), ins->imm, vm->sp, vm->fp); } @@ -775,7 +777,7 @@ int spl_vm_run_once(spl_vm_t *vm) { case SPL_DUP: { if (vm->sp < 1) VM_ERROR("DUP: stack underflow"); - spl_val_t _v = vm->stacks.data[vm->sp - 1]; + spl_vm_val_t _v = vm->stacks.data[vm->sp - 1]; PUSH(_v); break; } @@ -789,7 +791,7 @@ int spl_vm_run_once(spl_vm_t *vm) { case SPL_SWAP: { if (vm->sp < 2) VM_ERROR("SWAP: stack underflow"); - spl_val_t _t = vm->stacks.data[vm->sp - 1]; + spl_vm_val_t _t = vm->stacks.data[vm->sp - 1]; vm->stacks.data[vm->sp - 1] = vm->stacks.data[vm->sp - 2]; vm->stacks.data[vm->sp - 2] = _t; break; @@ -806,9 +808,9 @@ int spl_vm_run_once(spl_vm_t *vm) { case SPL_ROT: { if (vm->sp < 3) VM_ERROR("ROT: stack underflow"); - spl_val_t _a = vm->stacks.data[vm->sp - 3]; - spl_val_t _b = vm->stacks.data[vm->sp - 2]; - spl_val_t _c = vm->stacks.data[vm->sp - 1]; + spl_vm_val_t _a = vm->stacks.data[vm->sp - 3]; + spl_vm_val_t _b = vm->stacks.data[vm->sp - 2]; + spl_vm_val_t _c = vm->stacks.data[vm->sp - 1]; vm->stacks.data[vm->sp - 3] = _b; vm->stacks.data[vm->sp - 2] = _c; vm->stacks.data[vm->sp - 1] = _a; @@ -840,7 +842,7 @@ int spl_vm_run_once(spl_vm_t *vm) { break; case SPL_NEG: { - spl_val_t _a = POP(); + spl_vm_val_t _a = POP(); if (spl_is_float((spl_type_t)ins->type)) { double _d; if (ins->type == SPL_F32) { @@ -862,17 +864,17 @@ int spl_vm_run_once(spl_vm_t *vm) { /* ========== Bitwise ========== */ case SPL_AND: { - spl_val_t _b = POP(), _a = POP(); + spl_vm_val_t _b = POP(), _a = POP(); PUSH(_a & _b); break; } case SPL_OR: { - spl_val_t _b = POP(), _a = POP(); + spl_vm_val_t _b = POP(), _a = POP(); PUSH(_a | _b); break; } case SPL_XOR: { - spl_val_t _b = POP(), _a = POP(); + spl_vm_val_t _b = POP(), _a = POP(); PUSH(_a ^ _b); break; } @@ -946,8 +948,8 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_CALL: { - spl_val_t _nargs = ins->imm; - spl_val_t _addr = POP(); + spl_vm_val_t _nargs = ins->imm; + spl_vm_val_t _addr = POP(); int _hit = fn_breakpoint_hit(vm, _addr); spl_vm_call(vm, _addr, _nargs); if (_hit) @@ -956,8 +958,8 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_CALLI: { - spl_val_t _addr = POP(); - spl_val_t _nargs = POP(); + spl_vm_val_t _addr = POP(); + spl_vm_val_t _nargs = POP(); int _hit = fn_breakpoint_hit(vm, _addr); spl_vm_call(vm, _addr, _nargs); if (_hit) @@ -966,7 +968,7 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_RET: { - spl_val_t _retval = 0; + spl_vm_val_t _retval = 0; if (ins->type != SPL_VOID) _retval = POP(); if (vm->cp <= 0) @@ -996,7 +998,7 @@ int spl_vm_run_once(spl_vm_t *vm) { /* ========== Stack / Frame Local Memory ========== */ case SPL_ALLOC: { - spl_val_t _k = ins->imm; + spl_vm_val_t _k = ins->imm; uintptr_t _new_sp = vm->sp + _k; if (_new_sp > vm->config.max_stack_depth) VM_ERROR("ALLOC: stack overflow"); @@ -1007,14 +1009,14 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_LADDR: - PUSH((spl_val_t)((char *)(vm->stacks.data + vm->fp) + ins->imm)); + PUSH((spl_vm_val_t)((char *)(vm->stacks.data + vm->fp) + ins->imm)); break; case SPL_GADDR: { - spl_val_t _idx = ins->imm; + spl_vm_val_t _idx = ins->imm; if (_idx >= vec_size(prog->gdata)) VM_ERROR("GADDR: global data index out of range"); - PUSH((spl_val_t)(uintptr_t)vec_at(prog->gdata, _idx).data); + PUSH((spl_vm_val_t)(uintptr_t)vec_at(prog->gdata, _idx).data); break; } @@ -1022,19 +1024,19 @@ int spl_vm_run_once(spl_vm_t *vm) { case SPL_LOAD: { void *_addr = (void *)POP(); CHECK_ADDR(_addr, "LOAD"); - spl_val_t _v = 0; + spl_vm_val_t _v = 0; usize _sz = spl_type_size(ins->type); memcpy(&_v, _addr, _sz); /* Sign-extend signed integer types smaller than 64 bits */ - if (_sz > 0 && _sz < sizeof(spl_val_t) && spl_is_signed(ins->type)) { - usize _shift = (sizeof(spl_val_t) - _sz) * 8; - _v = (spl_val_t)(((isize)(_v << _shift)) >> _shift); + if (_sz > 0 && _sz < sizeof(spl_vm_val_t) && spl_is_signed(ins->type)) { + usize _shift = (sizeof(spl_vm_val_t) - _sz) * 8; + _v = (spl_vm_val_t)(((isize)(_v << _shift)) >> _shift); } PUSH(_v); break; } case SPL_STORE: { - spl_val_t _v = POP(); + spl_vm_val_t _v = POP(); void *_addr = (void *)POP(); CHECK_ADDR(_addr, "STORE"); memcpy(_addr, &_v, spl_type_size(ins->type)); @@ -1043,12 +1045,12 @@ int spl_vm_run_once(spl_vm_t *vm) { /* ========== Type Conversion ========== */ case SPL_TRUNC: { - spl_val_t _v = POP(); + spl_vm_val_t _v = POP(); intptr_t _bits = ins->imm; if (_bits < 1 || _bits > 64) VM_ERROR("TRUNC: bad bit-width"); if (_bits < 64) { - spl_val_t _mask = ((spl_val_t)1 << _bits) - 1; + spl_vm_val_t _mask = ((spl_vm_val_t)1 << _bits) - 1; _v &= _mask; } PUSH(_v); @@ -1056,13 +1058,13 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_SEXT: { - spl_val_t _v = POP(); + spl_vm_val_t _v = POP(); intptr_t _bits = ins->imm; if (_bits < 1 || _bits > 64) VM_ERROR("SEXT: bad bit-width"); if (_bits < 64) { - spl_val_t _sign = (spl_val_t)1 << (_bits - 1); - spl_val_t _mask = ((spl_val_t)1 << _bits) - 1; + spl_vm_val_t _sign = (spl_vm_val_t)1 << (_bits - 1); + spl_vm_val_t _mask = ((spl_vm_val_t)1 << _bits) - 1; _v &= _mask; if (_v & _sign) _v |= ~_mask; @@ -1072,12 +1074,12 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_ZEXT: { - spl_val_t _v = POP(); + spl_vm_val_t _v = POP(); intptr_t _bits = ins->imm; if (_bits < 1 || _bits > 64) VM_ERROR("ZEXT: bad bit-width"); if (_bits < 64) - _v &= ((spl_val_t)1 << _bits) - 1; + _v &= ((spl_vm_val_t)1 << _bits) - 1; PUSH(_v); break; } @@ -1085,8 +1087,8 @@ int spl_vm_run_once(spl_vm_t *vm) { /* ========== Native Interface ========== */ case SPL_NCALL: { intptr_t _nargs = ins->imm; - spl_val_t _nat_idx = POP(); - spl_native_t *_nat; + spl_vm_val_t _nat_idx = POP(); + spl_vm_native_t *_nat; if (_nat_idx >= vec_size(prog->natives)) VM_ERROR("NCALL: native index out of range"); _nat = &vec_at(prog->natives, _nat_idx); @@ -1095,18 +1097,18 @@ int spl_vm_run_once(spl_vm_t *vm) { "NCALL: NULL native function pointer expect %s", _nat->name); VM_ERROR(vm->error_msg); } - spl_val_t *_arg_base = vm->stacks.data + vm->sp - _nargs; + spl_vm_val_t *_arg_base = vm->stacks.data + vm->sp - _nargs; // spl_vm_stackdump(vm, vm->sp); // printf("addr %p nargs %zd sp %zd stack %p arg_base %p\n", _nat->impl_fn, _nargs, vm->sp, // vm->stacks.data, _arg_base); - spl_val_t _result = _nat->impl_fn(_nargs, _arg_base); + spl_vm_val_t _result = _nat->impl_fn(_nargs, _arg_base); vm->sp -= _nargs; PUSH(_result); break; } case SPL_NLIB: { - spl_val_t _si = ins->imm; + spl_vm_val_t _si = ins->imm; const char *_lib; if (_si >= vec_size(prog->strtab) || !vec_at(prog->strtab, _si)) VM_ERROR("NLIB: invalid string index"); @@ -1175,44 +1177,44 @@ int spl_vm_run_until(spl_vm_t *vm, size_t step) { } } -static const char *func_name_by_ip(spl_prog_t *prog, spl_val_t ip) { +static const char *func_name_by_ip(spl_prog_t *prog, spl_vm_val_t ip) { vec_for(prog->funcs, i) { - spl_func_t *f = &vec_at(prog->funcs, i); + spl_vm_func_t *f = &vec_at(prog->funcs, i); if (ip >= f->address && ip < (f->address + f->ninsns)) return f->name; } return "?"; } -void spl_vm_dump_instr(spl_vm_t *vm, spl_val_t ip) { +void spl_vm_dump_instr(spl_vm_t *vm, spl_vm_val_t ip) { if (!vm || !vm->prog) return; if (ip >= vec_size(vm->prog->insns)) return; - spl_ins_t *ins = &vec_at(vm->prog->insns, ip); - fprintf(stderr, " instr at ip=%zd: op=%s type=%s imm=%zu\n", ip, spl_opcode_name(ins->opcode), - spl_type_tag_name(ins->type), ins->imm); + spl_vm_ins_t *ins = &vec_at(vm->prog->insns, ip); + fprintf(stderr, " instr at ip=%zd: op=%s type=%s imm=%zu\n", ip, + spl_vm_opcode_name(ins->opcode), spl_vm_type_kind_name(ins->type), ins->imm); } -void spl_vm_stackdump(spl_vm_t *vm, spl_val_t sp) { +void spl_vm_stackdump(spl_vm_t *vm, spl_vm_val_t sp) { if (!vm) return; fprintf(stderr, "stack dump (sp=%zd, fp=%zd):\n", sp, vm->fp); - spl_val_t start = sp > 32 ? sp - 32 : 0; - for (spl_val_t i = start; i <= sp; i++) { + spl_vm_val_t start = sp > 32 ? sp - 32 : 0; + for (spl_vm_val_t i = start; i <= sp; i++) { fprintf(stderr, " [%3zd] = [addr 0x%p] 0x%016zx (%zd)\n", i, &vm->stacks.data[i], vm->stacks.data[i], vm->stacks.data[i]); } } -int spl_vm_backtrace(spl_vm_t *vm, spl_val_t fp) { +int spl_vm_backtrace(spl_vm_t *vm, spl_vm_val_t fp) { if (!vm || !vm->prog) return -1; (void)fp; fprintf(stderr, "backtrace: \n"); for (isize i = vm->cp - 1; i >= 0; i--) { - spl_val_t _saved_ip = vm->frames.data[i].saved_ip; - spl_val_t _saved_fp = vm->frames.data[i].saved_fp; + spl_vm_val_t _saved_ip = vm->frames.data[i].saved_ip; + spl_vm_val_t _saved_fp = vm->frames.data[i].saved_fp; const char *_fn = func_name_by_ip(vm->prog, _saved_ip - 1); fprintf(stderr, " [%3zd] %s (fp=%zd, ip=%zd, args=%zd)\n", i, _fn, _saved_fp, _saved_ip, vm->frames.data[i].nargs); diff --git a/stage0/spl_vm.h b/stage0/spl_vm.h index bb93c67..f73b0fd 100644 --- a/stage0/spl_vm.h +++ b/stage0/spl_vm.h @@ -7,16 +7,16 @@ #include "spl_mcode.h" #include -#define SPL_STACK_CANARY ((spl_val_t)0xDEADBEEFCAFEBABEull) +#define SPL_STACK_CANARY ((spl_vm_val_t)0xDEADBEEFCAFEBABEull) typedef struct { uintptr_t saved_sp; uintptr_t saved_fp; uintptr_t saved_ip; - spl_val_t nargs; + spl_vm_val_t nargs; } spl_callframe_t; -typedef VEC(spl_val_t) spl_stack_vec_t; +typedef VEC(spl_vm_val_t) spl_stack_vec_t; typedef VEC(spl_callframe_t) spl_frame_vec_t; typedef struct { @@ -71,8 +71,8 @@ void spl_vm_clear_breakpoints(spl_vm_t *vm); /* 让 run_once 执行当前指令(忽略一次断点命中);continue 越过当前断点用 */ void spl_vm_skip_breakpoint(spl_vm_t *vm); -void spl_vm_dump_instr(spl_vm_t *vm, spl_val_t ip); -void spl_vm_stackdump(spl_vm_t *vm, spl_val_t sp); -int spl_vm_backtrace(spl_vm_t *vm, spl_val_t fp); +void spl_vm_dump_instr(spl_vm_t *vm, spl_vm_val_t ip); +void spl_vm_stackdump(spl_vm_t *vm, spl_vm_val_t sp); +int spl_vm_backtrace(spl_vm_t *vm, spl_vm_val_t fp); #endif /* __SPL_VM_H__ */ diff --git a/stage0/test_spl_vm.c b/stage0/test_spl_vm.c index 7ac03a2..b70f8bb 100644 --- a/stage0/test_spl_vm.c +++ b/stage0/test_spl_vm.c @@ -20,7 +20,7 @@ #define LE64(p, v) \ do { \ unsigned char *_p = (p); \ - spl_val_t _v = (spl_val_t)(v); \ + spl_vm_val_t _v = (spl_vm_val_t)(v); \ *_p++ = (unsigned char)(_v); \ *_p++ = (unsigned char)(_v >> 8); \ *_p++ = (unsigned char)(_v >> 16); \ @@ -33,8 +33,8 @@ } while (0) /* Convenience: build spl_ins_t from raw fields */ -static spl_ins_t ins(uint16_t op, uint16_t type, spl_val_t imm) { - spl_ins_t x; +static spl_vm_ins_t ins(uint16_t op, uint16_t type, spl_vm_val_t imm) { + spl_vm_ins_t x; x.opcode = op; x.type = type; x.imm = imm; @@ -43,8 +43,8 @@ static spl_ins_t ins(uint16_t op, uint16_t type, spl_val_t imm) { /* Build a single-function SIR binary in malloc'd memory. * Returns buffer that must be freed by caller. */ -static unsigned char *build_binary(const char *fname, spl_val_t nargs, const spl_ins_t *instns, - int ninsns, size_t *out_len) { +static unsigned char *build_binary(const char *fname, spl_vm_val_t nargs, + const spl_vm_ins_t *instns, int ninsns, size_t *out_len) { size_t nlen = strlen(fname) + 1; size_t npad = ((nlen + 7) / 8) * 8 - nlen; size_t sz = 8 + 8 + 8 + 8 + 8 + 8 /* magic + 5 counts */ @@ -54,22 +54,22 @@ static unsigned char *build_binary(const char *fname, spl_val_t nargs, const spl unsigned char *p = buf; memcpy(p, "SPLBIN\0\0", 8); - p += 8; /* magic */ - LE64(p, 1); /* nfuncs */ - LE64(p, (spl_val_t)ninsns); /* ninsns */ - LE64(p, 0); /* nnatives */ - LE64(p, 0); /* nstrs */ - LE64(p, 0); /* ndata */ + p += 8; /* magic */ + LE64(p, 1); /* nfuncs */ + LE64(p, (spl_vm_val_t)ninsns); /* ninsns */ + LE64(p, 0); /* nnatives */ + LE64(p, 0); /* nstrs */ + LE64(p, 0); /* ndata */ /* func entry */ - LE64(p, (spl_val_t)nlen); /* name_len */ + LE64(p, (spl_vm_val_t)nlen); /* name_len */ memcpy(p, fname, nlen); p += nlen; memset(p, 0, npad); p += npad; LE64(p, 0); /* idx_of_strtab */ LE64(p, nargs); - LE64(p, (spl_val_t)ninsns); + LE64(p, (spl_vm_val_t)ninsns); LE64(p, 0); /* address = 0 */ for (int i = 0; i < ninsns; i++) { @@ -101,7 +101,7 @@ static int write_temp(const unsigned char *bin, size_t len) { } /* Run a single-function program, return exit code (or -1 on failure). */ -static int run(const spl_ins_t *instns, int ninsns) { +static int run(const spl_vm_ins_t *instns, int ninsns) { size_t len; unsigned char *bin = build_binary("main", 0, instns, ninsns, &len); spl_prog_t prog; @@ -127,7 +127,7 @@ static int run(const spl_ins_t *instns, int ninsns) { } /* Run with native functions registered. */ -static int run_with_natives(const spl_ins_t *instns, int ninsns, spl_native_t *natives, +static int run_with_natives(const spl_vm_ins_t *instns, int ninsns, spl_vm_native_t *natives, int nnatives) { size_t len; unsigned char *bin = build_binary("main", 0, instns, ninsns, &len); @@ -159,7 +159,7 @@ static int run_with_natives(const spl_ins_t *instns, int ninsns, spl_native_t *n * Native function for NCALL tests * ================================================================ */ -static spl_val_t native_add_impl(int nargs, spl_val_t *args) { +static spl_vm_val_t native_add_impl(int nargs, spl_vm_val_t *args) { return (nargs >= 2) ? args[0] + args[1] : 0; } @@ -168,34 +168,34 @@ static spl_val_t native_add_impl(int nargs, spl_val_t *args) { * ================================================================ */ void test_push_imm(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 2) == 42); } void test_dup(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 99), ins(SPL_DUP, SPL_VOID, 0), - ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 99), ins(SPL_DUP, SPL_VOID, 0), + ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 198); } void test_drop(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), - ins(SPL_DROP, SPL_VOID, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), + ins(SPL_DROP, SPL_VOID, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_swap(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), - ins(SPL_SWAP, SPL_VOID, 0), ins(SPL_DROP, SPL_VOID, 0), - ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), + ins(SPL_SWAP, SPL_VOID, 0), ins(SPL_DROP, SPL_VOID, 0), + ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 5) == 2); } void test_pick(void) { /* push 10, 20, 30, pick 1 -> copy 20, add -> 50 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), - ins(SPL_PUSH, SPL_I32, 30), ins(SPL_PICK, SPL_VOID, 1), - ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), + ins(SPL_PUSH, SPL_I32, 30), ins(SPL_PICK, SPL_VOID, 1), + ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 6) == 50); } @@ -204,43 +204,43 @@ void test_pick(void) { * ================================================================ */ void test_add(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 2), ins(SPL_PUSH, SPL_I32, 3), ins(SPL_ADD, SPL_I32, 0), - ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 2), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 5); } void test_sub(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 3), - ins(SPL_SUB, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_SUB, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 7); } void test_mul(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 6), ins(SPL_PUSH, SPL_I32, 7), ins(SPL_MUL, SPL_I32, 0), - ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 6), ins(SPL_PUSH, SPL_I32, 7), + ins(SPL_MUL, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 42); } void test_div(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 100), ins(SPL_PUSH, SPL_I32, 3), - ins(SPL_DIV_S, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 100), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_DIV_S, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 33); } void test_rem(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 100), ins(SPL_PUSH, SPL_I32, 3), - ins(SPL_REM_S, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 100), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_REM_S, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_neg(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_NEG, SPL_I32, 0), - ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_NEG, SPL_I32, 0), + ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 3) == -42); } void test_i64_arith(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I64, 42), ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I64, 42), ins(SPL_RET, SPL_I64, 0)}; TEST_CHECK(run(p, 2) == 42); } @@ -249,45 +249,46 @@ void test_i64_arith(void) { * ================================================================ */ void test_and(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFF00), ins(SPL_PUSH, SPL_U32, 0x0FF0), - ins(SPL_AND, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFF00), ins(SPL_PUSH, SPL_U32, 0x0FF0), + ins(SPL_AND, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 0x0F00); } void test_or(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFF00), ins(SPL_PUSH, SPL_U32, 0x00FF), - ins(SPL_OR, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFF00), ins(SPL_PUSH, SPL_U32, 0x00FF), + ins(SPL_OR, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 0xFFFF); } void test_xor(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF), ins(SPL_PUSH, SPL_U32, 0x0FF0), - ins(SPL_XOR, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF), ins(SPL_PUSH, SPL_U32, 0x0FF0), + ins(SPL_XOR, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 0xF00F); } void test_not(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF0000), ins(SPL_NOT, SPL_U32, 0), - ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF0000), ins(SPL_NOT, SPL_U32, 0), + ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 3) == (unsigned int)0x0000FFFF); } void test_shl(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 1), ins(SPL_PUSH, SPL_U32, 10), - ins(SPL_SHL, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 1), ins(SPL_PUSH, SPL_U32, 10), + ins(SPL_SHL, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1024); } void test_shr(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 1024), ins(SPL_PUSH, SPL_U32, 10), - ins(SPL_SHR_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 1024), ins(SPL_PUSH, SPL_U32, 10), + ins(SPL_SHR_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_shr_s(void) { /* arithmetic right shift: -1024 >> 5 sign-extends */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, (spl_val_t)(int32_t)-1024), ins(SPL_PUSH, SPL_U32, 5), - ins(SPL_SHR_S, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, (spl_vm_val_t)(int32_t)-1024), + ins(SPL_PUSH, SPL_U32, 5), ins(SPL_SHR_S, SPL_I32, 0), + ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == -32); } @@ -296,69 +297,69 @@ void test_shr_s(void) { * ================================================================ */ void test_eq(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_PUSH, SPL_I32, 42), - ins(SPL_EQ, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_PUSH, SPL_I32, 42), + ins(SPL_EQ, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_neq(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_PUSH, SPL_I32, 99), - ins(SPL_NE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 42), ins(SPL_PUSH, SPL_I32, 99), + ins(SPL_NE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_lt(void) { - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), - ins(SPL_SLT, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), + ins(SPL_SLT, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_gt_signed(void) { /* -1 > 1 should be 0 (false) for signed compare */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), - ins(SPL_SGT, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), + ins(SPL_SGT, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 0); } void test_sle(void) { /* -1 <= 1 -> true (1) for signed */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), - ins(SPL_SLE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), + ins(SPL_SLE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_sge(void) { /* -1 >= 1 -> false (0) for signed */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), - ins(SPL_SGE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_I32, 1), + ins(SPL_SGE, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 4) == 0); } void test_ult(void) { /* 0xFFFFFFFF < 1 -> false (0) for unsigned */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), - ins(SPL_ULT, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), + ins(SPL_ULT, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 0); } void test_ule(void) { /* 0xFFFFFFFF <= 0xFFFFFFFF -> true (1) */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), - ins(SPL_ULE, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), + ins(SPL_ULE, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_ugt(void) { /* 0xFFFFFFFF > 1 -> true (1) for unsigned */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), - ins(SPL_UGT, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), + ins(SPL_UGT, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1); } void test_uge(void) { /* 0xFFFFFFFF >= 1 -> true (1) */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), - ins(SPL_UGE, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFFFFFF), ins(SPL_PUSH, SPL_U32, 1), + ins(SPL_UGE, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1); } @@ -369,23 +370,23 @@ void test_uge(void) { void test_jmp(void) { /* push 1, jmp +3 (skip next 2 insns), push 2 (skipped), push 3, add, ret -> 4 */ /* jmp at ip=1, after fetch ip=2, target ip=3 (push 3) => offset = 1 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_JMP, SPL_VOID, 1), - ins(SPL_PUSH, SPL_I32, 2), ins(SPL_PUSH, SPL_I32, 3), - ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_JMP, SPL_VOID, 1), + ins(SPL_PUSH, SPL_I32, 2), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_ADD, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 6) == 4); } void test_bz_bnz(void) { /* push 0, bz +2 (skip to ret with 1) -> return 1 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0), ins(SPL_BZ, SPL_VOID, 2), - ins(SPL_PUSH, SPL_I32, 99), ins(SPL_RET, SPL_I32, 0), - ins(SPL_PUSH, SPL_I32, 1), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0), ins(SPL_BZ, SPL_VOID, 2), + ins(SPL_PUSH, SPL_I32, 99), ins(SPL_RET, SPL_I32, 0), + ins(SPL_PUSH, SPL_I32, 1), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 6) == 1); /* push 1, bnz +2 (skip to ret with 42) -> return 42 */ - spl_ins_t q[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_BNZ, SPL_VOID, 2), - ins(SPL_PUSH, SPL_I32, 99), ins(SPL_RET, SPL_I32, 0), - ins(SPL_PUSH, SPL_I32, 42), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t q[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_BNZ, SPL_VOID, 2), + ins(SPL_PUSH, SPL_I32, 99), ins(SPL_RET, SPL_I32, 0), + ins(SPL_PUSH, SPL_I32, 42), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(q, 6) == 42); } @@ -395,7 +396,7 @@ void test_bz_bnz(void) { void test_alloc_laddr_st64_ld64(void) { /* alloc 1 local, laddr + st64 42, laddr + ld64 back -> 42 */ - spl_ins_t p[] = { + spl_vm_ins_t p[] = { ins(SPL_ALLOC, SPL_VOID, 1), /* 0: alloc 1 local */ ins(SPL_LADDR, SPL_VOID, 0), /* 1: addr of local[0] */ ins(SPL_PUSH, SPL_I64, 42), /* 2: value */ @@ -409,8 +410,8 @@ void test_alloc_laddr_st64_ld64(void) { void test_alloc_zeroed(void) { /* alloc 1 local, laddr + ld64 -> should be 0 (zero-initialized) */ - spl_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 1), ins(SPL_LADDR, SPL_VOID, 0), - ins(SPL_LOAD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 1), ins(SPL_LADDR, SPL_VOID, 0), + ins(SPL_LOAD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; TEST_CHECK(run(p, 4) == 0); } @@ -420,34 +421,34 @@ void test_alloc_zeroed(void) { void test_ld_st64(void) { /* alloc 8 slots, st64 42, ld64 back -> 42 */ - spl_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), - ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 42), - ins(SPL_STORE, SPL_I64, 0), ins(SPL_LOAD, SPL_I64, 0), - ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), + ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 42), + ins(SPL_STORE, SPL_I64, 0), ins(SPL_LOAD, SPL_I64, 0), + ins(SPL_RET, SPL_I64, 0)}; TEST_CHECK(run(p, 7) == 42); } void test_ld_st32(void) { - spl_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), - ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xAABBCCDD), - ins(SPL_STORE, SPL_U32, 0), ins(SPL_LOAD, SPL_U32, 0), - ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), + ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xAABBCCDD), + ins(SPL_STORE, SPL_U32, 0), ins(SPL_LOAD, SPL_U32, 0), + ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 7) == (int)0xAABBCCDD); } void test_ld_st16(void) { - spl_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), - ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xBEEF), - ins(SPL_STORE, SPL_U16, 0), ins(SPL_LOAD, SPL_U16, 0), - ins(SPL_RET, SPL_U16, 0)}; + spl_vm_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), + ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xBEEF), + ins(SPL_STORE, SPL_U16, 0), ins(SPL_LOAD, SPL_U16, 0), + ins(SPL_RET, SPL_U16, 0)}; TEST_CHECK(run(p, 7) == 0xBEEF); } void test_ld_st8(void) { - spl_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), - ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xAB), - ins(SPL_STORE, SPL_U8, 0), ins(SPL_LOAD, SPL_U8, 0), - ins(SPL_RET, SPL_U8, 0)}; + spl_vm_ins_t p[] = {ins(SPL_ALLOC, SPL_VOID, 8), ins(SPL_LADDR, SPL_VOID, 0), + ins(SPL_DUP, SPL_VOID, 0), ins(SPL_PUSH, SPL_I64, 0xAB), + ins(SPL_STORE, SPL_U8, 0), ins(SPL_LOAD, SPL_U8, 0), + ins(SPL_RET, SPL_U8, 0)}; TEST_CHECK(run(p, 7) == 0xAB); } @@ -475,12 +476,12 @@ void test_call_add(void) { * call 2 ip=9 nargs=2 * ret i64 ip=10 */ - spl_ins_t add_insns[] = {ins(SPL_LADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_I64, 0), - ins(SPL_LADDR, SPL_VOID, 8), ins(SPL_LOAD, SPL_I64, 0), - ins(SPL_ADD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; - spl_ins_t main_insns[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), - ins(SPL_PUSH, SPL_VOID, 0), ins(SPL_CALL, SPL_VOID, 2), - ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t add_insns[] = {ins(SPL_LADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_I64, 0), + ins(SPL_LADDR, SPL_VOID, 8), ins(SPL_LOAD, SPL_I64, 0), + ins(SPL_ADD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t main_insns[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), + ins(SPL_PUSH, SPL_VOID, 0), ins(SPL_CALL, SPL_VOID, 2), + ins(SPL_RET, SPL_I64, 0)}; int nadd = (int)(sizeof(add_insns) / sizeof(add_insns[0])); int nmain = (int)(sizeof(main_insns) / sizeof(main_insns[0])); @@ -499,32 +500,32 @@ void test_call_add(void) { memcpy(p, "SPLBIN\0\0", 8); p += 8; LE64(p, 2); - LE64(p, (spl_val_t)ninsns_t); + LE64(p, (spl_vm_val_t)ninsns_t); LE64(p, 0); LE64(p, 0); LE64(p, 0); /* func[0]: "add" */ - LE64(p, (spl_val_t)nlen0); + LE64(p, (spl_vm_val_t)nlen0); memcpy(p, "add", nlen0); p += nlen0; memset(p, 0, npad0); p += npad0; LE64(p, 0); LE64(p, 2); - LE64(p, (spl_val_t)nadd); + LE64(p, (spl_vm_val_t)nadd); LE64(p, 0); /* func[1]: "main" */ - LE64(p, (spl_val_t)nlen1); + LE64(p, (spl_vm_val_t)nlen1); memcpy(p, "main", nlen1); p += nlen1; memset(p, 0, npad1); p += npad1; LE64(p, 0); LE64(p, 0); - LE64(p, (spl_val_t)nmain); - LE64(p, (spl_val_t)nadd); /* address */ + LE64(p, (spl_vm_val_t)nmain); + LE64(p, (spl_vm_val_t)nadd); /* address */ for (int i = 0; i < nadd; i++) { *p++ = (unsigned char)(add_insns[i].opcode); @@ -582,12 +583,12 @@ void test_calli(void) { * calli ip=10 * ret i64 ip=11 */ - spl_ins_t add_insns[] = {ins(SPL_LADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_I64, 0), - ins(SPL_LADDR, SPL_VOID, 8), ins(SPL_LOAD, SPL_I64, 0), - ins(SPL_ADD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; - spl_ins_t main_insns[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), - ins(SPL_PUSH, SPL_VOID, 2), ins(SPL_PUSH, SPL_VOID, 0), - ins(SPL_CALLI, SPL_VOID, 0), ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t add_insns[] = {ins(SPL_LADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_I64, 0), + ins(SPL_LADDR, SPL_VOID, 8), ins(SPL_LOAD, SPL_I64, 0), + ins(SPL_ADD, SPL_I64, 0), ins(SPL_RET, SPL_I64, 0)}; + spl_vm_ins_t main_insns[] = {ins(SPL_PUSH, SPL_I32, 10), ins(SPL_PUSH, SPL_I32, 20), + ins(SPL_PUSH, SPL_VOID, 2), ins(SPL_PUSH, SPL_VOID, 0), + ins(SPL_CALLI, SPL_VOID, 0), ins(SPL_RET, SPL_I64, 0)}; int ninsns_t = 6 + 6; size_t nlen0 = strlen("add") + 1; @@ -602,13 +603,13 @@ void test_calli(void) { memcpy(p, "SPLBIN\0\0", 8); p += 8; LE64(p, 2); - LE64(p, (spl_val_t)ninsns_t); + LE64(p, (spl_vm_val_t)ninsns_t); LE64(p, 0); LE64(p, 0); LE64(p, 0); /* func[0]: add */ - LE64(p, (spl_val_t)nlen0); + LE64(p, (spl_vm_val_t)nlen0); memcpy(p, "add", nlen0); p += nlen0; memset(p, 0, npad0); @@ -619,7 +620,7 @@ void test_calli(void) { LE64(p, 0); /* func[1]: main */ - LE64(p, (spl_val_t)nlen1); + LE64(p, (spl_vm_val_t)nlen1); memcpy(p, "main", nlen1); p += nlen1; memset(p, 0, npad1); @@ -669,8 +670,8 @@ void test_calli(void) { void test_gaddr_ld32(void) { /* Load program, add global data, GADDR + LD32 to read it back */ - spl_ins_t p[] = {ins(SPL_GADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_U32, 0), - ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_GADDR, SPL_VOID, 0), ins(SPL_LOAD, SPL_U32, 0), + ins(SPL_RET, SPL_U32, 0)}; size_t len; unsigned char *bin = build_binary("main", 0, p, 3, &len); spl_prog_t prog; @@ -697,8 +698,8 @@ void test_gaddr_ld32(void) { void test_gaddr_multi(void) { /* Two global data entries: read second one via GADDR 1 */ - spl_ins_t p[] = {ins(SPL_GADDR, SPL_VOID, 1), ins(SPL_LOAD, SPL_U32, 0), - ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_GADDR, SPL_VOID, 1), ins(SPL_LOAD, SPL_U32, 0), + ins(SPL_RET, SPL_U32, 0)}; size_t len; unsigned char *bin = build_binary("main", 0, p, 3, &len); spl_prog_t prog; @@ -731,10 +732,10 @@ void test_gaddr_multi(void) { void test_ncall(void) { /* main() -> i32 { return native_add(30, 12); } */ /* NCALL imm = nargs, native index is pushed separately */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 30), ins(SPL_PUSH, SPL_I32, 12), - ins(SPL_PUSH, SPL_VOID, 0), ins(SPL_NCALL, SPL_I32, 2), - ins(SPL_RET, SPL_I32, 0)}; - spl_native_t nat[] = {{"native_add", 0, native_add_impl}}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 30), ins(SPL_PUSH, SPL_I32, 12), + ins(SPL_PUSH, SPL_VOID, 0), ins(SPL_NCALL, SPL_I32, 2), + ins(SPL_RET, SPL_I32, 0)}; + spl_vm_native_t nat[] = {{"native_add", 0, native_add_impl}}; TEST_CHECK(run_with_natives(p, 5, nat, 1) == 42); } @@ -744,22 +745,22 @@ void test_ncall(void) { void test_trunc(void) { /* push 0xABCD, trunc to 8 bits -> 0xCD */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xABCD), ins(SPL_TRUNC, SPL_U8, 8), - ins(SPL_RET, SPL_U8, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xABCD), ins(SPL_TRUNC, SPL_U8, 8), + ins(SPL_RET, SPL_U8, 0)}; TEST_CHECK(run(p, 3) == 0xCD); } void test_sext(void) { /* push 0x80, sext from 8 bits -> 0xFFFFFF80 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0x80), ins(SPL_SEXT, SPL_I32, 8), - ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 0x80), ins(SPL_SEXT, SPL_I32, 8), + ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 3) == (int)(int8_t)(0x80)); } void test_zext(void) { /* push 0xFFFF, zext from 8 bits -> 0xFF */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF), ins(SPL_ZEXT, SPL_U32, 8), - ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 0xFFFF), ins(SPL_ZEXT, SPL_U32, 8), + ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 3) == 0xFF); } @@ -769,15 +770,15 @@ void test_zext(void) { void test_div_u(void) { /* unsigned: 100 / 3 = 33 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 100), ins(SPL_PUSH, SPL_U32, 3), - ins(SPL_DIV_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 100), ins(SPL_PUSH, SPL_U32, 3), + ins(SPL_DIV_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 33); } void test_rem_u(void) { /* unsigned: 100 % 3 = 1 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 100), ins(SPL_PUSH, SPL_U32, 3), - ins(SPL_REM_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_U32, 100), ins(SPL_PUSH, SPL_U32, 3), + ins(SPL_REM_U, SPL_U32, 0), ins(SPL_RET, SPL_U32, 0)}; TEST_CHECK(run(p, 4) == 1); } @@ -787,15 +788,16 @@ void test_rem_u(void) { void test_many_ops(void) { /* (1+2) * (3+4) = 21 */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), ins(SPL_ADD, SPL_I32, 0), - ins(SPL_PUSH, SPL_I32, 3), ins(SPL_PUSH, SPL_I32, 4), ins(SPL_ADD, SPL_I32, 0), - ins(SPL_MUL, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 1), ins(SPL_PUSH, SPL_I32, 2), + ins(SPL_ADD, SPL_I32, 0), ins(SPL_PUSH, SPL_I32, 3), + ins(SPL_PUSH, SPL_I32, 4), ins(SPL_ADD, SPL_I32, 0), + ins(SPL_MUL, SPL_I32, 0), ins(SPL_RET, SPL_I32, 0)}; TEST_CHECK(run(p, 8) == 21); } void test_halt(void) { /* push 77, halt -> exit code 0 (HALT doesn't pop) */ - spl_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 77), ins(SPL_HALT, SPL_VOID, 0)}; + spl_vm_ins_t p[] = {ins(SPL_PUSH, SPL_I32, 77), ins(SPL_HALT, SPL_VOID, 0)}; TEST_CHECK(run(p, 2) == 0); }