This commit is contained in:
agra
2026-03-04 09:18:24 +02:00
parent 0336f361c7
commit 67e02a20a5
6 changed files with 153 additions and 23 deletions

View File

@@ -192,6 +192,9 @@ pub const LLVMEmitter = struct {
self.declareFunction(&func, @intCast(i));
}
// Pass 1.5: Initialize vtable globals (needs function declarations from Pass 1)
self.initVtableGlobals();
// Pass 2: Emit function bodies
for (self.ir_mod.functions.items, 0..) |func, i| {
if (func.is_extern or func.blocks.items.len == 0) continue;
@@ -279,6 +282,7 @@ pub const LLVMEmitter = struct {
.float => |v| c.LLVMConstReal(llvm_ty, v),
.boolean => |v| c.LLVMConstInt(llvm_ty, @intFromBool(v), 0),
.string => |sid| self.emitConstStringGlobal(self.ir_mod.types.getString(sid)),
.vtable => c.LLVMConstNull(llvm_ty), // placeholder — initialized in initVtableGlobals after function declarations
else => c.LLVMConstNull(llvm_ty),
};
c.LLVMSetInitializer(llvm_global, init_val);
@@ -290,6 +294,35 @@ pub const LLVMEmitter = struct {
}
}
/// Initialize vtable globals with function pointer constants.
/// Must run after Pass 1 (function declarations) so func_map is populated.
fn initVtableGlobals(self: *LLVMEmitter) void {
for (self.ir_mod.globals.items, 0..) |global, i| {
const iv = global.init_val orelse continue;
const func_ids = switch (iv) {
.vtable => |ids| ids,
else => continue,
};
const llvm_global = self.global_map.get(@intCast(i)) orelse continue;
const llvm_ty = self.toLLVMType(global.ty);
// Build constant struct of function pointers
var field_vals = std.ArrayList(c.LLVMValueRef).empty;
defer field_vals.deinit(self.alloc);
for (func_ids) |fid| {
const llvm_func = self.func_map.get(fid.index()) orelse {
field_vals.append(self.alloc, c.LLVMConstNull(self.cached_ptr)) catch unreachable;
continue;
};
field_vals.append(self.alloc, llvm_func) catch unreachable;
}
const init_val = c.LLVMConstNamedStruct(llvm_ty, field_vals.items.ptr, @intCast(field_vals.items.len));
c.LLVMSetInitializer(llvm_global, init_val);
c.LLVMSetGlobalConstant(llvm_global, 1);
}
}
fn valueToLLVMConst(self: *LLVMEmitter, val: Value, llvm_ty: c.LLVMTypeRef) c.LLVMValueRef {
_ = self;
return switch (val) {