...
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user