diff --git a/bootstrap/backend/llvm.zig b/bootstrap/backend/llvm.zig index 8784efb..f197892 100644 --- a/bootstrap/backend/llvm.zig +++ b/bootstrap/backend/llvm.zig @@ -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, ¶meter_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(¶meter_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, ¶meter_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, ¶meter_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(¶meter_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; diff --git a/bootstrap/frontend/lexer.zig b/bootstrap/frontend/lexer.zig index 5c96a73..420b967 100644 --- a/bootstrap/frontend/lexer.zig +++ b/bootstrap/frontend/lexer.zig @@ -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; diff --git a/bootstrap/frontend/parser.zig b/bootstrap/frontend/parser.zig index 78562e6..775a94a 100644 --- a/bootstrap/frontend/parser.zig +++ b/bootstrap/frontend/parser.zig @@ -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(); diff --git a/bootstrap/library.zig b/bootstrap/library.zig index 02c048b..070b30c 100644 --- a/bootstrap/library.zig +++ b/bootstrap/library.zig @@ -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); diff --git a/bootstrap/linker/lld.zig b/bootstrap/linker/lld.zig index f437bc8..2b8bf95 100644 --- a/bootstrap/linker/lld.zig +++ b/bootstrap/linker/lld.zig @@ -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, " "); } diff --git a/bootstrap/main.zig b/bootstrap/main.zig index 99e7d35..846e3de 100644 --- a/bootstrap/main.zig +++ b/bootstrap/main.zig @@ -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;