stage2 修复大量AI生成的风格问题 stage1 修复对于vm abi的错误生成
This commit is contained in:
1 parent
0e38858785
commit
76f980654c
40 files changed
+619
-938
No files matched your search
+29
-47
@@ -1,28 +1,15 @@
|
||||
// Expect retcode = 0
|
||||
|
||||
// SPL VM 机器码容器(移植自 stage0/spl_mcode.c 的构建/序列化/dump 部分)。
|
||||
// 只负责「内存中的 prog」与「写入 .sir」,不包含反序列化(由 C 侧 spl_cli 读)。
|
||||
//
|
||||
// 字符串一律是 ByteView(借用上层 IR/attr 的名称,本模块不复制、不释放);
|
||||
// gdata 条目是 ByteBuffer,由本模块拥有并释放。
|
||||
//
|
||||
// 二进制格式(元数据字段均为 u64 小端):
|
||||
// [HEADER] magic(8) nfuncs(8) ninsns(8) nnatives(8) nstrs(8) ndata(8)
|
||||
// [FUNCS] 每项: name_len(8) name(pad8, 含结尾 NUL) idx_of_strtab(8)
|
||||
// nargs(8) ninsns(8) address(8)
|
||||
// [INSTRS] 每项: opcode(2) type(2) imm(8) = 12 字节
|
||||
// [NATIVES] 每项: name_len(8) name(pad8, 含结尾 NUL) idx_of_strtab(8)
|
||||
// [STRTAB] 每项: slen(8) str(pad8)
|
||||
// [GDATA] 每项: dsize(8) data(pad8)
|
||||
// VM 字节码容器:内存中的 Prog 与 .sir 序列化(反序列化在 C 侧 spl_cli)。
|
||||
// 字符串用 ByteView 借用、不拥有;gdata 条目为 ByteBuffer,由本模块拥有释放。
|
||||
|
||||
type .{ .Error, .Status, .make } = @import("utils/error.spl");
|
||||
type .{ .Vec } = @import("utils/vec.spl");
|
||||
type .{ .ByteView } = @import("utils/byte_view.spl");
|
||||
type .{ .ByteBuffer } = @import("utils/byte_buffer.spl");
|
||||
type .{ .append_usize, .append_i64 } = @import("utils/fmt.spl");
|
||||
type Mem = @import("sys/mem.spl");
|
||||
type File = @import("sys/file.spl");
|
||||
type .{ .open_cstr, .write_all, .read_all } = @import("utils/io.spl");
|
||||
type Mem = @import("utils/memory.spl");
|
||||
type .{ .open_cstr, .write_all, .read_all, .File } = @import("utils/io.spl");
|
||||
|
||||
type Op = enum {
|
||||
Error,
|
||||
@@ -208,7 +195,6 @@ fn kind_name(k: VmKind): []u8 {
|
||||
ret "???";
|
||||
}
|
||||
|
||||
// ---- 生命周期 ----
|
||||
|
||||
fn new(): ProgResult {
|
||||
var prog = Prog {
|
||||
@@ -264,7 +250,6 @@ fn drop(self: *Prog) {
|
||||
Vec.drop(&self.insns);
|
||||
}
|
||||
|
||||
// ---- 构建 ----
|
||||
|
||||
fn add_instr(self: *Prog, op: Op, ty: VmKind, imm: usize): usize {
|
||||
var i = self.insns.len;
|
||||
@@ -306,7 +291,7 @@ fn add_data(self: *Prog, ptr: usize, size: usize): usize {
|
||||
}
|
||||
if size != 0 {
|
||||
if ptr == 0 { ByteBuffer.drop(&entry); ret 0; }
|
||||
ignore_ptr(Mem.copy(entry.storage.data as *any, ptr as *any, size));
|
||||
Mem.copy(entry.storage.data as *any, ptr as *any, size);
|
||||
entry.storage.len = size;
|
||||
}
|
||||
match Vec.push(&self.gdata, &entry as *u8) {
|
||||
@@ -353,7 +338,6 @@ fn get_or_add_native(self: *Prog, name: ByteView): isize {
|
||||
ret (self.natives.len - 1) as isize;
|
||||
}
|
||||
|
||||
// ---- dump(输出必须与 stage0 spl_prog_dump 逐字节一致)----
|
||||
|
||||
fn out_s(out: *ByteBuffer, s: []u8): bool {
|
||||
match ByteBuffer.append(out, s) { .Ok => { ret true; }, .Err(error) => { ret false; } }
|
||||
@@ -470,21 +454,23 @@ fn dump(self: *Prog, out: *ByteBuffer): bool {
|
||||
if !out_s(out, " ") { ret false; }
|
||||
if !out_i(out, ins.imm as i64) { ret false; }
|
||||
|
||||
if @enum2int(ins.opcode) == @enum2int(Op.Jmp) ||
|
||||
@enum2int(ins.opcode) == @enum2int(Op.Bz) ||
|
||||
@enum2int(ins.opcode) == @enum2int(Op.Bnz) {
|
||||
if !out_s(out, " ; -> ") { ret false; }
|
||||
if !out_u(out, i + 1 + ins.imm) { ret false; }
|
||||
} else if @enum2int(ins.opcode) == @enum2int(Op.Call) {
|
||||
if !out_s(out, " ; nargs=") { ret false; }
|
||||
if !out_u(out, ins.imm) { ret false; }
|
||||
if !out_s(out, ", from stack") { ret false; }
|
||||
} else if @enum2int(ins.opcode) == @enum2int(Op.Calli) {
|
||||
if !out_s(out, " ; indirect call") { ret false; }
|
||||
} else if @enum2int(ins.opcode) == @enum2int(Op.Gaddr) {
|
||||
if !out_s(out, " ; gdata[") { ret false; }
|
||||
if !out_u(out, ins.imm) { ret false; }
|
||||
if !out_s(out, "]") { ret false; }
|
||||
match ins.opcode {
|
||||
.Jmp, .Bz, .Bnz => {
|
||||
if !out_s(out, " ; -> ") { ret false; }
|
||||
if !out_u(out, i + 1 + ins.imm) { ret false; }
|
||||
},
|
||||
.Call => {
|
||||
if !out_s(out, " ; nargs=") { ret false; }
|
||||
if !out_u(out, ins.imm) { ret false; }
|
||||
if !out_s(out, ", from stack") { ret false; }
|
||||
},
|
||||
.Calli => { if !out_s(out, " ; indirect call") { ret false; } },
|
||||
.Gaddr => {
|
||||
if !out_s(out, " ; gdata[") { ret false; }
|
||||
if !out_u(out, ins.imm) { ret false; }
|
||||
if !out_s(out, "]") { ret false; }
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
if !out_s(out, "\n") { ret false; }
|
||||
i = i + 1;
|
||||
@@ -513,14 +499,13 @@ fn str_at(self: *Prog, i: usize): ByteView {
|
||||
ret ByteView.empty();
|
||||
}
|
||||
|
||||
// ---- 序列化 ----
|
||||
|
||||
fn align8(n: usize): usize {
|
||||
ret (n + 7) & (~(7 as usize));
|
||||
}
|
||||
|
||||
// 说明:以下 put_* 直接写入已预留容量的 ByteBuffer 存储(store 已按精确总大小 reserve),
|
||||
// 跳过 ByteBuffer.append → Vec.append 的校验/拷贝路径。若容量不足会越界,故 store 先校验容量。
|
||||
// put_* 直接写入已预留容量的 ByteBuffer 存储(store 已按精确总大小 reserve),跳过
|
||||
// append 的校验/拷贝;容量不足会越界,故 store 先校验容量。
|
||||
|
||||
fn put_u8(out: *ByteBuffer, b: u8): bool {
|
||||
out.storage.data[out.storage.len] = b;
|
||||
@@ -545,7 +530,7 @@ fn put_u64(out: *ByteBuffer, v: usize): bool {
|
||||
|
||||
fn put_zeros(out: *ByteBuffer, n: usize): bool {
|
||||
if n != 0 {
|
||||
ignore_ptr(Mem.set((out.storage.data + out.storage.len) as *any, 0, n));
|
||||
Mem.set((out.storage.data + out.storage.len) as *any, 0, n);
|
||||
out.storage.len = out.storage.len + n;
|
||||
}
|
||||
ret true;
|
||||
@@ -602,7 +587,7 @@ fn encode(self: *Prog, out: *ByteBuffer): Status {
|
||||
total = total + 8 + align8(e.storage.len);
|
||||
fi = fi + 1;
|
||||
}
|
||||
match ByteBuffer.reserve(out, total) { .Ok => {}, .Err(error) => {} }
|
||||
ByteBuffer.reserve(out, total);
|
||||
if out.storage.cap < total || out.storage.data == null { ret .Err(make(.Io)); }
|
||||
|
||||
if !put_view(out, ByteView.from_slice("SPLBIN")) { ret .Err(make(.Io)); }
|
||||
@@ -702,10 +687,7 @@ fn serialize(self: *Prog, out: *ByteBuffer): Status {
|
||||
ret encode(self, out);
|
||||
}
|
||||
|
||||
fn ignore_ptr(p: *any) {}
|
||||
fn ignore_usize(v: usize) {}
|
||||
|
||||
// ---- 测试 ----
|
||||
|
||||
fn test_dump_basic() {
|
||||
var pr: Prog = undefined;
|
||||
@@ -715,7 +697,7 @@ fn test_dump_basic() {
|
||||
}
|
||||
defer { drop(&pr); }
|
||||
|
||||
ignore_usize(add_instr(&pr, .Halt, .Void, 0));
|
||||
add_instr(&pr, .Halt, .Void, 0);
|
||||
|
||||
var out = ByteBuffer.new();
|
||||
defer { ByteBuffer.drop(&out); }
|
||||
@@ -763,8 +745,8 @@ fn test_store_roundtrip() {
|
||||
}
|
||||
defer { drop(&pr); }
|
||||
|
||||
ignore_usize(add_func(&pr, ByteView.from_slice("main"), 0, 0));
|
||||
ignore_usize(add_instr(&pr, .Halt, .Void, 0));
|
||||
add_func(&pr, ByteView.from_slice("main"), 0, 0);
|
||||
add_instr(&pr, .Halt, .Void, 0);
|
||||
|
||||
var path = ByteView.from_slice("build/_mcode_roundtrip.tmp");
|
||||
match store(&pr, path) {
|
||||
|
||||
Reference in new issue
Block a user