Reduce usage of UnpinnedArray to just Compilation

This commit is contained in:
David Gonzalez Martin 2024-04-25 00:10:36 -06:00
parent 7bd4095cd7
commit 8ae3b0caa4
6 changed files with 253 additions and 252 deletions

View File

@ -7,8 +7,9 @@ const write = Compilation.write;
// const logln = Compilation.logln;
const Module = Compilation.Module;
const data_structures = @import("../library.zig");
const BoundedArray = data_structures.BoundedArray;
const MyHashMap = data_structures.MyHashMap;
const UnpinnedArray = data_structures.UnpinnedArray;
const PinnedArray = data_structures.PinnedArray;
pub const bindings = @import("llvm_bindings.zig");
@ -1221,19 +1222,20 @@ pub const LLVM = struct {
return llvm_type;
} else {
const sema_type = unit.types.get(type_index);
var type_buffer = BoundedArray(*LLVM.Type, 512){};
const llvm_type: *LLVM.Type = switch (sema_type.*) {
.function => |function_prototype_index| blk: {
const sema_function_prototype = unit.function_prototypes.get(function_prototype_index);
const llvm_return_type = try llvm.getType(unit, context, sema_function_prototype.abi.return_type);
var parameter_types = try UnpinnedArray(*LLVM.Type).initialize_with_capacity(context.my_allocator, @intCast(sema_function_prototype.abi.parameter_types.len));
var parameter_types = BoundedArray(*LLVM.Type, 512){};
for (sema_function_prototype.abi.parameter_types) |argument_type_index| {
parameter_types.append_with_capacity(try llvm.getType(unit, context, argument_type_index));
parameter_types.appendAssumeCapacity(try llvm.getType(unit, context, argument_type_index));
}
const is_var_args = false;
const llvm_function_type = LLVM.Context.getFunctionType(llvm_return_type, parameter_types.pointer, parameter_types.length, is_var_args) orelse return Type.Error.function;
const llvm_function_type = LLVM.Context.getFunctionType(llvm_return_type, &parameter_types.buffer, parameter_types.len, is_var_args) orelse return Type.Error.function;
break :blk llvm_function_type.toType();
},
.integer => |integer| switch (integer.kind) {
@ -1294,16 +1296,15 @@ pub const LLVM = struct {
break :blk struct_type.toType();
},
.@"struct" => |*sema_struct_type| blk: {
var field_type_list = try UnpinnedArray(*LLVM.Type).initialize_with_capacity(context.my_allocator, sema_struct_type.fields.length);
for (sema_struct_type.fields.slice()) |sema_field_index| {
const sema_field = unit.struct_fields.get(sema_field_index);
const llvm_type = try llvm.getType(unit, context, sema_field.type);
field_type_list.append_with_capacity(llvm_type);
type_buffer.appendAssumeCapacity(llvm_type);
}
// TODO:
const is_packed = false;
const struct_type = llvm.context.getStructType(field_type_list.pointer, field_type_list.length, is_packed) orelse return Type.Error.@"struct";
const struct_type = llvm.context.getStructType(&type_buffer.buffer, type_buffer.len, is_packed) orelse return Type.Error.@"struct";
break :blk struct_type.toType();
},
@ -1363,6 +1364,7 @@ pub const LLVM = struct {
return result;
} else {
const sema_type = unit.types.get(sema_type_index);
var name = BoundedArray(u8, 4096){};
const result: []const u8 = switch (sema_type.*) {
.integer => |integer| switch (integer.kind) {
.materialized_int => b: {
@ -1382,14 +1384,13 @@ pub const LLVM = struct {
},
// .bool => "bool",
.pointer => |pointer| b: {
var name = UnpinnedArray(u8){};
try name.append(context.my_allocator, '&');
name.appendAssumeCapacity('&');
if (pointer.mutability == .@"const") {
try name.append_slice(context.my_allocator, "const");
name.appendSliceAssumeCapacity("const");
}
try name.append(context.my_allocator, ' ');
name.appendAssumeCapacity(' ');
const element_type_name = try llvm.renderTypeName(unit, context, pointer.type);
try name.append_slice(context.my_allocator, element_type_name);
name.appendSliceAssumeCapacity(element_type_name);
break :b name.slice();
},
.@"struct" => |struct_index| switch (unit.structs.get(struct_index).kind) {
@ -1398,24 +1399,22 @@ pub const LLVM = struct {
},
// TODO: termination
.slice => |slice| b: {
var name = UnpinnedArray(u8){};
try name.append_slice(context.my_allocator, "[] ");
name.appendSliceAssumeCapacity("[] ");
if (slice.mutability == .@"const") {
try name.append_slice(context.my_allocator, "const ");
name.appendSliceAssumeCapacity("const ");
}
const element_type_name = try llvm.renderTypeName(unit, context, slice.child_type);
try name.append_slice(context.my_allocator, element_type_name);
name.appendSliceAssumeCapacity(element_type_name);
break :b name.slice();
},
.array => |array| b: {
var name = UnpinnedArray(u8){};
try name.append(context.my_allocator, '[');
name.appendAssumeCapacity('[');
var buffer: [65]u8 = undefined;
const array_count = data_structures.format_int(&buffer, array.count, 10, false);
try name.append_slice(context.my_allocator, array_count);
try name.append(context.my_allocator, ']');
name.appendSliceAssumeCapacity(array_count);
name.appendAssumeCapacity(']');
const element_type_name = try llvm.renderTypeName(unit, context, array.type);
try name.append_slice(context.my_allocator, element_type_name);
name.appendSliceAssumeCapacity(element_type_name);
break :b name.slice();
},
@ -1425,7 +1424,12 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)),
};
try llvm.type_name_map.put(context.my_allocator, sema_type_index, result);
try llvm.type_name_map.put(context.my_allocator, sema_type_index, if (name.len > 0) b: {
const new_name = try context.arena.new_array(u8, name.len);
@memcpy(new_name, result);
break :b new_name;
} else result);
return result;
}
@ -1530,7 +1534,7 @@ pub const LLVM = struct {
});
try llvm.debug_type_map.put_no_clobber(context.my_allocator, sema_type_index, struct_type.toType());
var field_types = try UnpinnedArray(*LLVM.DebugInfo.Type).initialize_with_capacity(context.my_allocator, @intCast(fields.len));
var field_types = BoundedArray(*LLVM.DebugInfo.Type, 512){};
bit_size = 0;
for (fields) |struct_field_index| {
@ -1541,11 +1545,11 @@ pub const LLVM = struct {
const field_name = unit.getIdentifier(struct_field.name);
const alignment = struct_field_bit_size;
const member_type = llvm.debug_info_builder.createMemberType(null, field_name.ptr, field_name.len, file, 0, struct_field_bit_size, alignment, bit_size, flags, field_type).toType();
field_types.append_with_capacity(member_type);
field_types.appendAssumeCapacity(member_type);
bit_size += struct_field_bit_size;
}
llvm.debug_info_builder.replaceCompositeTypes(struct_type, field_types.pointer, field_types.length);
llvm.debug_info_builder.replaceCompositeTypes(struct_type, &field_types.buffer, field_types.len);
return struct_type.toType();
}
@ -1629,14 +1633,17 @@ pub const LLVM = struct {
break :b boolean_type;
},
.@"enum" => |*enum_type| b: {
var enumerators = try UnpinnedArray(*LLVM.DebugInfo.Type.Enumerator).initialize_with_capacity(context.my_allocator, enum_type.fields.length);
var enumerators = try context.arena.new_array(*LLVM.DebugInfo.Type.Enumerator, enum_type.fields.length);
enumerators.len = 0;
for (enum_type.fields.slice()) |enum_field_index| {
const enum_field = unit.enum_fields.get(enum_field_index);
const enum_field_name = unit.getIdentifier(enum_field.name);
const is_unsigned = true;
const enumerator = llvm.debug_info_builder.createEnumerator(enum_field_name.ptr, enum_field_name.len, enum_field.value, is_unsigned) orelse unreachable;
enumerators.append_with_capacity(enumerator);
const index = enumerators.len;
enumerators.len += 1;
enumerators[index] = enumerator;
}
const type_declaration = unit.type_declarations.get(sema_type_index).?;
@ -1651,18 +1658,21 @@ pub const LLVM = struct {
const alignment = 0;
const line = type_declaration.declaration.line + 1;
const scope = try llvm.getScope(unit, context, enum_type.scope.scope.parent.?);
const enumeration_type = llvm.debug_info_builder.createEnumerationType(scope, name.ptr, name.len, file, line, bit_size, alignment, enumerators.pointer, enumerators.length, backing_type) orelse unreachable;
const enumeration_type = llvm.debug_info_builder.createEnumerationType(scope, name.ptr, name.len, file, line, bit_size, alignment, enumerators.ptr, enumerators.len, backing_type) orelse unreachable;
break :b enumeration_type.toType();
},
.@"error" => |*error_type| b: {
var enumerators = try UnpinnedArray(*LLVM.DebugInfo.Type.Enumerator).initialize_with_capacity(context.my_allocator, error_type.fields.length);
var enumerators = try context.arena.new_array(*LLVM.DebugInfo.Type.Enumerator, error_type.fields.length);
enumerators.len = 0;
for (error_type.fields.slice()) |error_field_index| {
const error_field = unit.error_fields.get(error_field_index);
const error_field_name = unit.getIdentifier(error_field.name);
const is_unsigned = true;
const enumerator = llvm.debug_info_builder.createEnumerator(error_field_name.ptr, error_field_name.len, error_field.value, is_unsigned) orelse unreachable;
enumerators.append_with_capacity(enumerator);
const index = enumerators.len;
enumerators.len += 1;
enumerators[index] = enumerator;
}
const type_declaration = unit.type_declarations.get(sema_type_index).?;
@ -1677,7 +1687,7 @@ pub const LLVM = struct {
const alignment = 0;
const line = type_declaration.declaration.line + 1;
const scope = try llvm.getScope(unit, context, error_type.scope.scope.parent.?);
const enumeration_type = llvm.debug_info_builder.createEnumerationType(scope, name.ptr, name.len, file, line, bit_size, alignment, enumerators.pointer, enumerators.length, backing_type) orelse unreachable;
const enumeration_type = llvm.debug_info_builder.createEnumerationType(scope, name.ptr, name.len, file, line, bit_size, alignment, enumerators.ptr, enumerators.len, backing_type) orelse unreachable;
break :b enumeration_type.toType();
},
else => |t| @panic(@tagName(t)),
@ -1791,10 +1801,10 @@ pub const LLVM = struct {
},
.function => |function_prototype_index| b: {
const function_prototype = unit.function_prototypes.get(function_prototype_index);
var parameter_types = try UnpinnedArray(*LLVM.DebugInfo.Type).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.argument_types.len));
var parameter_types = BoundedArray(*LLVM.DebugInfo.Type, 512){};
for (function_prototype.argument_types) |argument_type_index| {
const argument_type = try llvm.getDebugType(unit, context, argument_type_index);
parameter_types.append_with_capacity(argument_type);
parameter_types.appendAssumeCapacity(argument_type);
}
const subroutine_type_flags = LLVM.DebugInfo.Node.Flags{
.visibility = .none,
@ -1826,7 +1836,7 @@ pub const LLVM = struct {
.all_calls_described = false,
};
const subroutine_type_calling_convention = LLVM.DebugInfo.CallingConvention.none;
const subroutine_type = llvm.debug_info_builder.createSubroutineType(parameter_types.pointer, parameter_types.length, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
const subroutine_type = llvm.debug_info_builder.createSubroutineType(&parameter_types.buffer, parameter_types.len, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
break :b subroutine_type.toType();
},
else => |t| @panic(@tagName(t)),
@ -2072,7 +2082,9 @@ pub const LLVM = struct {
const sema_array_type = unit.types.get(constant_array.type).array;
const constant_type = try llvm.getType(unit, context, constant_array.type);
const array_type = constant_type.toArray() orelse unreachable;
var list = try UnpinnedArray(*LLVM.Value.Constant).initialize_with_capacity(context.my_allocator, @intCast(constant_array.values.len));
var list = try context.arena.new_array(*LLVM.Value.Constant, constant_array.values.len);
list.len = 0;
for (constant_array.values) |sema_value| {
const value = switch (sema_value) {
.constant_int => |const_int| b: {
@ -2099,16 +2111,19 @@ pub const LLVM = struct {
},
else => |t| @panic(@tagName(t)),
};
list.append_with_capacity(value);
const index = list.len;
list.len += 1;
list[index] = value;
}
const result = array_type.getConstant(list.pointer, list.length) orelse unreachable;
const result = array_type.getConstant(list.ptr, list.len) orelse unreachable;
return result;
}
fn getConstantStruct(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, constant_struct_index: Compilation.V.Comptime.ConstantStruct.Index) !*LLVM.Value.Constant {
const constant_struct = unit.constant_structs.get(constant_struct_index);
var field_values = try UnpinnedArray(*LLVM.Value.Constant).initialize_with_capacity(context.my_allocator, @intCast(constant_struct.fields.len));
var field_values = BoundedArray(*LLVM.Value.Constant, 512){};
const sema_struct_index = unit.types.get(constant_struct.type).@"struct";
const sema_struct = unit.structs.get(sema_struct_index);
const llvm_type = try llvm.getType(unit, context, constant_struct.type);
@ -2119,7 +2134,7 @@ pub const LLVM = struct {
for (constant_struct.fields, sema_struct_type.fields.slice()) |field_value, field_index| {
const field = unit.struct_fields.get(field_index);
const constant = try llvm.emitComptimeRightValue(unit, context, field_value, field.type);
field_values.append_with_capacity(constant);
field_values.appendAssumeCapacity(constant);
}
},
.error_union => |error_union| {
@ -2130,7 +2145,7 @@ pub const LLVM = struct {
const field_types = [2]Compilation.Type.Index{ err_union_base_type, .bool };
for (field_types, constant_struct.fields) |field_type_index, field_value| {
const constant = try llvm.emitComptimeRightValue(unit, context, field_value, field_type_index);
field_values.append_with_capacity(constant);
field_values.appendAssumeCapacity(constant);
}
},
else => |t| @panic(@tagName(t)),
@ -2141,7 +2156,7 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)),
}
const const_struct = struct_type.getConstant(field_values.pointer, field_values.length) orelse unreachable;
const const_struct = struct_type.getConstant(&field_values.buffer, field_values.len) orelse unreachable;
return const_struct;
}
@ -2162,9 +2177,9 @@ pub const LLVM = struct {
}
fn emitParameterAttributes(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, abi: Compilation.Function.AbiInfo, is_return: bool) !*const LLVM.Attribute.Set {
var attributes = UnpinnedArray(*LLVM.Attribute){};
var attributes = BoundedArray(*LLVM.Attribute, 256){};
if (abi.attributes.by_reg) {
try attributes.append(context.my_allocator, llvm.attributes.inreg);
attributes.appendAssumeCapacity(llvm.attributes.inreg);
}
switch (abi.kind) {
.ignore => {
@ -2175,39 +2190,39 @@ pub const LLVM = struct {
const indirect_type = try llvm.getType(unit, context, indirect.type);
if (is_return) {
const sret = llvm.context.getAttributeFromType(.StructRet, indirect_type);
try attributes.append(context.my_allocator, sret);
try attributes.append(context.my_allocator, llvm.attributes.@"noalias");
attributes.appendAssumeCapacity(sret);
attributes.appendAssumeCapacity(llvm.attributes.@"noalias");
// TODO: alignment
} else {
if (abi.attributes.by_value) {
const byval = llvm.context.getAttributeFromType(.ByVal, indirect_type);
try attributes.append(context.my_allocator, byval);
attributes.appendAssumeCapacity(byval);
}
//TODO: alignment
}
},
else => |t| @panic(@tagName(t)),
}
const attribute_set = llvm.context.getAttributeSet(attributes.pointer, attributes.length);
const attribute_set = llvm.context.getAttributeSet(&attributes.buffer, attributes.len);
return attribute_set;
}
fn getFunctionAttributes(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, function_prototype: *Compilation.Function.Prototype) !*const LLVM.Attribute.Set {
var function_attributes = UnpinnedArray(*LLVM.Attribute){};
try function_attributes.append(context.my_allocator, llvm.attributes.nounwind);
fn getFunctionAttributes(llvm: *LLVM, unit: *Compilation.Unit, function_prototype: *Compilation.Function.Prototype) *const LLVM.Attribute.Set {
var function_attributes = BoundedArray(*LLVM.Attribute, 256){};
function_attributes.appendAssumeCapacity(llvm.attributes.nounwind);
switch (unit.types.get(function_prototype.return_type).*) {
.noreturn => {
try function_attributes.append(context.my_allocator, llvm.attributes.noreturn);
function_attributes.appendAssumeCapacity(llvm.attributes.noreturn);
},
else => {},
}
if (function_prototype.attributes.naked) {
try function_attributes.append(context.my_allocator, llvm.attributes.naked);
function_attributes.appendAssumeCapacity(llvm.attributes.naked);
}
const function_attribute_set = llvm.context.getAttributeSet(function_attributes.pointer, function_attributes.length);
const function_attribute_set = llvm.context.getAttributeSet(&function_attributes.buffer, function_attributes.len);
return function_attribute_set;
}
@ -2217,14 +2232,14 @@ pub const LLVM = struct {
};
fn setCallOrFunctionAttributes(llvm: *LLVM, unit: *Compilation.Unit, context: *const Compilation.Context, function_prototype: *Compilation.Function.Prototype, call_or_function: CallOrFunction) !void {
const function_attribute_set = try llvm.getFunctionAttributes(unit, context, function_prototype);
const function_attribute_set = llvm.getFunctionAttributes(unit, function_prototype);
var parameter_attribute_sets = try UnpinnedArray(*const LLVM.Attribute.Set).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.abi.parameter_types_abi.len + @intFromBool(function_prototype.abi.return_type_abi.kind == .indirect)));
var parameter_attribute_sets = BoundedArray(*const LLVM.Attribute.Set, 512){};
const return_attribute_set = blk: {
const attribute_set = try llvm.emitParameterAttributes(unit, context, function_prototype.abi.return_type_abi, true);
break :blk switch (function_prototype.abi.return_type_abi.kind) {
.indirect => b: {
parameter_attribute_sets.append_with_capacity(attribute_set);
parameter_attribute_sets.appendAssumeCapacity(attribute_set);
break :b llvm.context.getAttributeSet(null, 0);
},
else => attribute_set,
@ -2233,18 +2248,18 @@ pub const LLVM = struct {
for (function_prototype.abi.parameter_types_abi) |parameter_type_abi| {
const parameter_attribute_set = try llvm.emitParameterAttributes(unit, context, parameter_type_abi, false);
parameter_attribute_sets.append_with_capacity(parameter_attribute_set);
parameter_attribute_sets.appendAssumeCapacity(parameter_attribute_set);
}
const calling_convention = getCallingConvention(function_prototype.calling_convention);
switch (call_or_function) {
.call => |call| {
call.setAttributes(llvm.context, function_attribute_set, return_attribute_set, parameter_attribute_sets.pointer, parameter_attribute_sets.length);
call.setAttributes(llvm.context, function_attribute_set, return_attribute_set, &parameter_attribute_sets.buffer, parameter_attribute_sets.len);
call.setCallingConvention(calling_convention);
},
.function => |function| {
function.setAttributes(llvm.context, function_attribute_set, return_attribute_set, parameter_attribute_sets.pointer, parameter_attribute_sets.length);
function.setAttributes(llvm.context, function_attribute_set, return_attribute_set, &parameter_attribute_sets.buffer, parameter_attribute_sets.len);
function.setCallingConvention(calling_convention);
},
}
@ -2286,10 +2301,10 @@ pub const LLVM = struct {
if (generate_debug_information) {
// if (data_structures.byte_equal(name, "nat_split_struct_ints")) @breakpoint();
const debug_file = try llvm.getDebugInfoFile(unit, context, declaration.declaration.scope.file);
var parameter_types = try UnpinnedArray(*LLVM.DebugInfo.Type).initialize_with_capacity(context.my_allocator, @intCast(function_prototype.argument_types.len));
var parameter_types = BoundedArray(*LLVM.DebugInfo.Type, 512){};
for (function_prototype.argument_types) |argument_type_index| {
const argument_type = try llvm.getDebugType(unit, context, argument_type_index);
parameter_types.append_with_capacity(argument_type);
parameter_types.appendAssumeCapacity(argument_type);
}
const subroutine_type_flags = LLVM.DebugInfo.Node.Flags{
@ -2322,7 +2337,7 @@ pub const LLVM = struct {
.all_calls_described = false,
};
const subroutine_type_calling_convention = LLVM.DebugInfo.CallingConvention.none;
const subroutine_type = llvm.debug_info_builder.createSubroutineType(parameter_types.pointer, parameter_types.length, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
const subroutine_type = llvm.debug_info_builder.createSubroutineType(&parameter_types.buffer, parameter_types.len, subroutine_type_flags, subroutine_type_calling_convention) orelse unreachable;
const subprogram_flags = LLVM.DebugInfo.Subprogram.Flags{
.virtuality = .none,
.local_to_unit = !export_or_extern,
@ -2570,10 +2585,10 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.inline_assembly => |inline_assembly_index| {
const assembly_block = unit.inline_assembly.get(inline_assembly_index);
var assembly_statements = UnpinnedArray(u8){};
var constraints = UnpinnedArray(u8){};
var operand_values = UnpinnedArray(*LLVM.Value){};
var operand_types = UnpinnedArray(*LLVM.Type){};
var assembly_statements = BoundedArray(u8, 4096){};
var constraints = BoundedArray(u8, 4096){};
var operand_values = BoundedArray(*LLVM.Value, 256){};
var operand_types = BoundedArray(*LLVM.Type, 256){};
switch (unit.descriptor.arch) {
.x86_64 => {
@ -2581,13 +2596,13 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const instruction = unit.assembly_instructions.get(assembly_instruction_index);
const instruction_id: Compilation.InlineAssembly.x86_64.Instruction = @enumFromInt(instruction.id);
try assembly_statements.append_slice(context.my_allocator, switch (instruction_id) {
assembly_statements.appendSliceAssumeCapacity(switch (instruction_id) {
.xor => "xorl",
.mov => "movq",
.@"and" => "andq",
.call => "callq",
});
try assembly_statements.append(context.my_allocator, ' ');
assembly_statements.appendAssumeCapacity(' ');
if (instruction.operands.len > 0) {
var reverse_operand_iterator = std.mem.reverseIterator(instruction.operands);
@ -2596,8 +2611,8 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
switch (operand) {
.register => |register_value| {
const register: Compilation.InlineAssembly.x86_64.Register = @enumFromInt(register_value);
try assembly_statements.append(context.my_allocator, '%');
try assembly_statements.append_slice(context.my_allocator, @tagName(register));
assembly_statements.appendAssumeCapacity('%');
assembly_statements.appendSliceAssumeCapacity(@tagName(register));
},
.number_literal => |literal| {
var buffer: [65]u8 = undefined;
@ -2608,7 +2623,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
literal_slice[1] = '$';
literal_slice[2] = '0';
literal_slice[3] = 'x';
try assembly_statements.append_slice(context.my_allocator, try context.my_allocator.duplicate_bytes(literal_slice));
assembly_statements.appendSliceAssumeCapacity(try context.my_allocator.duplicate_bytes(literal_slice));
},
.value => |sema_value| {
if (llvm.llvm_value_map.get(sema_value)) |v| {
@ -2617,7 +2632,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
} else {
const value = try llvm.emitLeftValue(unit, context, sema_value);
var buffer: [65]u8 = undefined;
const operand_number = data_structures.format_int(&buffer, operand_values.length, 16, false);
const operand_number = data_structures.format_int(&buffer, operand_values.len, 16, false);
const slice_ptr = operand_number.ptr - 2;
const operand_slice = slice_ptr[0 .. operand_number.len + 2];
operand_slice[0] = '$';
@ -2628,23 +2643,23 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
new_buffer[operand_slice.len + 1] = 'P';
new_buffer[operand_slice.len + 2] = '}';
const new_slice = try context.my_allocator.duplicate_bytes(new_buffer[0 .. operand_slice.len + 3]);
try assembly_statements.append_slice(context.my_allocator, new_slice);
try operand_values.append(context.my_allocator, value);
assembly_statements.appendSliceAssumeCapacity(new_slice);
operand_values.appendAssumeCapacity(value);
const value_type = value.getType();
try operand_types.append(context.my_allocator, value_type);
try constraints.append(context.my_allocator, 'X');
operand_types.appendAssumeCapacity(value_type);
constraints.appendAssumeCapacity('X');
}
},
}
try assembly_statements.append_slice(context.my_allocator, ", ");
assembly_statements.appendSliceAssumeCapacity(", ");
}
_ = assembly_statements.pop();
_ = assembly_statements.pop();
}
try assembly_statements.append_slice(context.my_allocator, "\n\t");
assembly_statements.appendSliceAssumeCapacity("\n\t");
}
// try constraints.append_slice(context.allocator, ",~{dirflag},~{fpsr},~{flags}");
@ -2653,14 +2668,14 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
}
const is_var_args = false;
const function_type = LLVM.Context.getFunctionType(try llvm.getType(unit, context, Compilation.Type.Index.void), operand_types.pointer, operand_types.length, is_var_args) orelse unreachable;
const function_type = LLVM.Context.getFunctionType(try llvm.getType(unit, context, Compilation.Type.Index.void), &operand_types.buffer, operand_types.len, is_var_args) orelse unreachable;
const has_side_effects = true;
const is_align_stack = true;
const dialect = LLVM.Value.InlineAssembly.Dialect.@"at&t";
const can_throw = false;
const inline_assembly = LLVM.Value.InlineAssembly.get(function_type, assembly_statements.pointer, assembly_statements.length, constraints.pointer, constraints.length, has_side_effects, is_align_stack, dialect, can_throw) orelse return LLVM.Value.Error.inline_assembly;
const call = llvm.builder.createCall(function_type, inline_assembly.toValue(), operand_values.pointer, operand_values.length, "", "".len, null) orelse return LLVM.Value.Instruction.Error.call;
const inline_assembly = LLVM.Value.InlineAssembly.get(function_type, &assembly_statements.buffer, assembly_statements.len, &constraints.buffer, constraints.len, has_side_effects, is_align_stack, dialect, can_throw) orelse return LLVM.Value.Error.inline_assembly;
const call = llvm.builder.createCall(function_type, inline_assembly.toValue(), &operand_values.buffer, operand_values.len, "", "".len, null) orelse return LLVM.Value.Instruction.Error.call;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, call.toValue());
},
.stack_slot => |stack_slot| {
@ -2876,27 +2891,27 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const return_type = try llvm.getType(unit, context, Compilation.Type.usize);
const is_var_args = false;
const function_type = LLVM.Context.getFunctionType(return_type, syscall_argument_types.ptr, syscall_argument_types.len, is_var_args) orelse unreachable;
var constraints = UnpinnedArray(u8){};
var constraints = BoundedArray(u8, 4096){};
const inline_asm = switch (unit.descriptor.arch) {
.x86_64 => blk: {
try constraints.append_slice(context.my_allocator, "={rax}");
constraints.appendSliceAssumeCapacity("={rax}");
const syscall_registers = [7][]const u8{ "rax", "rdi", "rsi", "rdx", "r10", "r8", "r9" };
for (syscall_registers[0..syscall_argument_count]) |syscall_register| {
try constraints.append(context.my_allocator, ',');
try constraints.append(context.my_allocator, '{');
try constraints.append_slice(context.my_allocator, syscall_register);
try constraints.append(context.my_allocator, '}');
constraints.appendAssumeCapacity(',');
constraints.appendAssumeCapacity('{');
constraints.appendSliceAssumeCapacity(syscall_register);
constraints.appendAssumeCapacity('}');
}
try constraints.append_slice(context.my_allocator, ",~{rcx},~{r11},~{memory}");
constraints.appendSliceAssumeCapacity(",~{rcx},~{r11},~{memory}");
const assembly = "syscall";
const has_side_effects = true;
const is_align_stack = true;
const can_throw = false;
const inline_assembly = LLVM.Value.InlineAssembly.get(function_type, assembly, assembly.len, constraints.pointer, constraints.length, has_side_effects, is_align_stack, LLVM.Value.InlineAssembly.Dialect.@"at&t", can_throw) orelse return LLVM.Value.Error.inline_assembly;
const inline_assembly = LLVM.Value.InlineAssembly.get(function_type, assembly, assembly.len, &constraints.buffer, constraints.len, has_side_effects, is_align_stack, LLVM.Value.InlineAssembly.Dialect.@"at&t", can_throw) orelse return LLVM.Value.Error.inline_assembly;
break :blk inline_assembly;
},
else => |t| @panic(@tagName(t)),
@ -3129,8 +3144,10 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
last_block = else_block_node;
break :b bb;
} else null;
var basic_block_array = try UnpinnedArray(*LLVM.Value.BasicBlock).initialize_with_capacity(context.my_allocator, switch_expression.cases.length);
var condition_array = try UnpinnedArray(*LLVM.Value.Constant.Int).initialize_with_capacity(context.my_allocator, switch_expression.cases.length);
var basic_block_array = BoundedArray(*LLVM.Value.BasicBlock, 4096){};
var condition_array = BoundedArray(*LLVM.Value.Constant.Int, 4096){};
for (switch_expression.cases.pointer[0..switch_expression.cases.length]) |case| {
const constant_value = try llvm.emitComptimeRightValue(unit, context, case.condition, switch_expression.condition.type);
const constant_int = constant_value.toInt() orelse unreachable;
@ -3141,13 +3158,13 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const block = llvm.llvm_block_map.get(case.basic_block).?;
break :b block;
};
condition_array.append_with_capacity(constant_int);
basic_block_array.append_with_capacity(block);
condition_array.appendAssumeCapacity(constant_int);
basic_block_array.appendAssumeCapacity(block);
}
const branch_weights = null;
const unpredictable = null;
const switch_instruction = llvm.builder.createSwitch(condition, else_block, condition_array.pointer, basic_block_array.pointer, condition_array.length, branch_weights, unpredictable);
const switch_instruction = llvm.builder.createSwitch(condition, else_block, &condition_array.buffer, &basic_block_array.buffer, condition_array.len, branch_weights, unpredictable);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, switch_instruction.toValue());
},
.memcpy => |memcpy| {
@ -3207,8 +3224,6 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const result = llvm.function.verify(&message_ptr, &message_len);
if (!result) {
// std.debug.print("PANIC: Failed to verify function:\n{s}\n", .{error_message});
var module_len: usize = 0;
const module_ptr = llvm.module.toString(&module_len);
const module_dump = module_ptr[0..module_len];
@ -3269,25 +3284,34 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.windows => "x86_64-windows-gnu",
};
const cpu = "generic";
const temp_use_native_features = true;
const features = if (temp_use_native_features) blk: {
var buffer = UnpinnedArray(u8){};
for (@import("builtin").cpu.arch.allFeaturesList(), 0..) |feature, index_usize| {
const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
const is_enabled = @import("builtin").cpu.features.isEnabled(index);
if (feature.llvm_name) |llvm_name| {
const plus_or_minus = "-+"[@intFromBool(is_enabled)];
try buffer.append(context.my_allocator, plus_or_minus);
try buffer.append_slice(context.my_allocator, llvm_name);
try buffer.append_slice(context.my_allocator, ",");
var features = PinnedArray(u8){
.pointer = @constCast(@ptrCast("")),
.length = 0,
.granularity = 0,
};
const temp_use_native_features = true;
if (temp_use_native_features) {
const feature_list = @import("builtin").cpu.arch.allFeaturesList();
if (feature_list.len > 0) {
features = try PinnedArray(u8).init_with_default_granularity();
for (feature_list, 0..) |feature, index_usize| {
const index = @as(std.Target.Cpu.Feature.Set.Index, @intCast(index_usize));
const is_enabled = @import("builtin").cpu.features.isEnabled(index);
if (feature.llvm_name) |llvm_name| {
const plus_or_minus = "-+"[@intFromBool(is_enabled)];
_ = features.append(plus_or_minus);
features.append_slice(llvm_name);
features.append_slice(",");
}
}
assert(std.mem.endsWith(u8, features.slice(), ","));
features.length -= 1;
}
if (buffer.length == 0) break :blk "";
assert(std.mem.endsWith(u8, buffer.slice(), ","));
buffer.slice()[buffer.length - 1] = 0;
break :blk buffer.slice()[0 .. buffer.length - 1 :0];
} else "";
}
const target = blk: {
var error_message: [*]const u8 = undefined;
@ -3306,7 +3330,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.optimize_for_speed, .optimize_for_size => .default,
.aggressively_optimize_for_speed, .aggressively_optimize_for_size => .aggressive,
};
const target_machine = target.createTargetMachine(target_triple.ptr, target_triple.len, cpu, cpu.len, features.ptr, features.len, LLVM.RelocationModel.static, code_model, is_code_model_present, codegen_optimization_level, jit) orelse unreachable;
const target_machine = target.createTargetMachine(target_triple.ptr, target_triple.len, cpu, cpu.len, features.pointer, features.length, LLVM.RelocationModel.static, code_model, is_code_model_present, codegen_optimization_level, jit) orelse unreachable;
llvm.module.setTargetMachineDataLayout(target_machine);
llvm.module.setTargetTriple(target_triple.ptr, target_triple.len);
const file_path = unit.descriptor.executable_path;

View File

@ -8,7 +8,6 @@ const byte_equal = library.byte_equal;
const enumFromString = library.enumFromString;
const MyAllocator = library.MyAllocator;
const PinnedArray = library.PinnedArray;
const UnpinnedArray = library.UnpinnedArray;
const Compilation = @import("../Compilation.zig");
const File = Compilation.File;

View File

@ -363,7 +363,7 @@ const Analyzer = struct {
}
} else @panic(identifier_name);
try stack_list.append(attribute_node);
stack_list.appendAssumeCapacity(attribute_node);
switch (analyzer.peekToken()) {
.operator_assign => {},
@ -462,7 +462,7 @@ const Analyzer = struct {
}
} else @panic(identifier_name);
try attribute_and_return_type_node_list.append(attribute_node);
attribute_and_return_type_node_list.appendAssumeCapacity(attribute_node);
if (analyzer.peekToken() == .operator_comma) analyzer.consumeToken();
}
@ -471,7 +471,7 @@ const Analyzer = struct {
const arguments = try analyzer.argumentList(.operator_left_parenthesis, .operator_right_parenthesis);
const return_type = try analyzer.typeExpression();
try attribute_and_return_type_node_list.append(return_type);
attribute_and_return_type_node_list.appendAssumeCapacity(return_type);
const function_prototype = try analyzer.addNode(.{
.id = .function_prototype,
@ -510,7 +510,7 @@ const Analyzer = struct {
analyzer.consumeToken();
}
try list.append(try analyzer.addNode(.{
list.appendAssumeCapacity(try analyzer.addNode(.{
.id = id,
.token = identifier_token,
.left = type_expression,
@ -552,7 +552,7 @@ const Analyzer = struct {
=> try analyzer.symbolDeclaration(),
};
try list.append(statement_index);
list.appendAssumeCapacity(statement_index);
}
_ = try analyzer.expectToken(.operator_right_brace);
@ -627,7 +627,7 @@ const Analyzer = struct {
else => left,
};
try array_list.append(switch_case_node);
array_list.appendAssumeCapacity(switch_case_node);
switch (analyzer.peekToken()) {
.operator_comma => analyzer.consumeToken(),
@ -660,7 +660,7 @@ const Analyzer = struct {
.right = expr,
});
try list.append(node);
list.appendAssumeCapacity(node);
}
_ = try analyzer.expectToken(.operator_right_brace);
@ -770,7 +770,7 @@ const Analyzer = struct {
else => |t| @panic(@tagName(t)),
};
try for_expression_list.append(node_index);
for_expression_list.appendAssumeCapacity(node_index);
switch (analyzer.peekToken()) {
.operator_comma => analyzer.consumeToken(),
@ -801,7 +801,7 @@ const Analyzer = struct {
else => |t| @panic(@tagName(t)),
}
try payload_nodes.append(try analyzer.addNode(.{
payload_nodes.appendAssumeCapacity(try analyzer.addNode(.{
.id = id,
.token = payload_token,
.left = Node.Index.null,
@ -992,7 +992,7 @@ const Analyzer = struct {
.operator_semicolon => {},
else => |t| @panic(@tagName(t)),
}
try operand_list.append(node);
operand_list.appendAssumeCapacity(node);
}
analyzer.consumeToken();
@ -1004,7 +1004,7 @@ const Analyzer = struct {
.right = try analyzer.nodeList(&operand_list),
});
try instruction_list.append(instruction);
instruction_list.appendAssumeCapacity(instruction);
}
_ = try analyzer.expectToken(.operator_backtick);
@ -1016,7 +1016,7 @@ const Analyzer = struct {
.left = try analyzer.nodeList(&instruction_list),
.right = .null,
});
try list.append(assembly_block);
list.appendAssumeCapacity(assembly_block);
const intrinsic = try analyzer.addNode(.{
.id = .intrinsic,
@ -1029,7 +1029,7 @@ const Analyzer = struct {
} else {
while (analyzer.peekToken() != .operator_right_parenthesis) {
const parameter = try analyzer.expression();
try list.append(parameter);
list.appendAssumeCapacity(parameter);
switch (analyzer.peekToken()) {
.operator_comma => analyzer.consumeToken(),
@ -1465,7 +1465,7 @@ const Analyzer = struct {
break :blk .pointer_type;
},
.many_pointer_type => blk: {
try list.append(try analyzer.addNode(.{
list.appendAssumeCapacity(try analyzer.addNode(.{
.id = .many_pointer_expression,
.token = analyzer.token_i,
.left = Node.Index.null,
@ -1475,7 +1475,7 @@ const Analyzer = struct {
_ = try analyzer.expectToken(.operator_ampersand);
switch (analyzer.peekToken()) {
.operator_right_bracket => {},
.operator_colon => try list.append(try analyzer.parseTermination()),
.operator_colon => list.appendAssumeCapacity(try analyzer.parseTermination()),
else => |t| @panic(@tagName(t)),
}
_ = try analyzer.expectToken(.operator_right_bracket);
@ -1490,17 +1490,17 @@ const Analyzer = struct {
break :blk .slice_type;
},
.operator_colon => {
try list.append(try analyzer.parseTermination());
list.appendAssumeCapacity(try analyzer.parseTermination());
_ = try analyzer.expectToken(.operator_right_bracket);
break :blk .slice_type;
},
else => {
const length_expression = try analyzer.expression();
try list.append(length_expression);
list.appendAssumeCapacity(length_expression);
switch (analyzer.peekToken()) {
.operator_right_bracket => {},
.operator_colon => try list.append(try analyzer.parseTermination()),
.operator_colon => list.appendAssumeCapacity(try analyzer.parseTermination()),
else => |t| @panic(@tagName(t)),
}
@ -1525,7 +1525,7 @@ const Analyzer = struct {
analyzer.consumeTokens(@intFromBool(analyzer.peekToken() == .fixed_keyword_const));
if (const_node != .null) {
try list.append(const_node);
list.appendAssumeCapacity(const_node);
}
} else {
assert(list.len > 0);
@ -1533,7 +1533,7 @@ const Analyzer = struct {
const type_expression = try analyzer.typeExpression();
assert(type_expression != .null);
try list.append(type_expression);
list.appendAssumeCapacity(type_expression);
const node_list = try analyzer.nodeList(&list);
@ -1544,15 +1544,7 @@ const Analyzer = struct {
.right = Node.Index.null,
};
// logln(.parser, .pointer_like_type_expression, "ARRAY START\n===========", .{});
// for (list.slice()) |ni| {
// const n = analyzer.nodes.get(ni);
// logln(.parser, .pointer_like_type_expression, "{s} node element: {s}", .{ @tagName(expression_type), @tagName(n.id) });
// }
// logln(.parser, .pointer_like_type_expression, "ARRAY END\n=========", .{});
const node_index = try analyzer.addNode(node);
// logln(.parser, .pointer_like_type_expression, "Pointer end", .{});
switch (analyzer.peekToken()) {
.operator_comma,
@ -1663,7 +1655,7 @@ const Analyzer = struct {
});
}
try expression_list.append(parameter);
expression_list.appendAssumeCapacity(parameter);
switch (analyzer.peekToken()) {
.operator_right_parenthesis => {},
@ -1726,7 +1718,7 @@ const Analyzer = struct {
.right = Node.Index.null,
});
try list.append(field_initialization);
list.appendAssumeCapacity(field_initialization);
switch (analyzer.peekToken()) {
.operator_comma => analyzer.consumeToken(),
else => {},
@ -1737,7 +1729,7 @@ const Analyzer = struct {
else => |t| @panic(@tagName(t)),
},
else => blk: {
try list.append(try analyzer.anonymousExpression());
list.appendAssumeCapacity(try analyzer.anonymousExpression());
_ = try analyzer.expectToken(.operator_comma);
break :blk .anonymous;
},
@ -1754,7 +1746,7 @@ const Analyzer = struct {
else => {},
}
try list.append(field_expression_initializer);
list.appendAssumeCapacity(field_expression_initializer);
break :blk .anonymous;
},
else => |t| @panic(@tagName(t)),
@ -1837,7 +1829,7 @@ const Analyzer = struct {
var list = Node.StackList{};
while (analyzer.peekToken() != .operator_right_parenthesis) {
const parameter_node = try analyzer.expression();
try list.append(parameter_node);
list.appendAssumeCapacity(parameter_node);
switch (analyzer.peekToken()) {
.operator_comma => analyzer.consumeToken(),
else => {},
@ -1935,7 +1927,7 @@ const Analyzer = struct {
// logln(.parser, .container_members, "Container member {s}", .{@tagName(member_node.id)});
assert(member_node.id != .identifier);
try list.append(member_node_index);
list.appendAssumeCapacity(member_node_index);
}
if (maybe_token_id) |_| _ = try analyzer.expectToken(.operator_right_brace);
@ -2169,7 +2161,7 @@ const Analyzer = struct {
.right = value_associated,
});
try list.append(error_field_node);
list.appendAssumeCapacity(error_field_node);
}
analyzer.consumeToken();

View File

@ -99,9 +99,16 @@ pub fn PinnedArray(comptime T: type) type {
const Array = @This();
pub fn const_slice(array: *const Array) []const T{
return array.pointer[0..array.length];
}
pub fn slice(array: *Array) []T{
return array.pointer[0..array.length];
}
pub fn get_unchecked(array: *Array, index: u32) *T {
const slice = array.pointer[0..array.length];
return &slice[index];
const array_slice = array.slice();
return &array_slice[index];
}
pub fn get(array: *Array, index: Index) *T {
@ -142,6 +149,18 @@ pub fn PinnedArray(comptime T: type) type {
return array.append_with_capacity(item);
}
pub fn append_slice(array: *Array, items: []const T) void {
const count: u32 = @intCast(items.len);
if (((array.length + count) * @sizeOf(T)) & (array.granularity - 1) == 0) {
const length: u64 = array.length;
assert((length + count) * @sizeOf(T) <= pinned_array_max_size);
const ptr: [*]u8 = @ptrCast(array.pointer);
commit(ptr + ((length + count) * @sizeOf(T)), array.granularity) catch unreachable;
}
array.append_slice_with_capacity(items);
}
pub fn append_with_capacity(array: *Array, item: T) *T {
const index = array.length;
assert(index * @sizeOf(T) < pinned_array_max_size);
@ -150,6 +169,14 @@ pub fn PinnedArray(comptime T: type) type {
ptr.* = item;
return ptr;
}
pub fn append_slice_with_capacity(array: *Array, items: []const T) void {
const index = array.length;
const count: u32 = @intCast(items.len);
assert((index + count - 1) * @sizeOf(T) < pinned_array_max_size);
array.length += count;
@memcpy(array.pointer[index..][0..count], items);
}
};
}
@ -711,41 +738,6 @@ fn copy_backwards(comptime T: type, destination: []T, source: []const T) void {
}
}
test {
var page_allocator = PageAllocator{};
const allocator = &page_allocator.allocator;
var foo = UnpinnedArray(u32){};
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
try foo.append(allocator, 1);
}
pub fn equal(a: anytype, b: @TypeOf(a)) bool {
const T = @TypeOf(a);

View File

@ -3,97 +3,97 @@ const assert = std.debug.assert;
const linker = @import("linker.zig");
const library = @import("../library.zig");
const UnpinnedArray = library.UnpinnedArray;
const PinnedArray = library.PinnedArray;
const Compilation = @import("../Compilation.zig");
const write = Compilation.write;
pub fn link(context: *const Compilation.Context, options: linker.Options) !void {
assert(options.backend == .lld);
var argv = UnpinnedArray([]const u8){};
var argv = try PinnedArray([]const u8).init_with_default_granularity();
const driver_program = switch (@import("builtin").os.tag) {
.windows => "lld-link",
.linux => "ld.lld",
.macos => "ld64.lld",
else => @compileError("OS not supported"),
};
try argv.append(context.my_allocator, driver_program);
try argv.append(context.my_allocator, "--error-limit=0");
_ = argv.append(driver_program);
_ = argv.append("--error-limit=0");
// const output_path = out_path orelse "a.out";
try argv.append(context.my_allocator, "-o");
try argv.append(context.my_allocator, options.output_file_path);
_ = argv.append("-o");
_ = argv.append(options.output_file_path);
try argv.append_slice(context.my_allocator, options.extra_arguments);
argv.append_slice(options.extra_arguments);
for (options.objects) |object| {
try argv.append(context.my_allocator, object.path);
_ = argv.append(object.path);
}
const ci = @import("configuration").ci;
switch (@import("builtin").os.tag) {
.macos => {
try argv.append(context.my_allocator, "-dynamic");
try argv.append_slice(context.my_allocator, &.{ "-platform_version", "macos", "13.4.1", "13.3" });
try argv.append(context.my_allocator, "-arch");
try argv.append(context.my_allocator, switch (@import("builtin").cpu.arch) {
_ = argv.append("-dynamic");
argv.append_slice(context.my_allocator, &.{ "-platform_version", "macos", "13.4.1", "13.3" });
_ = argv.append("-arch");
_ = argv.append(switch (@import("builtin").cpu.arch) {
.aarch64 => "arm64",
else => |t| @panic(@tagName(t)),
});
try argv.append_slice(context.my_allocator, &.{ "-syslibroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk" });
argv.append_slice(&.{ "-syslibroot", "/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk" });
if (!library.ends_with_slice(options.output_file_path, ".dylib")) {
try argv.append_slice(context.my_allocator, &.{ "-e", "_main" });
argv.append_slice(&.{ "-e", "_main" });
}
try argv.append(context.my_allocator, "-lSystem");
_ = argv.append("-lSystem");
if (options.link_libcpp) {
try argv.append(context.my_allocator, "-L/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/lib");
try argv.append(context.my_allocator, "-lc++");
_ = argv.append("-L/Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/lib");
_ = argv.append("-lc++");
}
},
.linux => {
if (ci) {
if (options.link_libcpp) {
assert(options.link_libc);
try argv.append(context.my_allocator, "/lib/x86_64-linux-gnu/libstdc++.so.6");
_ = argv.append("/lib/x86_64-linux-gnu/libstdc++.so.6");
}
if (options.link_libc) {
try argv.append(context.my_allocator, "/lib/x86_64-linux-gnu/crt1.o");
try argv.append(context.my_allocator, "/lib/x86_64-linux-gnu/crti.o");
try argv.append_slice(context.my_allocator, &.{ "-L", "/lib/x86_64-linux-gnu" });
try argv.append_slice(context.my_allocator, &.{ "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2" });
try argv.append(context.my_allocator, "--as-needed");
try argv.append(context.my_allocator, "-lm");
try argv.append(context.my_allocator, "-lpthread");
try argv.append(context.my_allocator, "-lc");
try argv.append(context.my_allocator, "-ldl");
try argv.append(context.my_allocator, "-lrt");
try argv.append(context.my_allocator, "-lutil");
try argv.append(context.my_allocator, "/lib/x86_64-linux-gnu/crtn.o");
_ = argv.append("/lib/x86_64-linux-gnu/crt1.o");
_ = argv.append("/lib/x86_64-linux-gnu/crti.o");
argv.append_slice(&.{ "-L", "/lib/x86_64-linux-gnu" });
argv.append_slice(&.{ "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2" });
_ = argv.append("--as-needed");
_ = argv.append("-lm");
_ = argv.append("-lpthread");
_ = argv.append("-lc");
_ = argv.append("-ldl");
_ = argv.append("-lrt");
_ = argv.append("-lutil");
_ = argv.append("/lib/x86_64-linux-gnu/crtn.o");
}
} else {
if (options.link_libcpp) {
assert(options.link_libc);
try argv.append(context.my_allocator, "/usr/lib/libstdc++.so");
_ = argv.append("/usr/lib/libstdc++.so");
}
if (options.link_libc) {
try argv.append(context.my_allocator, "/usr/lib/crt1.o");
try argv.append(context.my_allocator, "/usr/lib/crti.o");
try argv.append_slice(context.my_allocator, &.{ "-L", "/usr/lib" });
try argv.append_slice(context.my_allocator, &.{ "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2" });
try argv.append(context.my_allocator, "--as-needed");
try argv.append(context.my_allocator, "-lm");
try argv.append(context.my_allocator, "-lpthread");
try argv.append(context.my_allocator, "-lc");
try argv.append(context.my_allocator, "-ldl");
try argv.append(context.my_allocator, "-lrt");
try argv.append(context.my_allocator, "-lutil");
try argv.append(context.my_allocator, "/usr/lib/crtn.o");
_ = argv.append("/usr/lib/crt1.o");
_ = argv.append("/usr/lib/crti.o");
argv.append_slice(&.{ "-L", "/usr/lib" });
argv.append_slice(&.{ "-dynamic-linker", "/lib64/ld-linux-x86-64.so.2" });
_ = argv.append("--as-needed");
_ = argv.append("-lm");
_ = argv.append("-lpthread");
_ = argv.append("-lc");
_ = argv.append("-ldl");
_ = argv.append("-lrt");
_ = argv.append("-lutil");
_ = argv.append("/usr/lib/crtn.o");
}
}
},
@ -102,10 +102,10 @@ pub fn link(context: *const Compilation.Context, options: linker.Options) !void
}
for (options.libraries) |lib| {
try argv.append(context.my_allocator, try std.mem.concat(context.allocator, u8, &.{ "-l", lib.path }));
_ = argv.append(try std.mem.concat(context.allocator, u8, &.{ "-l", lib.path }));
}
const argv_zero_terminated = try Compilation.argsCopyZ(context.allocator, argv.slice());
const argv_zero_terminated = try Compilation.argsCopyZ(context.allocator, argv.const_slice());
var stdout_ptr: [*]const u8 = undefined;
var stdout_len: usize = 0;
@ -121,7 +121,7 @@ pub fn link(context: *const Compilation.Context, options: linker.Options) !void
if (!result) {
const stdout = stdout_ptr[0..stdout_len];
const stderr = stderr_ptr[0..stderr_len];
for (argv.slice()) |arg| {
for (argv.const_slice()) |arg| {
try write(.panic, arg);
try write(.panic, " ");
}

View File

@ -9,7 +9,6 @@ const library = @import("library.zig");
const byte_equal = library.byte_equal;
const MyAllocator = library.MyAllocator;
const PageAllocator = library.PageAllocator;
const UnpinnedArray = library.UnpinnedArray;
const env_detecting_libc_paths = "NATIVITY_IS_DETECTING_LIBC_PATHS";
@ -27,26 +26,21 @@ var my_allocator = PageAllocator{};
pub fn main() !void {
var arena_allocator = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = arena_allocator.allocator();
var arg_it = try std.process.ArgIterator.initWithAllocator(allocator);
var args = library.UnpinnedArray([]const u8){};
const arguments: []const []const u8 = try std.process.argsAlloc(allocator);
const context = try Compilation.createContext(allocator, &my_allocator.allocator);
while (arg_it.next()) |arg| {
try args.append(context.my_allocator, arg);
}
const arguments = args.slice();
const debug_args = false;
if (debug_args and @import("builtin").os.tag != .windows) {
assert(arguments.len > 0);
const home_dir = std.posix.getenv("HOME") orelse unreachable;
const timestamp = std.time.milliTimestamp();
var argument_list = UnpinnedArray(u8){};
for (arguments) |arg| {
argument_list.append_slice(context.my_allocator, arg) catch {};
argument_list.append(context.my_allocator, ' ') catch {};
}
argument_list.append(context.my_allocator, '\n') catch {};
std.fs.cwd().writeFile(std.fmt.allocPrint(std.heap.page_allocator, "{s}/dev/nativity/nat/invocation_log_{}", .{ home_dir, timestamp }) catch unreachable, argument_list.slice()) catch {};
}
// const debug_args = false;
// if (debug_args and @import("builtin").os.tag != .windows) {
// assert(arguments.len > 0);
// const home_dir = std.posix.getenv("HOME") orelse unreachable;
// const timestamp = std.time.milliTimestamp();
// var argument_list = UnpinnedArray(u8){};
// for (arguments) |arg| {
// argument_list.append_slice(context.my_allocator, arg) catch {};
// argument_list.append(context.my_allocator, ' ') catch {};
// }
// argument_list.append(context.my_allocator, '\n') catch {};
// std.fs.cwd().writeFile(std.fmt.allocPrint(std.heap.page_allocator, "{s}/dev/nativity/nat/invocation_log_{}", .{ home_dir, timestamp }) catch unreachable, argument_list.slice()) catch {};
// }
if (arguments.len <= 1) {
return error.InvalidInput;