From a1e684f6d4e002e60eea84e15f261379a0327279 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Mon, 14 Sep 2026 16:01:33 +0800 Subject: [PATCH] =?UTF-8?q?stage0=20=E4=BF=AE=E5=A4=8D=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage0/spl_mcode.c | 11 +++--- stage0/spl_syscall.c | 81 ++++++++++++++++++++++++-------------------- stage0/spl_vm.c | 10 ++++-- 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/stage0/spl_mcode.c b/stage0/spl_mcode.c index 18f246b..a4afbfd 100644 --- a/stage0/spl_mcode.c +++ b/stage0/spl_mcode.c @@ -19,6 +19,7 @@ void spl_prog_init(spl_prog_t *prog) { vec_init(prog->natives); vec_init(prog->strtab); vec_init(prog->gdata); + vec_push(prog->gdata, (spl_vm_gdata_t){0}); map_init(prog->symtab, MAP_HASH_STR, MAP_CMP_STR); 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); nnatives = vec_size(prog->natives); nstrs = vec_size(prog->strtab); - ndata = vec_size(prog->gdata); + ndata = vec_size(prog->gdata) - 1; /* jump 0 node */ /* Calculate total size */ total = 8 /* magic */ @@ -325,7 +326,7 @@ int spl_prog_store_to_file(const char *fname, spl_prog_t *prog) { } /* gdata */ - for (i = 0; i < ndata; i++) { + for (i = 1; i < vec_size(prog->gdata); i++) { usize dsize = vec_at(prog->gdata, i).size; 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 ---- */ - for (i = 0; i < ndata; i++) { + for (i = 1; i <= ndata; i++) { spl_vm_gdata_t *entry = &vec_at(prog->gdata, i); pad = ALIGN8(entry->size) - 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); entry.size = size; 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) { @@ -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(" %zd:%zx", ins->imm, ins->imm); printf("\n"); -} +} \ No newline at end of file diff --git a/stage0/spl_syscall.c b/stage0/spl_syscall.c index ef0ceac..feac9dd 100644 --- a/stage0/spl_syscall.c +++ b/stage0/spl_syscall.c @@ -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)) static spl_vm_val_t vm_printf(int nargs, spl_vm_val_t *args) { - (void)args; - if (nargs <= 0) { + if (nargs <= 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; string_builder_t buffer; vec_init(buffer); - if (nargs <= 1) { - printf("%s", fmt); - return nargs; - } - int arg_idx = 0; + + int arg_idx = 1; /* 0 是 format */ char tmp_buf[32]; - memset(tmp_buf, 0, sizeof(tmp_buf)); + for (usize i = 0; i < fmt_len; ++i) { if (fmt[i] != '%') { vec_push(buffer, fmt[i]); continue; } - arg_idx += 1; - 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]); - } + if (++i >= fmt_len) 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': vec_push(buffer, (char)args[arg_idx]); + arg_idx++; break; - case 's': - for (usize j = 0; j < strlen((const char *)args[arg_idx]); ++j) { - vec_push(buffer, ((const char *)args[arg_idx])[j]); - } + case 's': { + const spl_vm_val_t *s = (const spl_vm_val_t *)args[arg_idx]; + 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; + } 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); - return nargs; + return (spl_vm_val_t)nargs; } /* ================================================================= diff --git a/stage0/spl_vm.c b/stage0/spl_vm.c index 2f7633b..7950489 100644 --- a/stage0/spl_vm.c +++ b/stage0/spl_vm.c @@ -328,6 +328,9 @@ static int spl_type_size(spl_vm_kind_t t) { _r = _da OP _db; \ break; \ } \ + case SPL_BOOL: \ + _r = (uint8_t)_a OP(uint8_t) _b; \ + break; \ default: \ _r = 0; \ break; \ @@ -1018,9 +1021,12 @@ int spl_vm_run_once(spl_vm_t *vm) { case SPL_GADDR: { 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"); - 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; }