stage0 更改名称spl_ir -> spl_mcode spl_cli提供debug模式 提供临时语言规范

This commit is contained in:
zzy
2026-07-29 12:05:18 +08:00
parent 89d4bae8db
commit a77eade06f
10 changed files with 1224 additions and 476 deletions

View File

@@ -4,23 +4,32 @@
* Built-in syscalls are auto-registered via spl_syscall_register().
*
* Usage:
* spl_cli <file.sir> [entry_point]
* spl_cli [-d] <file.sir> [entry_point]
*/
#include "spl_ir.h"
#include "spl_mcode.h"
#include "spl_syscall.h"
#include "spl_vm.h"
#include <stdio.h>
#include <string.h>
int main(int argc, const char **argv) {
if (argc < 2) {
fprintf(stderr, "Usage: spl_cli <file.sir> [entry_point]\n");
int debug_mode = 0;
int arg_idx = 1;
if (argc >= 2 && strcmp(argv[1], "-d") == 0) {
debug_mode = 1;
arg_idx = 2;
}
if (arg_idx >= argc) {
fprintf(stderr, "Usage: spl_cli [-d] <file.sir> [entry_point]\n");
return 1;
}
const char *path = argv[1];
const char *entry = argc >= 3 ? argv[2] : "main";
const char *path = argv[arg_idx];
const char *entry = argc >= arg_idx + 2 ? argv[arg_idx + 1] : "main";
spl_prog_t prog;
if (spl_prog_load_from_file(path, &prog) != 0) {
@@ -32,6 +41,7 @@ int main(int argc, const char **argv) {
spl_vm_t vm;
spl_vm_init(&vm);
if (debug_mode) spl_vm_set_debug(&vm, 1);
if (spl_vm_load_prog(&vm, &prog) != 0) {
fprintf(stderr, "vm: prog '%s' not found\n", entry);
spl_prog_drop(&prog);

View File

@@ -3,7 +3,7 @@
* Usage: spl_disasm <file.sir>
*/
#include "spl_ir.h"
#include "spl_mcode.h"
#include <stdio.h>
int main(int argc, const char **argv) {

View File

@@ -1,4 +1,4 @@
/* spl_ir.c — SIR binary serialization, deserialization, and utilities
/* spl_mcode.c — SPL VM machine code binary serialization, deserialization, and utilities
*
* Binary format (all metadata fields are spl_val_t = uint64_t LE):
* [HEADER] magic(8) nfuncs(8) ninsns(8) nnatives(8) nstrs(8) ndata(8)
@@ -9,7 +9,7 @@
* [STRTAB] each: slen(8) str(slen bytes, padded to 8)
*/
#include "spl_ir.h"
#include "spl_mcode.h"
void spl_prog_init(spl_prog_t *prog) {
if (!prog)
@@ -445,12 +445,10 @@ const char *opcode_name[] = {
const char *spl_opcode_name(spl_opcode_t opcode) { return opcode_name[opcode]; }
const char *spl_type_tag_name(spl_type_t type) {
switch (type) {
case SPL_VOID:
return "void";
case SPL_I8:
return "i8";
case SPL_U8:
return "u8";
case SPL_VOID: return "void";
case SPL_BOOL: return "bool";
case SPL_I8: return "i8";
case SPL_U8: return "u8";
case SPL_I16:
return "i16";
case SPL_U16:

View File

@@ -1,8 +1,8 @@
/* spl_ir.h - SPL Intermediate Representation: instruction set and binary format
/* spl_mcode.h - SPL VM Machine Code: instruction set and binary format
*/
#ifndef __SPL_IR_H__
#define __SPL_IR_H__
#ifndef __SPL_MCODE_H__
#define __SPL_MCODE_H__
#include "include/core_map.h"
#include "include/core_vec.h"
@@ -14,6 +14,7 @@ typedef intptr_t isize;
typedef enum {
SPL_VOID,
SPL_BOOL,
SPL_I8,
SPL_U8,
SPL_I16,
@@ -220,4 +221,4 @@ const char *spl_type_tag_name(spl_type_t type);
void spl_ins_dump(spl_ins_t *ins, spl_val_t addr);
#endif /* __SPL_IR_H__ */
#endif /* __SPL_MCODE_H__ */

View File

@@ -10,7 +10,7 @@
#include "spl_syscall.h"
#include "include/core_map.h"
#include "include/core_vec.h"
#include "spl_ir.h"
#include "spl_mcode.h"
#include "spl_vm.h"
#include <stdio.h>
@@ -128,7 +128,7 @@ static spl_val_t vm_read_file(int nargs, spl_val_t *args) {
const char *path = (const char *)(uintptr_t)args[0];
if (path == nullptr) {
fprintf(stderr, "filepath can't be null");
return 1;
return 0;
}
FILE *f = fopen(path, "rb");
if (!f) {

View File

@@ -12,7 +12,7 @@
#ifndef __SPL_SYSCALL_H__
#define __SPL_SYSCALL_H__
#include "spl_ir.h"
#include "spl_mcode.h"
/* Register all known built-in syscalls into prog->natives[].
* Entries whose name matches a known syscall get their impl_fn set;

View File

@@ -5,7 +5,7 @@
*/
#include "spl_vm.h"
#include "spl_ir.h"
#include "spl_mcode.h"
#include <stdio.h>
#include <stdlib.h>
@@ -45,6 +45,7 @@ static int spl_type_size(spl_type_t t) {
switch (t) {
case SPL_VOID:
return 0;
case SPL_BOOL:
case SPL_I8:
case SPL_U8:
return 1;
@@ -80,6 +81,16 @@ static int spl_type_size(spl_type_t t) {
return -1; \
} while (0)
#define CHECK_ADDR(addr, label) do { \
if (vm->debug_addr && (uintptr_t)(addr) < 0x1000) { \
fprintf(stderr, "vm: %s at ip=%zd: LOW ADDR=%p sp=%zd fp=%zd\n", \
label, vm->ip - 1, (void*)(uintptr_t)(addr), vm->sp, vm->fp); \
spl_vm_stackdump(vm, vm->sp); \
spl_vm_backtrace(vm, vm->fp); \
vm->exit_code = 1; return -1; \
} \
} while(0)
/* ================================================================
* Stack push/pop (stacks.data is pre-allocated in init)
* ================================================================ */
@@ -547,6 +558,7 @@ void spl_vm_init_ex(spl_vm_t *vm, int stack_size, int call_depth) {
vm->prog = NULL;
vm->trace = 0;
vm->debug = 1;
vm->debug_addr = 0;
vm->exit_code = 0;
}
@@ -584,6 +596,7 @@ void spl_vm_set_debug(spl_vm_t *vm, int enabled) {
if (!vm)
return;
vm->debug = enabled ? 1 : 0;
vm->debug_addr = enabled ? 1 : 0;
}
#define STACK_CANARY(vm) (vm)->stacks.data[(vm)->fp - 1]
@@ -922,6 +935,7 @@ int spl_vm_run_once(spl_vm_t *vm) {
/* ========== Indirect Memory (load/store with types) ========== */
case SPL_LOAD: {
void *_addr = (void *)POP();
CHECK_ADDR(_addr, "LOAD");
spl_val_t _v = 0;
usize _sz = spl_type_size(ins->type);
memcpy(&_v, _addr, _sz);
@@ -936,6 +950,7 @@ int spl_vm_run_once(spl_vm_t *vm) {
case SPL_STORE: {
spl_val_t _v = POP();
void *_addr = (void *)POP();
CHECK_ADDR(_addr, "STORE");
memcpy(_addr, &_v, spl_type_size(ins->type));
break;
}

View File

@@ -4,7 +4,7 @@
#define __SPL_VM_H__
#include "include/core_vec.h"
#include "spl_ir.h"
#include "spl_mcode.h"
#include <stdint.h>
#define SPL_STACK_CANARY ((spl_val_t)0xDEADBEEFCAFEBABEull)
@@ -30,6 +30,7 @@ typedef struct {
int exit_code;
int trace; /* non-zero to print each instruction */
int debug; /* non-zero to enable canary checks */
int debug_addr; /* non-zero to check for low-address memory access */
spl_prog_t *prog;
char error_msg[1024];
struct {