stage2 修复全局变量未完成的问题 提供错误处理解析

This commit is contained in:
zzy committed 2026-09-25 13:46:07 +08:00
1 parent c0a86ea552
commit 0b8f649818
11 files changed
+317 -18

No files matched your search

+57 -1
View File
@@ -18,7 +18,7 @@ type .{ .Layout } = @import("./layout.spl");
type AttrM = @import("./attr.spl");
type .{ .Attr } = @import("./attr.spl");
type IrM = @import("./ir.spl");
type .{ .Ir, .IrFunc, .IrEntry } = @import("./ir.spl");
type .{ .Ir, .IrFunc, .IrEntry, .Global } = @import("./ir.spl");
type Ir2C = @self;
@@ -570,6 +570,7 @@ fn emit_const(self: *Ir2C, ref: usize, n: *IrEntry) {
}
},
.Ptr(v) => { put(self, "(void*)"); put_u(self, v); },
.Global(g) => { put(self, "(void*)spl_g_"); put_u(self, g); },
.Float(v) => { put(self, "0.0"); },
.Fn(fid) => { put(self, "(void*)&"); c_fn_name(self, fid); },
}
@@ -1240,6 +1241,32 @@ fn find_main(self: *Ir2C): usize {
fn run(self: *Ir2C) {
put(self, "#include \"spl_rt.h\"\n");
// 模块级全局变量(Zero → BSS:无初始化式)。
var gi: usize = 0;
while gi < self.ir.globals.len {
var g = (self.ir.globals.data as *Global) + gi;
var sz = type_size(self, g.tid);
if sz == 0 { sz = 1; }
put(self, "static unsigned char spl_g_");
put_u(self, gi);
put(self, "[");
put_u(self, sz);
put(self, "]");
if !g.zero {
put(self, " = {");
var k: usize = 0;
while k < g.data.len {
if k > 0 { put(self, ", "); }
put_u(self, ((g.data.data as *u8) + k).* as usize);
k = k + 1;
}
if g.data.len == 0 { put(self, "0"); }
put(self, "}");
}
put(self, ";\n");
gi = gi + 1;
}
var i: usize = 1;
while i < self.ir.funcs.len {
var f = IrM.func(self.ir, i);
@@ -1256,6 +1283,7 @@ fn run(self: *Ir2C) {
}
i = i + 1;
}
emit_ct_table(self);
var m = find_main(self);
if m != 0 {
var f = IrM.func(self.ir, m);
@@ -1283,6 +1311,34 @@ fn run(self: *Ir2C) {
}
}
// compiler function(`ct_` 前缀)回调表:供 native 端 vm_set_foreign 按名分发。
fn emit_ct_table(self: *Ir2C) {
put(self, "static const struct { const char *name; void *fn; } spl_ct_tab[] = {\n");
var n: usize = 0;
var i: usize = 1;
while i < self.ir.funcs.len {
var f = IrM.func(self.ir, i);
if f != null && !fn_is_extern(self, f) &&
ByteView.starts_with(f.name, ByteView.from_slice("ct_")) {
put(self, " {\"");
put_bv(self, f.name);
put(self, "\", (void*)f");
put_u(self, i);
put(self, "},\n");
n = n + 1;
}
i = i + 1;
}
if n == 0 { put(self, " {0, 0},\n"); }
put(self, "};\n");
put(self, "void *spl_ct_lookup(const char *name) {\n");
put(self, " unsigned long i;\n");
put(self, " for (i = 0; i < sizeof(spl_ct_tab)/sizeof(spl_ct_tab[0]); i++)\n");
put(self, " if (spl_ct_tab[i].name && strcmp(spl_ct_tab[i].name, name) == 0) return spl_ct_tab[i].fn;\n");
put(self, " return 0;\n");
put(self, "}\n");
}
fn new(ir: *Ir, ty: *TypeTable, layout: *Layout, attr: *Attr, out: *ByteBuffer): Ir2C {
ret Ir2C {
.ir = ir,