stage1 指针计算类型的错误修复 as运算符优先级的修改 ir2vm的bug修复

This commit is contained in:
zzy committed 2026-09-15 21:24:58 +08:00
1 parent 06f3884c30
commit 09d05e3a34
10 files changed
+191 -60

No files matched your search

+106 -31
View File
@@ -36,21 +36,21 @@
} while (0)
#define SYSCALL_0(name, ret_expr) \
static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \
static spl_vm_val_t name(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) { \
CHECK_NARGS(#name, 0); \
(void)args; \
return (spl_vm_val_t)(uintptr_t)(ret_expr); \
}
#define SYSCALL_1(name, t1, ret_expr) \
static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \
static spl_vm_val_t name(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) { \
CHECK_NARGS(#name, 1); \
t1 a1 = (t1)(uintptr_t)args[0]; \
return (spl_vm_val_t)(uintptr_t)(ret_expr); \
}
#define SYSCALL_2(name, t1, t2, ret_expr) \
static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \
static spl_vm_val_t name(spl_vm_t *_vm, 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]; \
@@ -58,7 +58,7 @@
}
#define SYSCALL_3(name, t1, t2, t3, ret_expr) \
static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \
static spl_vm_val_t name(spl_vm_t *_vm, 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]; \
@@ -67,7 +67,7 @@
}
#define SYSCALL_4(name, t1, t2, t3, t4, ret_expr) \
static spl_vm_val_t name(int nargs, spl_vm_val_t *args) { \
static spl_vm_val_t name(spl_vm_t *_vm, 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]; \
@@ -76,6 +76,42 @@
return (spl_vm_val_t)(uintptr_t)(ret_expr); \
}
/* syscall / VM 内部统一地址检查宏。
* 失败时打印 ctx + 地址 + size + ip,置 native_error,return 0。
* 要求所在函数有可用的 _vm 变量。 */
#define ADDRCHECK(vm, ptr, size, ctx) \
do { \
uintptr_t _acp = (uintptr_t)(ptr); \
usize _acs = (usize)(size); \
if (!spl_vm_addr_valid(_acp, _acs)) { \
fprintf(stderr, "%s: invalid address %p size=%zu (ip=%zu fp=%zu sp=%zu)\n", (ctx), \
(void *)_acp, _acs, (vm)->ip, (vm)->fp, (vm)->sp); \
spl_vm_backtrace((vm), (vm)->fp); \
(vm)->exit_code = 2; \
return 0; \
} \
} while (0)
/* syscall 内部:把当前栈和调用栈打印出来,供出错时定位 */
#define SYSCALL_DUMP(vm) \
do { \
fprintf(stderr, " --- syscall dump (sp=%zu fp=%zu cp=%zu ip=%zu) ---\n", (vm)->sp, \
(vm)->fp, (vm)->cp, (vm)->ip); \
spl_vm_backtrace((vm), (vm)->fp); \
spl_vm_stackdump((vm), (vm)->sp); \
} while (0)
/* syscall 内部:报告致命错误,dump 后让 VM 停在当前 ip */
#define SYSCALL_FAIL(vm, ...) \
do { \
fprintf(stderr, "syscall error: "); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
SYSCALL_DUMP(vm); \
(vm)->exit_code = 1; \
return 0; \
} while (0)
/* =================================================================
* OS syscalls
* ================================================================= */
@@ -108,7 +144,7 @@ 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_vm_val_t vm_fsize(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_fsize(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_fsize", 1);
FILE *f = (FILE *)(uintptr_t)args[0];
long cur = ftell(f);
@@ -123,7 +159,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_vm_val_t vm_read_file(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_read_file(spl_vm_t *_vm, 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) {
@@ -149,28 +185,69 @@ static spl_vm_val_t vm_read_file(int nargs, spl_vm_val_t *args) {
return (spl_vm_val_t)(uintptr_t)buf;
}
/* vm_alloc - allocate memory (malloc) */
SYSCALL_1(vm_alloc, size_t, (uintptr_t)malloc(a1))
static spl_vm_val_t vm_alloc(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_alloc", 1);
size_t sz = (size_t)args[0];
if (sz == 0)
SYSCALL_FAIL(_vm, "vm_alloc: zero size");
if (sz > (size_t)1 << 32)
SYSCALL_FAIL(_vm, "vm_alloc: size too large (%zu)", sz);
void *p = malloc(sz);
if (!p)
SYSCALL_FAIL(_vm, "vm_alloc: malloc(%zu) failed", sz);
return (spl_vm_val_t)(uintptr_t)p;
}
/* vm_free - free memory */
SYSCALL_1(vm_free, void *, (free(a1), (spl_vm_val_t)0))
static spl_vm_val_t vm_free(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
(void)_vm;
CHECK_NARGS("vm_free", 1);
void *p = (void *)(uintptr_t)args[0];
if (p)
free(p);
return 0;
}
/* vm_realloc - reallocate memory (realloc) */
SYSCALL_2(vm_realloc, void *, size_t, (uintptr_t)realloc(a1, a2))
static spl_vm_val_t vm_realloc(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_realloc", 2);
void *p = (void *)(uintptr_t)args[0];
size_t sz = (size_t)args[1];
if (!p)
SYSCALL_FAIL(_vm, "vm_realloc: NULL ptr");
if (sz == 0)
SYSCALL_FAIL(_vm, "vm_realloc: zero size");
ADDRCHECK(_vm, p, 1, "vm_realloc");
void *np = realloc(p, sz);
if (!np)
SYSCALL_FAIL(_vm, "vm_realloc: realloc(%p, %zu) failed", p, sz);
return (spl_vm_val_t)(uintptr_t)np;
}
/* vm_strlen - get string length */
SYSCALL_1(vm_strlen, const char *, strlen(a1))
static spl_vm_val_t vm_memcpy(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_memcpy", 3);
void *dst = (void *)(uintptr_t)args[0];
const void *src = (const void *)(uintptr_t)args[1];
size_t size = (size_t)args[2];
if (size == 0)
return (spl_vm_val_t)(uintptr_t)dst;
ADDRCHECK(_vm, dst, size, "vm_memcpy(dst)");
ADDRCHECK(_vm, src, size, "vm_memcpy(src)");
memcpy(dst, src, size);
return (spl_vm_val_t)(uintptr_t)dst;
}
/* vm_strcmp - compare two strings */
SYSCALL_2(vm_strcmp, const char *, const char *, strcmp(a1, a2))
static spl_vm_val_t vm_memcmp(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_memcmp", 3);
const void *a = (const void *)(uintptr_t)args[0];
const void *b = (const void *)(uintptr_t)args[1];
size_t size = (size_t)args[2];
if (size == 0)
return 0;
ADDRCHECK(_vm, a, size, "vm_memcmp(a)");
ADDRCHECK(_vm, b, size, "vm_memcmp(b)");
return (spl_vm_val_t)memcmp(a, b, size);
}
/* vm_memcpy - copy memory, returns dst */
SYSCALL_3(vm_memcpy, void *, const void *, size_t, (memcpy(a1, a2, a3), (uintptr_t)a1))
/* vm_memcmp - compare two memory */
SYSCALL_3(vm_memcmp, void *, const void *, size_t, (memcmp(a1, a2, a3), (uintptr_t)a1))
static spl_vm_val_t vm_printf(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_printf(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
if (nargs <= 0)
return 0;
@@ -245,7 +322,7 @@ static spl_vm_val_t vm_printf(int nargs, spl_vm_val_t *args) {
* ================================================================= */
/* vm_new - create a new sub-VM instance, returns spl_vm_t* */
static spl_vm_val_t vm_new(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_new(spl_vm_t *_vm, 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));
@@ -256,7 +333,7 @@ static spl_vm_val_t vm_new(int nargs, spl_vm_val_t *args) {
}
/* vm_drop - destroy a sub-VM and its loaded program */
static spl_vm_val_t vm_drop(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_drop(spl_vm_t *_vm, 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)
@@ -272,7 +349,7 @@ static spl_vm_val_t vm_drop(int nargs, spl_vm_val_t *args) {
}
/* vm_load - load a .sir file, register syscalls, return spl_prog_t* */
static spl_vm_val_t vm_load(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_load(spl_vm_t *_vm, 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];
@@ -296,7 +373,7 @@ static spl_vm_val_t vm_load(int nargs, spl_vm_val_t *args) {
}
/* vm_push - push a value onto the sub-VM's stack (for passing arguments) */
static spl_vm_val_t vm_push(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_push(spl_vm_t *_vm, int nargs, spl_vm_val_t *args) {
CHECK_NARGS("vm_push", 2);
spl_vm_t *vm = (spl_vm_t *)(uintptr_t)args[0];
spl_vm_val_t val = args[1];
@@ -321,7 +398,7 @@ static spl_vm_val_t vm_push(int nargs, spl_vm_val_t *args) {
* - Sets fp = sp - nargs (so arg0 = data[fp], arg1 = data[fp+1], ...)
* - Sets ip to the function address
*/
static spl_vm_val_t vm_call(int nargs, spl_vm_val_t *args) {
static spl_vm_val_t vm_call(spl_vm_t *_vm, 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];
@@ -387,8 +464,6 @@ void spl_syscall_register(spl_prog_t *prog) {
{"vm_alloc", 0, vm_alloc},
{"vm_free", 0, vm_free},
{"vm_realloc", 0, vm_realloc},
{"vm_strlen", 0, vm_strlen},
{"vm_strcmp", 0, vm_strcmp},
{"vm_memcpy", 0, vm_memcpy},
{"vm_memcmp", 0, vm_memcmp},
{"vm_printf", 0, vm_printf},