stage2 修复大量AI生成的风格问题 stage1 修复对于vm abi的错误生成

This commit is contained in:
zzy committed 2026-10-03 15:05:55 +08:00
1 parent 0e38858785
commit 76f980654c
40 files changed
+619 -938

No files matched your search

+25 -44
View File
@@ -1,11 +1,7 @@
// Expect retcode = 0
// IR -> VM 机器码(移植自 stage1/spl_ir2vm.c)。
// 依赖:IR(ir.spl)、IR 类型表(type_table.spl)、布局(layout.spl)、
// 属性(attr.spl)、字节码容器(mcode.spl)。
//
// extern_native 用「按函数 ref 下标的 isize 数组」代替 stage1 的 map:
// 默认 -1 表示非 extern,>=0 表示 native 索引(语义等价)。
// IR -> VM 字节码。extern_native 是按函数 ref 下标的 isize 数组:-1 非 extern,
// >=0 为 native 索引。
type .{ .Vec } = @import("utils/vec.spl");
type .{ .ByteView } = @import("utils/byte_view.spl");
@@ -19,7 +15,7 @@ type IrM = @import("./ir.spl");
type .{ .Ir, .IrFunc, .IrEntry, .Global } = @import("./ir.spl");
type Mcode = @import("./mcode.spl");
type .{ .Prog, .Op, .VmKind, .VmIns, .VmFunc } = @import("./mcode.spl");
type Mem = @import("sys/mem.spl");
type Mem = @import("utils/memory.spl");
type Ir2Vm = @self;
@@ -31,7 +27,6 @@ extern_native: Vec, // isize
global_gaddr: Vec, // usize:每个全局变量在 prog.gdata 的下标
prog: Prog,
// ---- 类型/布局查询 ----
fn info_of(ctx: *Ir2Vm, tid: usize): *LayoutM.LayoutInfo {
ret LayoutM.info_of(ctx.layout, tid);
@@ -187,7 +182,6 @@ fn ir_result_tid(ctx: *Ir2Vm, n: *IrEntry): usize {
ret 0;
}
// ---- 小工具 ----
// 内部热路径:假定索引有效,直接取址(省去 Vec.get/valid)。
fn usize_at(v: *Vec, i: usize): usize {
@@ -195,7 +189,7 @@ fn usize_at(v: *Vec, i: usize): usize {
}
fn push_usize(v: *Vec, x: usize) {
ignore_bool(Vec.push_raw(v, &x as *u8));
Vec.push_raw(v, &x as *u8);
}
fn fnode(f: *IrFunc, i: usize): *IrEntry {
@@ -239,7 +233,6 @@ fn const_fn(n: *IrEntry): usize {
ret 0;
}
// ---- extern ----
fn fn_check_extern(ctx: *Ir2Vm, f: *IrFunc): bool {
if ctx.attr == null || f == null { ret false; }
@@ -275,7 +268,6 @@ fn extern_set(ctx: *Ir2Vm, ref: usize, value: isize) {
}
}
// ---- 帧布局 ----
type Slot = struct {
result_off: usize,
@@ -363,7 +355,7 @@ fn frame_build(fl: *FrameLayout, ctx: *Ir2Vm, fid: usize) {
var i: usize = 0;
while i < n {
var blank: Slot = .{ .result_off = 0, .data_off = 0 };
ignore_bool(Vec.push_raw(&fl.slots, &blank as *u8));
Vec.push_raw(&fl.slots, &blank as *u8);
i = i + 1;
}
@@ -397,7 +389,6 @@ fn frame_drop(fl: *FrameLayout) {
Vec.drop(&fl.slots);
}
// ---- cgen ----
type FixKind = enum {
Jmp,
@@ -432,7 +423,7 @@ fn emit(cg: *Cgen, op: Op, ty: VmKind, imm: usize) {
prog.insns.len = i + 1;
ret;
}
ignore_usize(Mcode.add_instr(prog, op, ty, imm));
Mcode.add_instr(prog, op, ty, imm);
}
fn ip_of(cg: *Cgen): usize {
@@ -534,7 +525,7 @@ fn cg_add_fix(cg: *Cgen, ins_idx: usize, kind: FixKind, node_target: usize, fn_t
.node_target = node_target,
.fn_target = fn_target,
};
match Vec.push(cg.fixups, &fx as *u8) { .Ok => {}, .Err(error) => {} }
Vec.push(cg.fixups, &fx as *u8);
}
fn arith_tid(n: *IrEntry): usize {
@@ -696,7 +687,7 @@ fn cg_cast(cg: *Cgen, ref: usize, n: *IrEntry) {
} else if f_bool && t_int {
emit(cg, .Zext, .Void, 1);
}
ignore_bool(t_bool);
t_bool;
cg_store_slot(cg, ref, tk);
},
_ => {},
@@ -1148,7 +1139,6 @@ fn cmp_tid(n: *IrEntry): usize {
ret 0;
}
// ---- 翻译 ----
fn translate_function(ctx: *Ir2Vm, fid: usize, all_fixups: *Vec): usize {
var irf = IrM.func(ctx.ir, fid);
@@ -1172,7 +1162,7 @@ fn translate_function(ctx: *Ir2Vm, fid: usize, all_fixups: *Vec): usize {
var func_ip = ip_of(&cg);
ignore_usize(Mcode.add_func(&ctx.prog, irf.name, fn_nargs(ctx, irf.fn_tid), func_ip));
Mcode.add_func(&ctx.prog, irf.name, fn_nargs(ctx, irf.fn_tid), func_ip);
var local_slots = (cg.frame.frame_bytes - cg.frame.args_bytes + 7) / 8;
emit(&cg, .Alloc, .Void, local_slots);
@@ -1193,23 +1183,19 @@ fn translate_function(ctx: *Ir2Vm, fid: usize, all_fixups: *Vec): usize {
i = 0;
while i < local_fixups.len {
match Vec.get(&local_fixups, i) {
.Ok(ptr) => {
var fx = ptr as *Fix;
if @enum2int(fx.kind) == @enum2int(FixKind.Jmp) {
var ins = ins_ptr(&ctx.prog, fx.ins_idx);
if ins != null {
var target_ip: usize = 0;
if fx.node_target < nnodes {
target_ip = usize_at(&cg.node_ip, fx.node_target);
}
ins.imm = target_ip - fx.ins_idx - 1;
var fx = (local_fixups.data as *Fix) + i;
match fx.kind {
.Jmp => {
var ins = ins_ptr(&ctx.prog, fx.ins_idx);
if ins != null {
var target_ip: usize = 0;
if fx.node_target < nnodes {
target_ip = usize_at(&cg.node_ip, fx.node_target);
}
} else if @enum2int(fx.kind) == @enum2int(FixKind.Fnaddr) {
match Vec.push(all_fixups, ptr as *u8) { .Ok => {}, .Err(error) => {} }
ins.imm = target_ip - fx.ins_idx - 1;
}
},
.Err(error) => {},
.Fnaddr => { Vec.push(all_fixups, fx as *u8); },
}
i = i + 1;
}
@@ -1220,9 +1206,8 @@ fn translate_function(ctx: *Ir2Vm, fid: usize, all_fixups: *Vec): usize {
ret func_ip;
}
// ---- 生命周期 / 入口 ----
// 就地初始化(避免返回含 Prog 的大聚合;对应 stage1 spl_ir2vm_init)。
// 就地初始化,避免返回含 Prog 的大聚合。
fn init(ctx: *Ir2Vm, ir: *Ir, ty: *TypeTable, layout: *Layout, attr: *Attr) {
ctx.ir = ir;
ctx.ty = ty;
@@ -1246,7 +1231,7 @@ fn drop(ctx: *Ir2Vm) {
fn run_func(ctx: *Ir2Vm, ref: usize): i32 {
var all_fixups = Vec.blank(@sizeof(Fix), @alignof(Fix));
defer { Vec.drop(&all_fixups); }
ignore_usize(translate_function(ctx, ref, &all_fixups));
translate_function(ctx, ref, &all_fixups);
ret 0;
}
@@ -1258,7 +1243,7 @@ fn run(ctx: *Ir2Vm): i32 {
var i: usize = 0;
while i < n {
var v: isize = -1;
match Vec.push(&ctx.extern_native, &v as *u8) { .Ok => {}, .Err(error) => {} }
Vec.push(&ctx.extern_native, &v as *u8);
i = i + 1;
}
i = 1;
@@ -1283,12 +1268,12 @@ fn run(ctx: *Ir2Vm): i32 {
didx = Mcode.add_data(&ctx.prog, g.data.data as usize, gsize);
}
var dv = didx;
match Vec.push(&ctx.global_gaddr, &dv as *u8) { .Ok => {}, .Err(error) => {} }
Vec.push(&ctx.global_gaddr, &dv as *u8);
gi = gi + 1;
}
// 哨兵:保证真实函数入口地址非零。
ignore_usize(Mcode.add_instr(&ctx.prog, .Halt, .Void, 0));
Mcode.add_instr(&ctx.prog, .Halt, .Void, 0);
// 预分配指令容量(按 IR 节点数粗略估计),减少逐条 append 的扩容/拷贝。
var est: usize = 16;
@@ -1298,7 +1283,7 @@ fn run(ctx: *Ir2Vm): i32 {
if irf != null { est = est + irf.nodes.len * 8 + 32; }
i = i + 1;
}
match Vec.reserve(&ctx.prog.insns, est) { .Ok => {}, .Err(error) => {} }
Vec.reserve(&ctx.prog.insns, est);
// Pass 2:翻译非 extern 函数。
var fid_ip = Vec.blank(@sizeof(usize), @alignof(usize));
@@ -1382,12 +1367,8 @@ fn store(ctx: *Ir2Vm, path: ByteView): bool {
ret false;
}
// ---- 工具 ----
fn ignore_usize(v: usize) {}
fn ignore_bool(b: bool) {}
// ---- 测试 ----
fn main() {
var ir = IrM.new();