05
This commit is contained in:
@@ -130,14 +130,38 @@ pub const Builder = struct {
|
||||
// ── Function setup ──────────────────────────────────────────────
|
||||
|
||||
pub fn beginFunction(self: *Builder, name: StringId, params: []const Function.Param, ret_ty: TypeId) FuncId {
|
||||
// Check if there's an existing extern stub with this name — upgrade it in-place
|
||||
for (self.module.functions.items, 0..) |*existing, i| {
|
||||
if (existing.name == name and existing.is_extern) {
|
||||
existing.is_extern = false;
|
||||
existing.linkage = .internal;
|
||||
existing.params = self.module.alloc.dupe(Function.Param, params) catch params;
|
||||
existing.ret = ret_ty;
|
||||
const id = FuncId.fromIndex(@intCast(i));
|
||||
self.func = id;
|
||||
self.inst_counter = @intCast(params.len);
|
||||
self.current_block = null;
|
||||
return id;
|
||||
}
|
||||
}
|
||||
const func = Function.init(name, params, ret_ty);
|
||||
const id = self.module.addFunction(func);
|
||||
self.func = id;
|
||||
self.inst_counter = 0;
|
||||
// Reserve refs 0..N-1 for function parameters; instructions start at ref N.
|
||||
self.inst_counter = @intCast(params.len);
|
||||
self.current_block = null;
|
||||
return id;
|
||||
}
|
||||
|
||||
/// Declare an extern function (no body, external linkage).
|
||||
pub fn declareExtern(self: *Builder, name: StringId, params: []const Function.Param, ret_ty: TypeId) FuncId {
|
||||
var func = Function.init(name, params, ret_ty);
|
||||
func.is_extern = true;
|
||||
func.linkage = .external;
|
||||
const id = self.module.addFunction(func);
|
||||
return id;
|
||||
}
|
||||
|
||||
pub fn finalize(self: *Builder) void {
|
||||
self.func = null;
|
||||
self.current_block = null;
|
||||
@@ -160,6 +184,24 @@ pub const Builder = struct {
|
||||
|
||||
pub fn switchToBlock(self: *Builder, block: BlockId) void {
|
||||
self.current_block = block;
|
||||
// Record the starting ref index for this block
|
||||
const func = self.currentFunc();
|
||||
const blk = &func.blocks.items[block.index()];
|
||||
blk.first_ref = self.inst_counter;
|
||||
}
|
||||
|
||||
/// Get the type of a previously emitted instruction Ref.
|
||||
pub fn getRefType(self: *Builder, ref: Ref) TypeId {
|
||||
if (self.func == null) return .s64;
|
||||
const func = self.currentFunc();
|
||||
const ref_idx = @intFromEnum(ref);
|
||||
for (func.blocks.items) |*block| {
|
||||
const first = block.first_ref;
|
||||
if (ref_idx >= first and ref_idx < first + @as(u32, @intCast(block.insts.items.len))) {
|
||||
return block.insts.items[ref_idx - first].ty;
|
||||
}
|
||||
}
|
||||
return .s64;
|
||||
}
|
||||
|
||||
// ── Emit helpers ────────────────────────────────────────────────
|
||||
@@ -405,7 +447,7 @@ pub const Builder = struct {
|
||||
|
||||
// ── Internal helpers ────────────────────────────────────────────
|
||||
|
||||
fn currentFunc(self: *Builder) *Function {
|
||||
pub fn currentFunc(self: *Builder) *Function {
|
||||
return self.module.getFunctionMut(self.func.?);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user