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
+135
-158
@@ -1,8 +1,7 @@
|
||||
// Expect retcode = 0
|
||||
|
||||
// AST -> SIR(移植自 stage1/spl_ast2ir.c)。两遍:先 reserve 所有函数(拿稳定
|
||||
// func ref),再发射函数体。def2ir_map 记录 def -> IR 槽位(变量=内存指针,
|
||||
// 函数=func ref)。loop_stack/defer_stack 驱动 break/continue/ret 的收尾。
|
||||
// AST -> IR。两遍:先 reserve 所有函数拿稳定 func ref,再发射函数体;def2ir_map
|
||||
// 记录 def -> 槽位(变量=内存指针,函数=func ref)。
|
||||
|
||||
type .{ .Error } = @import("utils/error.spl");
|
||||
type .{ .Vec } = @import("utils/vec.spl");
|
||||
@@ -52,7 +51,6 @@ cur_defer_base: usize,
|
||||
diag: *Diag,
|
||||
owned: Vec, // ByteBuffer:为 dbg.panic 消息提供稳定存储
|
||||
|
||||
// ---- 小工具 ----
|
||||
|
||||
fn list_at(v: Vec, i: usize): usize {
|
||||
if i >= v.len { ret 0; }
|
||||
@@ -60,7 +58,7 @@ fn list_at(v: Vec, i: usize): usize {
|
||||
}
|
||||
|
||||
fn push_u(v: *Vec, x: usize) {
|
||||
match Vec.push(v, &x as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.push(v, &x as *u8);
|
||||
}
|
||||
|
||||
fn irt(self: *Ast2Ir, id: usize): *TypeEntry {
|
||||
@@ -103,7 +101,7 @@ fn ir_map_get(self: *Ast2Ir, def_id: usize, out: *usize): bool {
|
||||
}
|
||||
|
||||
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) => {} }
|
||||
Map.put(&self.def2ir_map, &def_id as *u8, &val as *u8);
|
||||
}
|
||||
|
||||
fn glob_get(self: *Ast2Ir, def_id: usize, out: *usize): bool {
|
||||
@@ -115,7 +113,7 @@ fn glob_get(self: *Ast2Ir, def_id: usize, out: *usize): bool {
|
||||
}
|
||||
|
||||
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) => {} }
|
||||
Map.put(&self.glob_gidx, &def_id as *u8, &val as *u8);
|
||||
}
|
||||
|
||||
// 顶层 var/const → 模块全局(alloc 于静态存储;引用是 *T 指针常量)。
|
||||
@@ -141,7 +139,7 @@ fn emit_global_var(self: *Ast2Ir, d: *Node) {
|
||||
match inode.body {
|
||||
.ExprIntLit(bi) => {
|
||||
var v: u64 = 0;
|
||||
match BigInt.to_u64(&v, bi.value) { .Ok => {}, .Err(e) => {} }
|
||||
BigInt.to_u64(&v, bi.value);
|
||||
var bits = LangType.int_bits(&self.sema.types, ir);
|
||||
var size = bits / 8;
|
||||
if size != 0 {
|
||||
@@ -149,7 +147,7 @@ fn emit_global_var(self: *Ast2Ir, d: *Node) {
|
||||
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) => {} }
|
||||
Vec.push(&bytes, &b as *u8);
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
@@ -184,7 +182,7 @@ fn int_lit_u64(n: *Node): u64 {
|
||||
match n.body {
|
||||
.ExprIntLit(&x) => {
|
||||
var out: u64 = 0;
|
||||
match BigInt.to_u64(&out, x.value) { .Ok => {}, .Err(e) => {} }
|
||||
BigInt.to_u64(&out, x.value);
|
||||
ret out;
|
||||
},
|
||||
_ => {},
|
||||
@@ -198,7 +196,6 @@ fn ir_kind_of(self: *Ast2Ir, ref: usize): IrKind {
|
||||
ret e.kind;
|
||||
}
|
||||
|
||||
// ---- 零值 ----
|
||||
|
||||
fn emit_zero_value(self: *Ast2Ir, tid: usize): usize {
|
||||
var tn = irt(self, tid);
|
||||
@@ -277,7 +274,6 @@ fn variant_at(v: Vec, idx: usize): usize {
|
||||
ret m.type_id;
|
||||
}
|
||||
|
||||
// ---- 模式绑定 ----
|
||||
|
||||
fn pattern_has_ref(self: *Ast2Ir, pat_ref: usize): bool {
|
||||
if pat_ref == 0 { ret false; }
|
||||
@@ -334,7 +330,7 @@ fn emit_pattern_bind(self: *Ast2Ir, pat_ref: usize, src_ptr: usize, tid: usize,
|
||||
if place_mode {
|
||||
var slot = IrBuilder.mem_alloca(self.ir, tid, const_usize(self, 1));
|
||||
var v = IrBuilder.mem_load(self.ir, tid, src_ptr);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, tid, slot, v));
|
||||
IrBuilder.mem_store(self.ir, tid, slot, v);
|
||||
ir_map_put(self, pat.resolved_def_id, slot);
|
||||
} else {
|
||||
ir_map_put(self, pat.resolved_def_id, src_ptr);
|
||||
@@ -348,7 +344,7 @@ fn emit_pattern_bind(self: *Ast2Ir, pat_ref: usize, src_ptr: usize, tid: usize,
|
||||
if in != null { ptr_tid = node_ir(self, in); }
|
||||
if ptr_tid == 0 { ptr_tid = TypeTable.make_ptr(&self.sema.types.ir, tid); }
|
||||
var slot = IrBuilder.mem_alloca(self.ir, ptr_tid, const_usize(self, 1));
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, ptr_tid, slot, src_ptr));
|
||||
IrBuilder.mem_store(self.ir, ptr_tid, slot, src_ptr);
|
||||
emit_pattern_bind(self, x.pat, slot, ptr_tid, false);
|
||||
ret;
|
||||
},
|
||||
@@ -539,7 +535,7 @@ fn copy_attrs_node(self: *Ast2Ir, n: *Node, ir_ref: usize) {
|
||||
var i: usize = 0;
|
||||
while i < n.attrs.len {
|
||||
var a = list_at(n.attrs, i);
|
||||
match Vec.push(&irn.attrs, &a as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.push(&irn.attrs, &a as *u8);
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
@@ -551,12 +547,11 @@ fn copy_attrs_func(self: *Ast2Ir, n: *Node, fn_ref: usize) {
|
||||
var i: usize = 0;
|
||||
while i < n.attrs.len {
|
||||
var a = list_at(n.attrs, i);
|
||||
match Vec.push(&irf.attrs, &a as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.push(&irf.attrs, &a as *u8);
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// ---- intrinsic ----
|
||||
|
||||
fn ast2ir_intrin_cast(self: *Ast2Ir, n: *Node, in: Intrin, args: Vec): usize {
|
||||
if args.len < 1 {
|
||||
@@ -579,38 +574,39 @@ fn ast2ir_intrin_cast(self: *Ast2Ir, n: *Node, in: Intrin, args: Vec): usize {
|
||||
}
|
||||
|
||||
fn ast2ir_intrin_call(self: *Ast2Ir, n: *Node, in: Intrin, args: Vec): usize {
|
||||
if @enum2int(in) == @enum2int(Intrin.BitSizeof) {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_bitsizeof(self.ir, node_ir(self, arg));
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Sizeof) {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_sizeof(self.ir, node_ir(self, arg));
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Alignof) {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_alignof(self.ir, node_ir(self, arg));
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Enum2Int) {
|
||||
var src = Ast.node(self.ast, list_at(args, 0));
|
||||
var v = emit_expr(self, list_at(args, 0));
|
||||
if v == 0 { ret 0; }
|
||||
var agg_t = node_ir(self, src);
|
||||
var tag_t = node_ir(self, n);
|
||||
if agg_t == 0 || tag_t == 0 { ret 0; }
|
||||
ret IrBuilder.agg_extract(self.ir, agg_t, tag_t, 0, v);
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.FieldCount) {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_field_count(self.ir, node_ir(self, arg));
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.OffsetOf) {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
var agg_t = node_ir(self, arg);
|
||||
if agg_t == 0 { ret 0; }
|
||||
var fnode = Ast.node(self.ast, list_at(args, 1));
|
||||
var idx: usize = 0;
|
||||
if fnode != null {
|
||||
match in {
|
||||
.BitSizeof => {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_bitsizeof(self.ir, node_ir(self, arg));
|
||||
},
|
||||
.Sizeof => {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_sizeof(self.ir, node_ir(self, arg));
|
||||
},
|
||||
.Alignof => {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_alignof(self.ir, node_ir(self, arg));
|
||||
},
|
||||
.Enum2Int => {
|
||||
var src = Ast.node(self.ast, list_at(args, 0));
|
||||
var v = emit_expr(self, list_at(args, 0));
|
||||
if v == 0 { ret 0; }
|
||||
var agg_t = node_ir(self, src);
|
||||
var tag_t = node_ir(self, n);
|
||||
if agg_t == 0 || tag_t == 0 { ret 0; }
|
||||
ret IrBuilder.agg_extract(self.ir, agg_t, tag_t, 0, v);
|
||||
},
|
||||
.FieldCount => {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
ret IrBuilder.type_field_count(self.ir, node_ir(self, arg));
|
||||
},
|
||||
.OffsetOf => {
|
||||
var arg = Ast.node(self.ast, list_at(args, 0));
|
||||
var agg_t = node_ir(self, arg);
|
||||
if agg_t == 0 { ret 0; }
|
||||
var fnode = Ast.node(self.ast, list_at(args, 1));
|
||||
if fnode == null { ret 0; }
|
||||
var idx: usize = 0;
|
||||
match fnode.body {
|
||||
.ExprIntLit(x) => { idx = int_lit_u64(fnode) as usize; },
|
||||
.ExprIdent(e) => {
|
||||
@@ -618,29 +614,16 @@ fn ast2ir_intrin_call(self: *Ast2Ir, n: *Node, in: Intrin, args: Vec): usize {
|
||||
},
|
||||
_ => { ret 0; },
|
||||
}
|
||||
} else {
|
||||
ret 0;
|
||||
}
|
||||
var idx_node = const_usize(self, idx);
|
||||
ret IrBuilder.type_offsetof(self.ir, agg_t, idx_node);
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Assert) {
|
||||
ret ast2ir_intrin_assert(self, n, args);
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.IntCast) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Truncate) ||
|
||||
@enum2int(in) == @enum2int(Intrin.BitCast) ||
|
||||
@enum2int(in) == @enum2int(Intrin.FloatCast) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Float2Int) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Int2Float) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Bool2Int) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Ptr2Int) ||
|
||||
@enum2int(in) == @enum2int(Intrin.Int2Ptr) ||
|
||||
@enum2int(in) == @enum2int(Intrin.PtrCast) {
|
||||
ret ast2ir_intrin_cast(self, n, in, args);
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Breakpoint) {
|
||||
ret IrBuilder.dbg_breakpoint(self.ir);
|
||||
var idx_node = const_usize(self, idx);
|
||||
ret IrBuilder.type_offsetof(self.ir, agg_t, idx_node);
|
||||
},
|
||||
.Assert => { ret ast2ir_intrin_assert(self, n, args); },
|
||||
.IntCast, .Truncate, .BitCast, .FloatCast, .Float2Int, .Int2Float,
|
||||
.Bool2Int, .Ptr2Int, .Int2Ptr, .PtrCast => {
|
||||
ret ast2ir_intrin_cast(self, n, in, args);
|
||||
},
|
||||
.Breakpoint => { ret IrBuilder.dbg_breakpoint(self.ir); },
|
||||
_ => { ret 0; },
|
||||
}
|
||||
ret 0;
|
||||
}
|
||||
@@ -665,22 +648,22 @@ fn ast2ir_intrin_assert(self: *Ast2Ir, n: *Node, args: Vec): usize {
|
||||
if self.sema.sources != null && n.span.file != no_file() {
|
||||
var src = set_at(self.sema.sources, n.span.file);
|
||||
if src != null {
|
||||
ignore_bool(append_bytes(&msg, ByteView.as_slice(src.fname)));
|
||||
append_bytes(&msg, ByteView.as_slice(src.fname));
|
||||
var pos = Source.line_col(src.*, n.span.start);
|
||||
ignore_bool(append_bytes(&msg, ":"));
|
||||
ignore_bool(append_num(&msg, pos.line));
|
||||
ignore_bool(append_bytes(&msg, ":"));
|
||||
ignore_bool(append_num(&msg, pos.col));
|
||||
append_bytes(&msg, ":");
|
||||
append_num(&msg, pos.line);
|
||||
append_bytes(&msg, ":");
|
||||
append_num(&msg, pos.col);
|
||||
}
|
||||
}
|
||||
ignore_bool(append_bytes(&msg, ": assert failed"));
|
||||
append_bytes(&msg, ": assert failed");
|
||||
if args.len == 2 {
|
||||
var mn = Ast.node(self.ast, list_at(args, 1));
|
||||
if mn != null {
|
||||
match mn.body {
|
||||
.ExprStringLit(sl) => {
|
||||
ignore_bool(append_bytes(&msg, ": "));
|
||||
ignore_bool(append_bytes(&msg, ByteView.as_slice(sl.data)));
|
||||
append_bytes(&msg, ": ");
|
||||
append_bytes(&msg, ByteView.as_slice(sl.data));
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
@@ -688,8 +671,8 @@ fn ast2ir_intrin_assert(self: *Ast2Ir, n: *Node, args: Vec): usize {
|
||||
}
|
||||
var msg_view = ByteView.from_slice(ByteBuffer.as_slice(msg));
|
||||
@assert(msg_view.len == 0 || msg_view.ptr != null, "panic message bytes must be non-null");
|
||||
ignore_usize(IrBuilder.dbg_panic(self.ir, msg_view));
|
||||
ignore_usize(IrBuilder.control_trap(self.ir));
|
||||
IrBuilder.dbg_panic(self.ir, msg_view);
|
||||
IrBuilder.control_trap(self.ir);
|
||||
IrBuilder.block_end(self.ir);
|
||||
|
||||
var cont_blk = IrBuilder.block_begin(self.ir);
|
||||
@@ -707,7 +690,6 @@ fn append_num(buf: *ByteBuffer, v: usize): bool {
|
||||
ret false;
|
||||
}
|
||||
|
||||
fn ignore_bool(b: bool) {}
|
||||
|
||||
fn ast2ir_intrin_field(self: *Ast2Ir, n: *Node, in: Intrin): usize {
|
||||
if @enum2int(in) == @enum2int(Intrin.Len) { ret ast2ir_intrin_len(self, n); }
|
||||
@@ -742,7 +724,6 @@ fn ast2ir_intrin_len(self: *Ast2Ir, n: *Node): usize {
|
||||
ret 0;
|
||||
}
|
||||
|
||||
// ---- 左值 ----
|
||||
|
||||
fn emit_lvalue(self: *Ast2Ir, ref: usize): usize {
|
||||
var n = Ast.node(self.ast, ref);
|
||||
@@ -857,33 +838,32 @@ fn extra_elem(e: LangEntry): usize {
|
||||
ret 0;
|
||||
}
|
||||
|
||||
fn ignore_usize(x: usize) {}
|
||||
|
||||
// ---- 转换 ----
|
||||
|
||||
fn ast2ir_emit_cast_builtin(self: *Ast2Ir, n: *Node, in: Intrin, ft: usize, tt: usize,
|
||||
v: usize): usize {
|
||||
if @enum2int(in) == @enum2int(Intrin.IntCast) {
|
||||
var fs = irt(self, ft);
|
||||
if fs != null {
|
||||
match fs.node {
|
||||
.Int(x) => { if x.is_signed { ret IrBuilder.cast_sext(self.ir, ft, tt, v); } },
|
||||
_ => {},
|
||||
match in {
|
||||
.IntCast => {
|
||||
var fs = irt(self, ft);
|
||||
if fs != null {
|
||||
match fs.node {
|
||||
.Int(x) => { if x.is_signed { ret IrBuilder.cast_sext(self.ir, ft, tt, v); } },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
ret IrBuilder.cast_zext(self.ir, ft, tt, v);
|
||||
ret IrBuilder.cast_zext(self.ir, ft, tt, v);
|
||||
},
|
||||
.Truncate => { ret IrBuilder.cast_trunc(self.ir, ft, tt, v); },
|
||||
.BitCast => { ret IrBuilder.cast_bitcast(self.ir, ft, tt, v); },
|
||||
.FloatCast => { ret ir_float_cast(self, ft, tt, v); },
|
||||
.Float2Int => { ret IrBuilder.case_float2int(self.ir, ft, tt, v); },
|
||||
.Int2Float => { ret IrBuilder.case_int2float(self.ir, ft, tt, v); },
|
||||
.Bool2Int => { ret IrBuilder.cast_bool2int(self.ir, ft, tt, v); },
|
||||
.Ptr2Int => { ret IrBuilder.cast_ptr2int(self.ir, ft, tt, v); },
|
||||
.Int2Ptr => { ret IrBuilder.cast_int2ptr(self.ir, ft, tt, v); },
|
||||
.PtrCast => { ret IrBuilder.cast_bitcast(self.ir, ft, tt, v); },
|
||||
_ => {},
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Truncate) { ret IrBuilder.cast_trunc(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.BitCast) { ret IrBuilder.cast_bitcast(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.FloatCast) {
|
||||
ret ir_float_cast(self, ft, tt, v);
|
||||
}
|
||||
if @enum2int(in) == @enum2int(Intrin.Float2Int) { ret IrBuilder.case_float2int(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.Int2Float) { ret IrBuilder.case_int2float(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.Bool2Int) { ret IrBuilder.cast_bool2int(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.Ptr2Int) { ret IrBuilder.cast_ptr2int(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.Int2Ptr) { ret IrBuilder.cast_int2ptr(self.ir, ft, tt, v); }
|
||||
if @enum2int(in) == @enum2int(Intrin.PtrCast) { ret IrBuilder.cast_bitcast(self.ir, ft, tt, v); }
|
||||
Diag.err(self.diag, n.span, .Internal, "ast2ir: unknown cast builtin");
|
||||
ret 0;
|
||||
}
|
||||
@@ -968,19 +948,18 @@ fn ast2ir_enum_variant(self: *Ast2Ir, n: *Node): usize {
|
||||
var eptr = IrBuilder.mem_alloca(self.ir, t, const_usize(self, 1));
|
||||
var tptr = IrBuilder.mem_field(self.ir, t, eptr, 0);
|
||||
var tag_val = IrBuilder.type_const_int(self.ir, tag_ir, vidx);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, tag_ir, tptr, tag_val));
|
||||
IrBuilder.mem_store(self.ir, tag_ir, tptr, tag_val);
|
||||
if vidx < variants.len {
|
||||
var payload_ir = variant_at(variants, vidx);
|
||||
if payload_ir != 0 {
|
||||
var pptr = IrBuilder.mem_field(self.ir, t, eptr, vidx + 1);
|
||||
var zero = emit_zero_value(self, payload_ir);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, payload_ir, pptr, zero));
|
||||
IrBuilder.mem_store(self.ir, payload_ir, pptr, zero);
|
||||
}
|
||||
}
|
||||
ret eptr;
|
||||
}
|
||||
|
||||
// ---- 表达式 ----
|
||||
|
||||
fn emit_expr(self: *Ast2Ir, ref: usize): usize {
|
||||
var val = emit_expr_raw(self, ref);
|
||||
@@ -1120,7 +1099,7 @@ fn emit_binary(self: *Ast2Ir, n: *Node, op: Punct, left: usize, right: usize): u
|
||||
if ptr == 0 || v == 0 { ret 0; }
|
||||
var ln = Ast.node(self.ast, left);
|
||||
var t = node_ir(self, ln);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, t, ptr, v));
|
||||
IrBuilder.mem_store(self.ir, t, ptr, v);
|
||||
ret v;
|
||||
}
|
||||
if is_assign_arith(op) { ret emit_assign_arith(self, op, left, right); }
|
||||
@@ -1199,7 +1178,7 @@ fn emit_assign_arith(self: *Ast2Ir, op: Punct, left: usize, right: usize): usize
|
||||
else if punct_is(op, .RShAssign) { res = IrBuilder.arith_shr(self.ir, t, lv, rv); }
|
||||
else { ret 0; }
|
||||
if res == 0 { ret 0; }
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, t, ptr, res));
|
||||
IrBuilder.mem_store(self.ir, t, ptr, res);
|
||||
ret res;
|
||||
}
|
||||
|
||||
@@ -1210,14 +1189,14 @@ fn emit_short_circuit(self: *Ast2Ir, op: Punct, left: usize, right: usize): usiz
|
||||
|
||||
var l = emit_expr(self, left);
|
||||
if l == 0 { ret 0; }
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, b_ir, slot, l));
|
||||
IrBuilder.mem_store(self.ir, b_ir, slot, l);
|
||||
|
||||
var br = IrBuilder.control_br(self.ir, l);
|
||||
IrBuilder.block_end(self.ir);
|
||||
|
||||
var rhs_blk = IrBuilder.block_begin(self.ir);
|
||||
var r = emit_expr(self, right);
|
||||
if r != 0 { ignore_usize(IrBuilder.mem_store(self.ir, b_ir, slot, r)); }
|
||||
if r != 0 { IrBuilder.mem_store(self.ir, b_ir, slot, r); }
|
||||
var rhs_end: usize = 0;
|
||||
if !self.ir.terminated { rhs_end = IrBuilder.control_jmp(self.ir); }
|
||||
IrBuilder.block_end(self.ir);
|
||||
@@ -1371,7 +1350,7 @@ fn emit_array_to_slice(self: *Ast2Ir, n: *Node, t: usize, elems: Vec, elem_lang:
|
||||
var fptr = IrBuilder.mem_field(self.ir, arr_ir, slot, i);
|
||||
var v = emit_expr(self, list_at(elems, i));
|
||||
if v == 0 { ret 0; }
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, elem_ir, fptr, v));
|
||||
IrBuilder.mem_store(self.ir, elem_ir, fptr, v);
|
||||
i = i + 1;
|
||||
}
|
||||
base = IrBuilder.mem_field(self.ir, arr_ir, slot, 0);
|
||||
@@ -1413,13 +1392,13 @@ fn emit_aggregate_lit(self: *Ast2Ir, n: *Node, type_name: ByteView, fields: Vec)
|
||||
var eptr = IrBuilder.mem_alloca(self.ir, t, const_usize(self, 1));
|
||||
var tptr = IrBuilder.mem_field(self.ir, t, eptr, 0);
|
||||
var tag_val = IrBuilder.type_const_int(self.ir, tag_ir, vidx);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, tag_ir, tptr, tag_val));
|
||||
IrBuilder.mem_store(self.ir, tag_ir, tptr, tag_val);
|
||||
if iexpr != 0 {
|
||||
var payload_ir = variant_at(variants, vidx);
|
||||
var pptr = IrBuilder.mem_field(self.ir, t, eptr, vidx + 1);
|
||||
var payload = emit_expr(self, iexpr);
|
||||
if payload == 0 { ret 0; }
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, payload_ir, pptr, payload));
|
||||
IrBuilder.mem_store(self.ir, payload_ir, pptr, payload);
|
||||
}
|
||||
ret eptr;
|
||||
}
|
||||
@@ -1474,7 +1453,7 @@ fn emit_aggregate_lit(self: *Ast2Ir, n: *Node, type_name: ByteView, fields: Vec)
|
||||
}
|
||||
|
||||
fn set_u(v: *Vec, i: usize, x: usize) {
|
||||
match Vec.set(v, i, &x as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.set(v, i, &x as *u8);
|
||||
}
|
||||
|
||||
fn emit_deferred_until(self: *Ast2Ir, base: usize) {
|
||||
@@ -1545,7 +1524,7 @@ fn emit_match(self: *Ast2Ir, n: *Node, matched_ref: usize, arms: Vec): usize {
|
||||
scrut_slot = IrBuilder.mem_alloca(self.ir, matched_ir, const_usize(self, 1));
|
||||
var scrut_val = emit_expr(self, matched_ref);
|
||||
if scrut_val == 0 { ret 0; }
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, matched_ir, scrut_slot, scrut_val));
|
||||
IrBuilder.mem_store(self.ir, matched_ir, scrut_slot, scrut_val);
|
||||
}
|
||||
|
||||
var narms = arms.len;
|
||||
@@ -1567,7 +1546,7 @@ fn emit_match(self: *Ast2Ir, n: *Node, matched_ref: usize, arms: Vec): usize {
|
||||
push_u(&arm_branches, IrBuilder.control_jmp(self.ir));
|
||||
}
|
||||
IrBuilder.block_end(self.ir);
|
||||
if i + 1 < narms { ignore_usize(IrBuilder.block_begin(self.ir)); }
|
||||
if i + 1 < narms { IrBuilder.block_begin(self.ir); }
|
||||
i = i + 1;
|
||||
}
|
||||
var no_match_blk = IrBuilder.block_begin(self.ir);
|
||||
@@ -1585,7 +1564,7 @@ fn emit_match(self: *Ast2Ir, n: *Node, matched_ref: usize, arms: Vec): usize {
|
||||
var body: usize = 0;
|
||||
match arm.body { .MatchArm(ma) => { pat = ma.pattern; body = ma.body; }, _ => {} }
|
||||
emit_pattern_bind(self, pat, scrut_slot, matched_ir, matched_place_mode);
|
||||
if body != 0 { ignore_usize(emit_expr(self, body)); }
|
||||
if body != 0 { emit_expr(self, body); }
|
||||
}
|
||||
var j: usize = 0;
|
||||
if !self.ir.terminated { j = IrBuilder.control_jmp(self.ir); }
|
||||
@@ -1600,12 +1579,14 @@ fn emit_match(self: *Ast2Ir, n: *Node, matched_ref: usize, arms: Vec): usize {
|
||||
if branch != 0 {
|
||||
var bk = ir_kind_of(self, branch);
|
||||
var body_blk = list_at(body_blks, i);
|
||||
if @enum2int(bk) == @enum2int(IrKind.ControlBr) {
|
||||
var next_blk = no_match_blk;
|
||||
if i + 1 < narms { next_blk = list_at(cond_blks, i + 1); }
|
||||
IrBuilder.control_br_fixup(self.ir, branch, body_blk, next_blk);
|
||||
} else if @enum2int(bk) == @enum2int(IrKind.ControlJmp) {
|
||||
IrBuilder.control_jmp_fixup(self.ir, branch, body_blk);
|
||||
match bk {
|
||||
.ControlBr => {
|
||||
var next_blk = no_match_blk;
|
||||
if i + 1 < narms { next_blk = list_at(cond_blks, i + 1); }
|
||||
IrBuilder.control_br_fixup(self.ir, branch, body_blk, next_blk);
|
||||
},
|
||||
.ControlJmp => { IrBuilder.control_jmp_fixup(self.ir, branch, body_blk); },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
i = i + 1;
|
||||
@@ -1682,7 +1663,6 @@ fn emit_slice(self: *Ast2Ir, n: *Node, obj_ref: usize, begin_ref: usize, end_ref
|
||||
ret node;
|
||||
}
|
||||
|
||||
// ---- if / loop ----
|
||||
|
||||
fn emit_if_like(self: *Ast2Ir, ref: usize): usize {
|
||||
var n = Ast.node(self.ast, ref);
|
||||
@@ -1729,7 +1709,7 @@ fn emit_if_like(self: *Ast2Ir, ref: usize): usize {
|
||||
var then_v: usize = 0;
|
||||
if then_ref != 0 { then_v = emit_expr(self, then_ref); }
|
||||
if result_slot != 0 && then_v != 0 {
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, result_t, result_slot, then_v));
|
||||
IrBuilder.mem_store(self.ir, result_t, result_slot, then_v);
|
||||
}
|
||||
var then_end: usize = 0;
|
||||
if !self.ir.terminated { then_end = IrBuilder.control_jmp(self.ir); }
|
||||
@@ -1739,7 +1719,7 @@ fn emit_if_like(self: *Ast2Ir, ref: usize): usize {
|
||||
var else_v: usize = 0;
|
||||
if else_ref != 0 { else_v = emit_expr(self, else_ref); }
|
||||
if result_slot != 0 && else_v != 0 {
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, result_t, result_slot, else_v));
|
||||
IrBuilder.mem_store(self.ir, result_t, result_slot, else_v);
|
||||
}
|
||||
var else_end: usize = 0;
|
||||
if !self.ir.terminated { else_end = IrBuilder.control_jmp(self.ir); }
|
||||
@@ -1815,9 +1795,9 @@ fn emit_loop_like(self: *Ast2Ir, ref: usize): usize {
|
||||
}
|
||||
}
|
||||
if label_ref != 0 { ctx.label = label_name_of(self, label_ref); }
|
||||
match Vec.push(&self.loop_stack, &ctx as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.push(&self.loop_stack, &ctx as *u8);
|
||||
|
||||
if body_ref != 0 { ignore_usize(emit_expr(self, body_ref)); }
|
||||
if body_ref != 0 { emit_expr(self, body_ref); }
|
||||
|
||||
var body_end: usize = 0;
|
||||
if !self.ir.terminated { body_end = IrBuilder.control_jmp(self.ir); }
|
||||
@@ -1827,7 +1807,7 @@ fn emit_loop_like(self: *Ast2Ir, ref: usize): usize {
|
||||
var else_v: usize = 0;
|
||||
if is_while && else_ref != 0 { else_v = emit_expr(self, else_ref); }
|
||||
if result_slot != 0 && else_v != 0 {
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, result_t, result_slot, else_v));
|
||||
IrBuilder.mem_store(self.ir, result_t, result_slot, else_v);
|
||||
}
|
||||
if pre_jmp != 0 { IrBuilder.control_jmp_fixup(self.ir, pre_jmp, cont_blk); }
|
||||
if br != 0 { IrBuilder.control_br_fixup(self.ir, br, body_blk, after_blk); }
|
||||
@@ -1858,7 +1838,7 @@ fn pop_loop(self: *Ast2Ir) {
|
||||
.cont_blk = 0, .defer_base = 0, .label = ByteView.empty(),
|
||||
.breaks = Vec.blank(@sizeof(usize), @alignof(usize)), .result_slot = 0, .result_tid = 0,
|
||||
};
|
||||
match Vec.pop(&self.loop_stack, &out as *u8) { .Ok => {}, .Err(e) => {} }
|
||||
Vec.pop(&self.loop_stack, &out as *u8);
|
||||
}
|
||||
|
||||
fn label_name_of(self: *Ast2Ir, ref: usize): ByteView {
|
||||
@@ -1896,7 +1876,7 @@ fn emit_break_stmt(self: *Ast2Ir, n: *Node): usize {
|
||||
if expr_ref != 0 && target.result_slot != 0 {
|
||||
var bv = emit_expr(self, expr_ref);
|
||||
if bv != 0 {
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, target.result_tid, target.result_slot, bv));
|
||||
IrBuilder.mem_store(self.ir, target.result_tid, target.result_slot, bv);
|
||||
}
|
||||
}
|
||||
emit_deferred_until(self, target.defer_base);
|
||||
@@ -1907,7 +1887,6 @@ fn emit_break_stmt(self: *Ast2Ir, n: *Node): usize {
|
||||
ret 0;
|
||||
}
|
||||
|
||||
// ---- 语句 / 声明 ----
|
||||
|
||||
fn emit_stmt(self: *Ast2Ir, ref: usize) {
|
||||
var n = Ast.node(self.ast, ref);
|
||||
@@ -1918,20 +1897,20 @@ fn emit_stmt(self: *Ast2Ir, ref: usize) {
|
||||
var v: usize = 0;
|
||||
if x.expr != 0 { v = emit_expr(self, x.expr); }
|
||||
emit_deferred_until(self, self.cur_defer_base);
|
||||
if !self.ir.terminated { ignore_usize(IrBuilder.control_ret(self.ir, ret_ir, v)); }
|
||||
if !self.ir.terminated { IrBuilder.control_ret(self.ir, ret_ir, v); }
|
||||
},
|
||||
.StatementDefer(&x) => { if x.body != 0 { push_u(&self.defer_stack, x.body); } },
|
||||
.StatementComptime(&x) => { if x.body != 0 { ignore_usize(emit_expr(self, x.body)); } },
|
||||
.StatementComptime(&x) => { if x.body != 0 { emit_expr(self, x.body); } },
|
||||
.StatementDecl(&x) => { if x.decl != 0 { emit_decl(self, x.decl); } },
|
||||
.StatementExpr(&x) => { if x.expr != 0 { ignore_usize(emit_expr(self, x.expr)); } },
|
||||
.ExprIf(&x) => { ignore_usize(emit_if_like(self, ref)); },
|
||||
.ExprIfvar(&x) => { ignore_usize(emit_if_like(self, ref)); },
|
||||
.ExprWhile(&x) => { ignore_usize(emit_loop_like(self, ref)); },
|
||||
.ExprLoop(&x) => { ignore_usize(emit_loop_like(self, ref)); },
|
||||
.StatementBreak(&x) => { ignore_usize(emit_break_stmt(self, n)); },
|
||||
.StatementExpr(&x) => { if x.expr != 0 { emit_expr(self, x.expr); } },
|
||||
.ExprIf(&x) => { emit_if_like(self, ref); },
|
||||
.ExprIfvar(&x) => { emit_if_like(self, ref); },
|
||||
.ExprWhile(&x) => { emit_loop_like(self, ref); },
|
||||
.ExprLoop(&x) => { emit_loop_like(self, ref); },
|
||||
.StatementBreak(&x) => { emit_break_stmt(self, n); },
|
||||
.StatementContinue(&x) => { emit_continue_stmt(self, n); },
|
||||
.ExprBlock(&x) => { ignore_usize(emit_expr(self, ref)); },
|
||||
_ => { ignore_usize(emit_expr(self, ref)); },
|
||||
.ExprBlock(&x) => { emit_expr(self, ref); },
|
||||
_ => { emit_expr(self, ref); },
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1957,8 +1936,8 @@ fn emit_decl(self: *Ast2Ir, ref: usize) {
|
||||
var n = Ast.node(self.ast, ref);
|
||||
if n == null { ret; }
|
||||
match n.body {
|
||||
.VarDecl(&x) => { if self.ir.current_fn != 0 { ignore_usize(emit_var_decl(self, n)); } },
|
||||
.ConstDecl(&x) => { if self.ir.current_fn != 0 { ignore_usize(emit_var_decl(self, n)); } },
|
||||
.VarDecl(&x) => { if self.ir.current_fn != 0 { emit_var_decl(self, n); } },
|
||||
.ConstDecl(&x) => { if self.ir.current_fn != 0 { emit_var_decl(self, n); } },
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
@@ -1989,8 +1968,8 @@ fn fn_name_of(n: *Node): ByteView {
|
||||
fn diag_name(self: *Ast2Ir, span: Span, code: Code, prefix: []u8, name: ByteView) {
|
||||
var b = ByteBuffer.new();
|
||||
defer { ByteBuffer.drop(&b); }
|
||||
match ByteBuffer.append(&b, prefix) { .Ok => {}, .Err(e) => {} }
|
||||
match ByteBuffer.append(&b, ByteView.as_slice(name)) { .Ok => {}, .Err(e) => {} }
|
||||
ByteBuffer.append(&b, prefix);
|
||||
ByteBuffer.append(&b, ByteView.as_slice(name));
|
||||
Diag.err(self.diag, span, code, ByteBuffer.as_slice(b));
|
||||
}
|
||||
|
||||
@@ -2014,7 +1993,7 @@ fn emit_fn_body(self: *Ast2Ir, n: *Node) {
|
||||
var defer_base = self.cur_defer_base;
|
||||
var loop_base = self.loop_stack.len;
|
||||
|
||||
ignore_usize(IrBuilder.block_begin(self.ir));
|
||||
IrBuilder.block_begin(self.ir);
|
||||
|
||||
var params = Vec.blank(@sizeof(usize), @alignof(usize));
|
||||
var body_ref: usize = 0;
|
||||
@@ -2031,23 +2010,23 @@ fn emit_fn_body(self: *Ast2Ir, n: *Node) {
|
||||
var pv = IrBuilder.control_param(self.ir, p_ir, idx);
|
||||
var one = const_usize(self, 1);
|
||||
var slot = IrBuilder.mem_alloca(self.ir, p_ir, one);
|
||||
ignore_usize(IrBuilder.mem_store(self.ir, p_ir, slot, pv));
|
||||
IrBuilder.mem_store(self.ir, p_ir, slot, pv);
|
||||
ir_map_put(self, pd.resolved_def_id, slot);
|
||||
}
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
|
||||
if body_ref != 0 { ignore_usize(emit_expr(self, body_ref)); }
|
||||
if body_ref != 0 { emit_expr(self, body_ref); }
|
||||
if !self.ir.terminated { emit_deferred_until(self, defer_base); }
|
||||
if !self.ir.terminated {
|
||||
if ret_is_unit {
|
||||
ignore_usize(IrBuilder.control_ret(self.ir, ret_ir, 0));
|
||||
IrBuilder.control_ret(self.ir, ret_ir, 0);
|
||||
} else if ret_ir != 0 {
|
||||
var zero = emit_zero_value(self, ret_ir);
|
||||
ignore_usize(IrBuilder.control_ret(self.ir, ret_ir, zero));
|
||||
IrBuilder.control_ret(self.ir, ret_ir, zero);
|
||||
} else {
|
||||
ignore_usize(IrBuilder.control_unreachable(self.ir));
|
||||
IrBuilder.control_unreachable(self.ir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2077,7 +2056,7 @@ fn emit_aggregate_fns_reserve(self: *Ast2Ir, te: *Node) {
|
||||
var mn = Ast.node(self.ast, list_at(members, i));
|
||||
if mn != null {
|
||||
match mn.body {
|
||||
.FnDecl(x) => { ignore_usize(emit_fn_reserve(self, mn)); },
|
||||
.FnDecl(x) => { emit_fn_reserve(self, mn); },
|
||||
.MemberDecl(md) => {
|
||||
if md.type_expr != 0 {
|
||||
var mt = Ast.node(self.ast, md.type_expr);
|
||||
@@ -2138,7 +2117,7 @@ fn emit_container_reserve(self: *Ast2Ir, ref: usize) {
|
||||
var d = Ast.node(self.ast, dref);
|
||||
if d != null {
|
||||
match d.body {
|
||||
.FnDecl(x) => { ignore_usize(emit_fn_reserve(self, d)); },
|
||||
.FnDecl(x) => { emit_fn_reserve(self, d); },
|
||||
.TypeDecl(td) => {
|
||||
var tpat = Ast.node(self.ast, td.pattern);
|
||||
if tpat != null && is_pattern_ident(tpat) {
|
||||
@@ -2251,7 +2230,6 @@ fn emit_implicit_cast(self: *Ast2Ir, n: *Node, ft: usize, tt: usize, v: usize):
|
||||
ret 0;
|
||||
}
|
||||
|
||||
// ---- 驱动 ----
|
||||
|
||||
fn new(builder: *IrBuilder, sema: *Sema, diag: *Diag): Ast2Ir {
|
||||
ret Ast2Ir {
|
||||
@@ -2330,6 +2308,5 @@ fn list_ptr(v: Vec, i: usize): *Ast {
|
||||
ret null;
|
||||
}
|
||||
|
||||
// ---- 测试 ----
|
||||
|
||||
fn main() {}
|
||||
Reference in new issue
Block a user