stage0 修复部分问题

This commit is contained in:
zzy committed 2026-09-14 16:01:33 +08:00
1 parent 5073c2b3ea
commit a1e684f6d4
3 files changed
+58 -44

No files matched your search

+6 -5
View File
@@ -19,6 +19,7 @@ void spl_prog_init(spl_prog_t *prog) {
vec_init(prog->natives); vec_init(prog->natives);
vec_init(prog->strtab); vec_init(prog->strtab);
vec_init(prog->gdata); vec_init(prog->gdata);
vec_push(prog->gdata, (spl_vm_gdata_t){0});
map_init(prog->symtab, MAP_HASH_STR, MAP_CMP_STR); map_init(prog->symtab, MAP_HASH_STR, MAP_CMP_STR);
prog->debug = NULL; prog->debug = NULL;
} }
@@ -296,7 +297,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
ninsns = vec_size(prog->insns); ninsns = vec_size(prog->insns);
nnatives = vec_size(prog->natives); nnatives = vec_size(prog->natives);
nstrs = vec_size(prog->strtab); nstrs = vec_size(prog->strtab);
ndata = vec_size(prog->gdata); ndata = vec_size(prog->gdata) - 1; /* jump 0 node */
/* Calculate total size */ /* Calculate total size */
total = 8 /* magic */ total = 8 /* magic */
@@ -325,7 +326,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
} }
/* gdata */ /* gdata */
for (i = 0; i < ndata; i++) { for (i = 1; i < vec_size(prog->gdata); i++) {
usize dsize = vec_at(prog->gdata, i).size; usize dsize = vec_at(prog->gdata, i).size;
total += 8 + ALIGN8(dsize); /* dsize + data(pad) */ total += 8 + ALIGN8(dsize); /* dsize + data(pad) */
} }
@@ -398,7 +399,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) {
} }
/* ---- global data ---- */ /* ---- global data ---- */
for (i = 0; i < ndata; i++) { for (i = 1; i <= ndata; i++) {
spl_vm_gdata_t *entry = &vec_at(prog->gdata, i); spl_vm_gdata_t *entry = &vec_at(prog->gdata, i);
pad = ALIGN8(entry->size) - entry->size; pad = ALIGN8(entry->size) - entry->size;
wr64(&p, entry->size); wr64(&p, entry->size);
@@ -452,7 +453,7 @@ int spl_prog_add_data(spl_prog_t *prog, void *ptr, usize size) {
memcpy(entry.data, ptr, size); memcpy(entry.data, ptr, size);
entry.size = size; entry.size = size;
vec_push(prog->gdata, entry); vec_push(prog->gdata, entry);
return vec_size(prog->gdata); return (int)(vec_size(prog->gdata) - 1);
} }
spl_vm_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) {
@@ -528,4 +529,4 @@ void spl_vm_ins_dump(spl_vm_ins_t *ins, spl_vm_val_t addr) {
printf(" %s", spl_vm_type_kind_name((spl_vm_kind_t)ins->type)); printf(" %s", spl_vm_type_kind_name((spl_vm_kind_t)ins->type));
printf(" %zd:%zx", ins->imm, ins->imm); printf(" %zd:%zx", ins->imm, ins->imm);
printf("\n"); printf("\n");
} }
+44 -37
View File
@@ -168,63 +168,70 @@ SYSCALL_2(vm_strcmp, const char *, const char *, strcmp(a1, a2))
SYSCALL_3(vm_memcpy, void *, const void *, size_t, (memcpy(a1, a2, a3), (uintptr_t)a1)) SYSCALL_3(vm_memcpy, void *, const void *, size_t, (memcpy(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(int nargs, spl_vm_val_t *args) {
(void)args; if (nargs <= 0)
if (nargs <= 0) {
return 0; return 0;
/* args[0] 是 SPL 的 []u8 format 参数。VM 里 slice 作为参数传递时,
栈上压的是"指向 slice 结构体的指针",结构为 {ptr:*u8, len:u64} */
const spl_vm_val_t *fmt_slice = (const spl_vm_val_t *)args[0];
const char *fmt = (const char *)fmt_slice[0];
usize fmt_len = (usize)fmt_slice[1];
if (nargs <= 1) {
fwrite(fmt, 1, fmt_len, stdout);
return (spl_vm_val_t)nargs;
} }
const char *fmt = (const char *)args[0];
usize fmt_len = strlen(fmt);
typedef VEC(char) string_builder_t; typedef VEC(char) string_builder_t;
string_builder_t buffer; string_builder_t buffer;
vec_init(buffer); vec_init(buffer);
if (nargs <= 1) {
printf("%s", fmt); int arg_idx = 1; /* 0 是 format */
return nargs;
}
int arg_idx = 0;
char tmp_buf[32]; char tmp_buf[32];
memset(tmp_buf, 0, sizeof(tmp_buf));
for (usize i = 0; i < fmt_len; ++i) { for (usize i = 0; i < fmt_len; ++i) {
if (fmt[i] != '%') { if (fmt[i] != '%') {
vec_push(buffer, fmt[i]); vec_push(buffer, fmt[i]);
continue; continue;
} }
arg_idx += 1; if (++i >= fmt_len)
if (++i >= fmt_len) {
continue;
}
switch (fmt[i]) {
case '.': {
Assert(i + 2 < fmt_len && arg_idx + 1 <= nargs && fmt[i + 1] == '*' &&
fmt[i + 2] == 's');
for (usize j = 0; j < args[arg_idx]; ++j) {
vec_push(buffer, ((const char *)args[arg_idx + 1])[j]);
}
arg_idx += 1; /* %.*s 消耗 2 个实参(len, data),遇 % 已 +1,这里补 1 */
i += 2;
} break;
case 'd':
snprintf(tmp_buf, sizeof(tmp_buf), "%zd", args[arg_idx]);
for (usize j = 0; j < strlen(tmp_buf); ++j) {
vec_push(buffer, tmp_buf[j]);
}
break; break;
if (arg_idx >= nargs)
break;
switch (fmt[i]) {
case 'd': {
memset(tmp_buf, 0, sizeof(tmp_buf));
snprintf(tmp_buf, sizeof(tmp_buf), "%zd", (isize)args[arg_idx]);
for (usize j = 0; tmp_buf[j] != '\0'; ++j)
vec_push(buffer, tmp_buf[j]);
arg_idx++;
break;
}
case 'c': case 'c':
vec_push(buffer, (char)args[arg_idx]); vec_push(buffer, (char)args[arg_idx]);
arg_idx++;
break; break;
case 's': case 's': {
for (usize j = 0; j < strlen((const char *)args[arg_idx]); ++j) { const spl_vm_val_t *s = (const spl_vm_val_t *)args[arg_idx];
vec_push(buffer, ((const char *)args[arg_idx])[j]); const char *p = (const char *)s[0];
} usize l = (usize)s[1];
for (usize j = 0; j < l; ++j)
vec_push(buffer, p[j]);
arg_idx++;
break; break;
}
default: default:
continue; vec_push(buffer, '%');
vec_push(buffer, fmt[i]);
break;
} }
} }
vec_push(buffer, '\0');
printf("%s", buffer.data); if (vec_size(buffer) > 0)
fwrite(buffer.data, 1, vec_size(buffer), stdout);
vec_free(buffer); vec_free(buffer);
return nargs; return (spl_vm_val_t)nargs;
} }
/* ================================================================= /* =================================================================
+8 -2
View File
@@ -328,6 +328,9 @@ static int spl_type_size(spl_vm_kind_t t) {
_r = _da OP _db; \ _r = _da OP _db; \
break; \ break; \
} \ } \
case SPL_BOOL: \
_r = (uint8_t)_a OP(uint8_t) _b; \
break; \
default: \ default: \
_r = 0; \ _r = 0; \
break; \ break; \
@@ -1018,9 +1021,12 @@ int spl_vm_run_once(spl_vm_t *vm) {
case SPL_GADDR: { case SPL_GADDR: {
spl_vm_val_t _idx = ins->imm; spl_vm_val_t _idx = ins->imm;
if (_idx >= vec_size(prog->gdata)) if (_idx == 0 || _idx >= vec_size(prog->gdata))
VM_ERROR("GADDR: global data index out of range"); VM_ERROR("GADDR: global data index out of range");
PUSH((spl_vm_val_t)(uintptr_t)vec_at(prog->gdata, _idx).data); spl_vm_gdata_t *gd = &vec_at(prog->gdata, _idx);
if (!gd->data)
VM_ERROR("GADDR: null gdata entry");
PUSH((spl_vm_val_t)(uintptr_t)gd->data);
break; break;
} }