fixes
This commit is contained in:
@@ -282,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)),
|
||||
.aggregate => |agg| self.emitConstAggregate(agg, llvm_ty),
|
||||
.vtable => c.LLVMConstNull(llvm_ty), // placeholder — initialized in initVtableGlobals after function declarations
|
||||
else => c.LLVMConstNull(llvm_ty),
|
||||
};
|
||||
@@ -354,15 +355,16 @@ pub const LLVMEmitter = struct {
|
||||
|
||||
// main always returns i32 at the LLVM level (JIT expects it)
|
||||
const raw_ret_ty = self.toLLVMType(func.ret);
|
||||
const ret_ty = if (is_main) self.cached_i32 else if (func.is_extern) self.abiCoerceParamType(func.ret, raw_ret_ty) else raw_ret_ty;
|
||||
const needs_c_abi = func.is_extern or func.call_conv == .c;
|
||||
const ret_ty = if (is_main) self.cached_i32 else if (needs_c_abi) self.abiCoerceParamType(func.ret, raw_ret_ty) else raw_ret_ty;
|
||||
|
||||
// Build parameter types — apply C ABI coercion for foreign (extern) functions
|
||||
// Build parameter types — apply C ABI coercion for foreign/callconv(.c) functions
|
||||
const param_count: c_uint = @intCast(func.params.len);
|
||||
const param_types = self.alloc.alloc(c.LLVMTypeRef, func.params.len) catch unreachable;
|
||||
defer self.alloc.free(param_types);
|
||||
for (func.params, 0..) |param, j| {
|
||||
const llvm_ty = self.toLLVMType(param.ty);
|
||||
param_types[j] = if (func.is_extern) self.abiCoerceParamType(param.ty, llvm_ty) else llvm_ty;
|
||||
param_types[j] = if (needs_c_abi) self.abiCoerceParamType(param.ty, llvm_ty) else llvm_ty;
|
||||
}
|
||||
|
||||
const fn_type = c.LLVMFunctionType(ret_ty, param_types.ptr, param_count, 0);
|
||||
@@ -378,6 +380,11 @@ pub const LLVMEmitter = struct {
|
||||
.private => c.LLVMSetLinkage(llvm_func, c.LLVMPrivateLinkage),
|
||||
}
|
||||
|
||||
// Set calling convention
|
||||
if (func.call_conv == .c) {
|
||||
c.LLVMSetFunctionCallConv(llvm_func, c.LLVMCCallConv);
|
||||
}
|
||||
|
||||
// Add frame-pointer and nounwind attributes for correct ARM64 codegen
|
||||
{
|
||||
const fp_kind = "frame-pointer";
|
||||
@@ -2840,6 +2847,23 @@ pub const LLVMEmitter = struct {
|
||||
return c.LLVMConstStructInContext(self.context, &fields, 2, 0);
|
||||
}
|
||||
|
||||
fn emitConstAggregate(self: *LLVMEmitter, agg: []const ir_inst.ConstantValue, llvm_ty: c.LLVMTypeRef) c.LLVMValueRef {
|
||||
const elem_ty = c.LLVMGetElementType(llvm_ty);
|
||||
const n: c_uint = @intCast(agg.len);
|
||||
const vals = self.alloc.alloc(c.LLVMValueRef, agg.len) catch return c.LLVMConstNull(llvm_ty);
|
||||
defer self.alloc.free(vals);
|
||||
for (agg, 0..) |cv, i| {
|
||||
vals[i] = switch (cv) {
|
||||
.int => |v| c.LLVMConstInt(elem_ty, @bitCast(v), 1),
|
||||
.float => |v| c.LLVMConstReal(elem_ty, v),
|
||||
.boolean => |v| c.LLVMConstInt(elem_ty, @intFromBool(v), 0),
|
||||
.aggregate => |inner| self.emitConstAggregate(inner, elem_ty),
|
||||
else => c.LLVMConstNull(elem_ty),
|
||||
};
|
||||
}
|
||||
return c.LLVMConstArray(elem_ty, vals.ptr, n);
|
||||
}
|
||||
|
||||
fn emitStringConstant(self: *LLVMEmitter, str: []const u8) c.LLVMValueRef {
|
||||
// LLVMBuildGlobalStringPtr needs a null-terminated C string
|
||||
const str_z = self.alloc.dupeZ(u8, str) catch unreachable;
|
||||
|
||||
Reference in New Issue
Block a user