Commit c4fcf0e22a
Changed files (7)
src
src/arch/wasm/CodeGen.zig
@@ -3153,11 +3153,8 @@ fn lowerAnonDeclRef(
return WValue{ .imm32 = 0xaaaaaaaa };
}
- const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
- if (alignment != .none) {
- @panic("TODO how to make this anon decl be aligned?");
- }
- const res = try func.bin_file.lowerAnonDecl(decl_val, func.decl.srcLoc(mod));
+ const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
+ const res = try func.bin_file.lowerAnonDecl(decl_val, decl_align, func.decl.srcLoc(mod));
switch (res) {
.ok => {},
.fail => |em| {
src/link/Coff.zig
@@ -1091,7 +1091,7 @@ pub fn lowerUnnamedConst(self: *Coff, tv: TypedValue, decl_index: Module.Decl.In
const index = unnamed_consts.items.len;
const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
defer gpa.free(sym_name);
- const atom_index = switch (try self.lowerConst(sym_name, tv, self.rdata_section_index.?, decl.srcLoc(mod))) {
+ const atom_index = switch (try self.lowerConst(sym_name, tv, tv.ty.abiAlignment(mod), self.rdata_section_index.?, decl.srcLoc(mod))) {
.ok => |atom_index| atom_index,
.fail => |em| {
decl.analysis = .codegen_failure;
@@ -1109,13 +1109,12 @@ const LowerConstResult = union(enum) {
fail: *Module.ErrorMsg,
};
-fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
+fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, required_alignment: InternPool.Alignment, sect_id: u16, src_loc: Module.SrcLoc) !LowerConstResult {
const gpa = self.base.allocator;
var code_buffer = std.ArrayList(u8).init(gpa);
defer code_buffer.deinit();
- const mod = self.base.options.module.?;
const atom_index = try self.createAtom();
const sym = self.getAtom(atom_index).getSymbolPtr(self);
try self.setSymbolName(sym, name);
@@ -1129,10 +1128,13 @@ fn lowerConst(self: *Coff, name: []const u8, tv: TypedValue, sect_id: u16, src_l
.fail => |em| return .{ .fail = em },
};
- const required_alignment: u32 = @intCast(tv.ty.abiAlignment(mod).toByteUnits(0));
const atom = self.getAtomPtr(atom_index);
atom.size = @as(u32, @intCast(code.len));
- atom.getSymbolPtr(self).value = try self.allocateAtom(atom_index, atom.size, required_alignment);
+ atom.getSymbolPtr(self).value = try self.allocateAtom(
+ atom_index,
+ atom.size,
+ @intCast(required_alignment.toByteUnitsOptional().?),
+ );
errdefer self.freeAtom(atom_index);
log.debug("allocated atom for {s} at 0x{x}", .{ name, atom.getSymbol(self).value });
@@ -1736,7 +1738,7 @@ pub fn getDeclVAddr(self: *Coff, decl_index: Module.Decl.Index, reloc_info: link
return 0;
}
-pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
+pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
// This is basically the same as lowerUnnamedConst.
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
@@ -1747,15 +1749,21 @@ pub fn lowerAnonDecl(self: *Coff, decl_val: InternPool.Index, src_loc: Module.Sr
// to put it in some location.
// ...
const gpa = self.base.allocator;
+ const mod = self.base.options.module.?;
+ const ty = mod.intern_pool.typeOf(decl_val).toType();
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
- if (!gop.found_existing) {
- const mod = self.base.options.module.?;
- const ty = mod.intern_pool.typeOf(decl_val).toType();
+ const required_alignment = switch (decl_align) {
+ .none => ty.abiAlignment(mod),
+ else => decl_align,
+ };
+ if (!gop.found_existing or
+ !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).value))
+ {
const val = decl_val.toValue();
const tv = TypedValue{ .ty = ty, .val = val };
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
defer gpa.free(name);
- const res = self.lowerConst(name, tv, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
+ const res = self.lowerConst(name, tv, required_alignment, self.rdata_section_index.?, src_loc) catch |err| switch (err) {
else => {
// TODO improve error message
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
src/link/Elf.zig
@@ -473,7 +473,7 @@ pub fn getDeclVAddr(self: *Elf, decl_index: Module.Decl.Index, reloc_info: link.
return vaddr;
}
-pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
+pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
// This is basically the same as lowerUnnamedConst.
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
@@ -484,15 +484,21 @@ pub fn lowerAnonDecl(self: *Elf, decl_val: InternPool.Index, src_loc: Module.Src
// to put it in some location.
// ...
const gpa = self.base.allocator;
+ const mod = self.base.options.module.?;
+ const ty = mod.intern_pool.typeOf(decl_val).toType();
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
- if (!gop.found_existing) {
- const mod = self.base.options.module.?;
- const ty = mod.intern_pool.typeOf(decl_val).toType();
+ const required_alignment = switch (decl_align) {
+ .none => ty.abiAlignment(mod),
+ else => decl_align,
+ };
+ if (!gop.found_existing or
+ required_alignment.order(self.symbol(gop.value_ptr.*).atom(self).?.alignment).compare(.gt))
+ {
const val = decl_val.toValue();
const tv = TypedValue{ .ty = ty, .val = val };
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
defer gpa.free(name);
- const res = self.lowerConst(name, tv, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
+ const res = self.lowerConst(name, tv, required_alignment, self.zig_rodata_section_index.?, src_loc) catch |err| switch (err) {
else => {
// TODO improve error message
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
@@ -3479,7 +3485,7 @@ pub fn lowerUnnamedConst(self: *Elf, typed_value: TypedValue, decl_index: Module
const index = unnamed_consts.items.len;
const name = try std.fmt.allocPrint(gpa, "__unnamed_{s}_{d}", .{ decl_name, index });
defer gpa.free(name);
- const sym_index = switch (try self.lowerConst(name, typed_value, self.zig_rodata_section_index.?, decl.srcLoc(mod))) {
+ const sym_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.zig_rodata_section_index.?, decl.srcLoc(mod))) {
.ok => |sym_index| sym_index,
.fail => |em| {
decl.analysis = .codegen_failure;
@@ -3502,6 +3508,7 @@ fn lowerConst(
self: *Elf,
name: []const u8,
tv: TypedValue,
+ required_alignment: InternPool.Alignment,
output_section_index: u16,
src_loc: Module.SrcLoc,
) !LowerConstResult {
@@ -3510,7 +3517,6 @@ fn lowerConst(
var code_buffer = std.ArrayList(u8).init(gpa);
defer code_buffer.deinit();
- const mod = self.base.options.module.?;
const zig_module = self.file(self.zig_module_index.?).?.zig_module;
const sym_index = try zig_module.addAtom(self);
@@ -3524,7 +3530,6 @@ fn lowerConst(
.fail => |em| return .{ .fail = em },
};
- const required_alignment = tv.ty.abiAlignment(mod);
const phdr_index = self.phdr_to_shdr_table.get(output_section_index).?;
const local_sym = self.symbol(sym_index);
const name_str_index = try self.strtab.insert(gpa, name);
src/link/MachO.zig
@@ -2196,7 +2196,7 @@ pub fn lowerUnnamedConst(self: *MachO, typed_value: TypedValue, decl_index: Modu
const index = unnamed_consts.items.len;
const name = try std.fmt.allocPrint(gpa, "___unnamed_{s}_{d}", .{ decl_name, index });
defer gpa.free(name);
- const atom_index = switch (try self.lowerConst(name, typed_value, self.data_const_section_index.?, decl.srcLoc(mod))) {
+ const atom_index = switch (try self.lowerConst(name, typed_value, typed_value.ty.abiAlignment(mod), self.data_const_section_index.?, decl.srcLoc(mod))) {
.ok => |atom_index| atom_index,
.fail => |em| {
decl.analysis = .codegen_failure;
@@ -2219,6 +2219,7 @@ fn lowerConst(
self: *MachO,
name: []const u8,
tv: TypedValue,
+ required_alignment: InternPool.Alignment,
sect_id: u8,
src_loc: Module.SrcLoc,
) !LowerConstResult {
@@ -2227,8 +2228,6 @@ fn lowerConst(
var code_buffer = std.ArrayList(u8).init(gpa);
defer code_buffer.deinit();
- const mod = self.base.options.module.?;
-
log.debug("allocating symbol indexes for {s}", .{name});
const sym_index = try self.allocateSymbol();
@@ -2243,7 +2242,6 @@ fn lowerConst(
.fail => |em| return .{ .fail = em },
};
- const required_alignment = tv.ty.abiAlignment(mod);
const atom = self.getAtomPtr(atom_index);
atom.size = code.len;
// TODO: work out logic for disambiguating functions from function pointers
@@ -2868,7 +2866,7 @@ pub fn getDeclVAddr(self: *MachO, decl_index: Module.Decl.Index, reloc_info: Fil
return 0;
}
-pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
+pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !codegen.Result {
// This is basically the same as lowerUnnamedConst.
// example:
// const ty = mod.intern_pool.typeOf(decl_val).toType();
@@ -2879,15 +2877,21 @@ pub fn lowerAnonDecl(self: *MachO, decl_val: InternPool.Index, src_loc: Module.S
// to put it in some location.
// ...
const gpa = self.base.allocator;
+ const mod = self.base.options.module.?;
+ const ty = mod.intern_pool.typeOf(decl_val).toType();
const gop = try self.anon_decls.getOrPut(gpa, decl_val);
- if (!gop.found_existing) {
- const mod = self.base.options.module.?;
- const ty = mod.intern_pool.typeOf(decl_val).toType();
+ const required_alignment = switch (decl_align) {
+ .none => ty.abiAlignment(mod),
+ else => decl_align,
+ };
+ if (!gop.found_existing or
+ !required_alignment.check(self.getAtom(gop.value_ptr.*).getSymbol(self).n_value))
+ {
const val = decl_val.toValue();
const tv = TypedValue{ .ty = ty, .val = val };
const name = try std.fmt.allocPrint(gpa, "__anon_{d}", .{@intFromEnum(decl_val)});
defer gpa.free(name);
- const res = self.lowerConst(name, tv, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
+ const res = self.lowerConst(name, tv, required_alignment, self.data_const_section_index.?, src_loc) catch |err| switch (err) {
else => {
// TODO improve error message
const em = try Module.ErrorMsg.create(gpa, src_loc, "lowerAnonDecl failed with error: {s}", .{
src/link/Wasm.zig
@@ -1702,25 +1702,30 @@ pub fn getDeclVAddr(
return target_symbol_index;
}
-pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !codegen.Result {
+pub fn lowerAnonDecl(wasm: *Wasm, decl_val: InternPool.Index, decl_align: Alignment, src_loc: Module.SrcLoc) !codegen.Result {
const gop = try wasm.anon_decls.getOrPut(wasm.base.allocator, decl_val);
- if (gop.found_existing) {
- return .ok;
- }
+ if (!gop.found_existing) {
+ const mod = wasm.base.options.module.?;
+ const ty = mod.intern_pool.typeOf(decl_val).toType();
+ const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
+ const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
+ defer wasm.base.allocator.free(name);
- const mod = wasm.base.options.module.?;
- const ty = mod.intern_pool.typeOf(decl_val).toType();
- const tv: TypedValue = .{ .ty = ty, .val = decl_val.toValue() };
- const name = try std.fmt.allocPrintZ(wasm.base.allocator, "__anon_{d}", .{@intFromEnum(decl_val)});
- defer wasm.base.allocator.free(name);
+ switch (try wasm.lowerConst(name, tv, src_loc)) {
+ .ok => |atom_index| gop.value_ptr.* = atom_index,
+ .fail => |em| return .{ .fail = em },
+ }
+ }
- switch (try wasm.lowerConst(name, tv, src_loc)) {
- .ok => |atom_index| {
- gop.value_ptr.* = atom_index;
- return .ok;
+ const atom = wasm.getAtomPtr(gop.value_ptr.*);
+ atom.alignment = switch (atom.alignment) {
+ .none => decl_align,
+ else => switch (decl_align) {
+ .none => atom.alignment,
+ else => atom.alignment.maxStrict(decl_align),
},
- .fail => |em| return .{ .fail = em },
- }
+ };
+ return .ok;
}
pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
src/codegen.zig
@@ -731,16 +731,13 @@ fn lowerAnonDeclRef(
return Result.ok;
}
- const res = try bin_file.lowerAnonDecl(decl_val, src_loc);
+ const decl_align = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
+ const res = try bin_file.lowerAnonDecl(decl_val, decl_align, src_loc);
switch (res) {
.ok => {},
.fail => |em| return .{ .fail = em },
}
- const alignment = mod.intern_pool.indexToKey(anon_decl.orig_ty).ptr_type.flags.alignment;
- if (alignment != .none) {
- @panic("TODO how to make this anon decl be aligned?");
- }
const vaddr = try bin_file.getAnonDeclVAddr(decl_val, .{
.parent_atom_index = reloc_info.parent_atom_index,
.offset = code.items.len,
src/link.zig
@@ -940,15 +940,15 @@ pub const File = struct {
pub const LowerResult = @import("codegen.zig").Result;
- pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, src_loc: Module.SrcLoc) !LowerResult {
+ pub fn lowerAnonDecl(base: *File, decl_val: InternPool.Index, decl_align: InternPool.Alignment, src_loc: Module.SrcLoc) !LowerResult {
if (build_options.only_c) unreachable;
switch (base.tag) {
- .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, src_loc),
- .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, src_loc),
- .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, src_loc),
+ .coff => return @fieldParentPtr(Coff, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
+ .elf => return @fieldParentPtr(Elf, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
+ .macho => return @fieldParentPtr(MachO, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
.plan9 => return @fieldParentPtr(Plan9, "base", base).lowerAnonDecl(decl_val, src_loc),
.c => unreachable,
- .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, src_loc),
+ .wasm => return @fieldParentPtr(Wasm, "base", base).lowerAnonDecl(decl_val, decl_align, src_loc),
.spirv => unreachable,
.nvptx => unreachable,
}