/* spl_vm.h - SIR interpreter */ #ifndef __SPL_VM_H__ #define __SPL_VM_H__ #include "include/core_vec.h" #include "spl_mcode.h" #include #define SPL_STACK_CANARY ((spl_vm_val_t)0xDEADBEEFCAFEBABEull) typedef struct { uintptr_t saved_sp; uintptr_t saved_fp; uintptr_t saved_ip; spl_vm_val_t nargs; } spl_callframe_t; typedef VEC(spl_vm_val_t) spl_stack_vec_t; typedef VEC(spl_callframe_t) spl_frame_vec_t; typedef struct { spl_stack_vec_t stacks; spl_frame_vec_t frames; uintptr_t gp; // global pointer uintptr_t sp; // stack pointer uintptr_t fp; // frame pointer uintptr_t cp; // call pointer uintptr_t ip; // instr pointer 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 */ int skip_bp; /* non-zero: run_once 忽略下一次断点(continue 越过当前断点指令) */ VEC(usize) breakpoints; /* ip 断点(执行到该指令前暂停,run_once 返回 2) */ VEC(char *) fn_breakpoints; /* 函数名断点(CALL/CALLI 目标函数入口暂停) */ spl_prog_t *prog; char error_msg[1024]; struct { uintptr_t max_stack_depth; uintptr_t max_call_depth; } config; } spl_vm_t; /* Initialize VM with default sizes (SPL_DEFAULT_STACK_SIZE / * SPL_DEFAULT_CALL_DEPTH) */ void spl_vm_init(spl_vm_t *vm); /* Initialize VM with custom sizes (pass 0 to use defaults) */ void spl_vm_init_ex(spl_vm_t *vm, int stack_size, int call_depth); /* Free dynamically allocated memory in VM */ void spl_vm_drop(spl_vm_t *vm); int spl_vm_load_prog(spl_vm_t *vm, spl_prog_t *prog); int spl_vm_prepare(spl_vm_t *vm, const char *entry, int argc, const char **argv, const char **envp); /* Enable/disable instruction-level tracing */ void spl_vm_set_trace(spl_vm_t *vm, int enabled); /* Enable/disable debug mode (stack canary protection) */ void spl_vm_set_debug(spl_vm_t *vm, int enabled); int spl_vm_run_once(spl_vm_t *vm); int spl_vm_run_until(spl_vm_t *vm, size_t step); /* 断点:ip 断点 / 函数名断点(CALL/CALLI 目标函数入口)。命中时 run_once 返回 2。 */ void spl_vm_add_breakpoint(spl_vm_t *vm, usize ip); void spl_vm_add_breakpoint_fn(spl_vm_t *vm, const char *name); 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_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__ */