stage2 修复全局变量未完成的问题 提供错误处理解析
This commit is contained in:
1 parent
c0a86ea552
commit
0b8f649818
11 files changed
+317
-18
No files matched your search
@@ -44,6 +44,7 @@ sema: *Sema,
|
||||
ir: *IrBuilder,
|
||||
ast: *Ast,
|
||||
def2ir_map: Map,
|
||||
glob_gidx: Map, // def_id -> gidx+1(全局变量)
|
||||
loop_stack: Vec, // LoopCtx
|
||||
defer_stack: Vec, // ast node ref
|
||||
cur_ret_lang: usize,
|
||||
@@ -105,6 +106,62 @@ fn ir_map_put(self: *Ast2Ir, def_id: usize, val: usize) {
|
||||
match Map.put(&self.def2ir_map, &def_id as *u8, &val as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
}
|
||||
|
||||
fn glob_get(self: *Ast2Ir, def_id: usize, out: *usize): bool {
|
||||
match Map.get(&self.glob_gidx, &def_id as *u8, out as *u8) {
|
||||
.Found => { ret true; },
|
||||
.NotFound => { ret false; },
|
||||
}
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn glob_put(self: *Ast2Ir, def_id: usize, val: usize) {
|
||||
match Map.put(&self.glob_gidx, &def_id as *u8, &val as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
}
|
||||
|
||||
// 顶层 var/const → 模块全局(alloc 于静态存储;引用是 *T 指针常量)。
|
||||
fn emit_global_var(self: *Ast2Ir, d: *Node) {
|
||||
if d == null || d.resolved_def_id == 0 { ret; }
|
||||
var def_id = d.resolved_def_id;
|
||||
var existing: usize = 0;
|
||||
if glob_get(self, def_id, &existing) { ret; }
|
||||
var lang = LangType.def_lang_id(&self.sema.types, def_id);
|
||||
var ir = to_ir_type(self, lang);
|
||||
if ir == 0 { ret; }
|
||||
var init_ref: usize = 0;
|
||||
match d.body {
|
||||
.VarDecl(x) => { init_ref = x.init_expr; },
|
||||
.ConstDecl(x) => { init_ref = x.init_expr; },
|
||||
_ => {},
|
||||
}
|
||||
var zero = true;
|
||||
var bytes = Vec.blank(1, 1);
|
||||
if init_ref != 0 {
|
||||
var inode = Ast.node(self.ast, init_ref);
|
||||
if inode != null {
|
||||
match inode.body {
|
||||
.ExprIntLit(bi) => {
|
||||
var v: u64 = 0;
|
||||
match BigInt.to_u64(&v, bi.value) { .Ok => {}, .Err(e) => {} }
|
||||
var bits = LangType.int_bits(&self.sema.types, ir);
|
||||
var size = bits / 8;
|
||||
if size != 0 {
|
||||
zero = false;
|
||||
var i: usize = 0;
|
||||
while i < size {
|
||||
var b = ((v >> (8 * i)) & 255) as u8;
|
||||
match Vec.push(&bytes, &b as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
var gidx = IrBuilder.add_global(self.ir, ir, zero, bytes);
|
||||
glob_put(self, def_id, gidx + 1);
|
||||
}
|
||||
|
||||
fn kind_is(self: *Ast2Ir, lang_id: usize, want: LangKind): bool {
|
||||
var e = ltn(self, lang_id);
|
||||
if e == null { ret false; }
|
||||
@@ -608,6 +665,13 @@ fn emit_lvalue(self: *Ast2Ir, ref: usize): usize {
|
||||
.ExprIdent(x) => {
|
||||
var d = defn(self, n.resolved_def_id);
|
||||
if d != null && @enum2int(d.kind) == @enum2int(DefKind.Fn) { ret 0; }
|
||||
var g: usize = 0;
|
||||
if glob_get(self, n.resolved_def_id, &g) {
|
||||
var lang = node_lang(n);
|
||||
var ir = to_ir_type(self, lang);
|
||||
var ptr_ir = TypeTable.make_ptr(&self.sema.types.ir, ir);
|
||||
ret IrBuilder.type_const_global(self.ir, ptr_ir, g - 1);
|
||||
}
|
||||
var slot: usize = 0;
|
||||
if !ir_map_get(self, n.resolved_def_id, &slot) { ret 0; }
|
||||
ret slot;
|
||||
@@ -935,6 +999,13 @@ fn emit_ident(self: *Ast2Ir, n: *Node): usize {
|
||||
if !ir_map_get(self, n.resolved_def_id, &fn_ref) { ret 0; }
|
||||
ret IrBuilder.type_const_fn(self.ir, node_ir(self, n), fn_ref);
|
||||
}
|
||||
var g: usize = 0;
|
||||
if glob_get(self, n.resolved_def_id, &g) {
|
||||
var ir = node_ir(self, n);
|
||||
var ptr_ir = TypeTable.make_ptr(&self.sema.types.ir, ir);
|
||||
var ptr = IrBuilder.type_const_global(self.ir, ptr_ir, g - 1);
|
||||
ret IrBuilder.mem_load(self.ir, ir, ptr);
|
||||
}
|
||||
var slot: usize = 0;
|
||||
if !ir_map_get(self, n.resolved_def_id, &slot) { ret 0; }
|
||||
ret IrBuilder.mem_load(self.ir, node_ir(self, n), slot);
|
||||
@@ -1961,6 +2032,8 @@ fn emit_container_reserve(self: *Ast2Ir, ref: usize) {
|
||||
}
|
||||
},
|
||||
.TopLevelBlock(x) => { emit_container_reserve(self, dref); },
|
||||
.VarDecl(_) => { emit_global_var(self, d); },
|
||||
.ConstDecl(_) => { emit_global_var(self, d); },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@@ -1997,6 +2070,8 @@ fn emit_container_body(self: *Ast2Ir, ref: usize) {
|
||||
}
|
||||
},
|
||||
.TopLevelBlock(x) => { emit_container_body(self, dref); },
|
||||
.VarDecl(_) => {},
|
||||
.ConstDecl(_) => {},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@@ -2070,6 +2145,8 @@ fn new(builder: *IrBuilder, sema: *Sema, diag: *Diag): Ast2Ir {
|
||||
.ast = sema.ast,
|
||||
.def2ir_map = Map.new(@sizeof(usize), @alignof(usize), @sizeof(usize), @alignof(usize),
|
||||
hash_kind_usize()),
|
||||
.glob_gidx = Map.new(@sizeof(usize), @alignof(usize), @sizeof(usize), @alignof(usize),
|
||||
hash_kind_usize()),
|
||||
.loop_stack = Vec.blank(@sizeof(LoopCtx), @alignof(LoopCtx)),
|
||||
.defer_stack = Vec.blank(@sizeof(usize), @alignof(usize)),
|
||||
.cur_ret_lang = 0,
|
||||
@@ -2089,6 +2166,7 @@ fn drop(self: *Ast2Ir) {
|
||||
Vec.drop(&self.loop_stack);
|
||||
Vec.drop(&self.defer_stack);
|
||||
Map.drop(&self.def2ir_map);
|
||||
Map.drop(&self.glob_gidx);
|
||||
var k: usize = 0;
|
||||
while k < self.owned.len {
|
||||
match Vec.get(&self.owned, k) {
|
||||
|
||||
Reference in new issue
Block a user