stage0 更改名称spl_ir -> spl_mcode spl_cli提供debug模式 提供临时语言规范
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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:
|
||||
@@ -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__ */
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user