Commit 943dac3e85
Changed files (18)
src
arch
link
src/arch/wasm/CodeGen.zig
@@ -1,7 +1,6 @@
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;
-const ArrayList = std.ArrayList;
const assert = std.debug.assert;
const testing = std.testing;
const leb = std.leb;
@@ -631,7 +630,7 @@ blocks: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, struct {
/// Maps `loop` instructions to their label. `br` to here repeats the loop.
loops: std.AutoHashMapUnmanaged(Air.Inst.Index, u32) = .empty,
/// `bytes` contains the wasm bytecode belonging to the 'code' section.
-code: *ArrayList(u8),
+code: *std.ArrayListUnmanaged(u8),
/// The index the next local generated will have
/// NOTE: arguments share the index with locals therefore the first variable
/// will have the index that comes after the last argument's index
@@ -639,8 +638,6 @@ local_index: u32 = 0,
/// The index of the current argument.
/// Used to track which argument is being referenced in `airArg`.
arg_index: u32 = 0,
-/// If codegen fails, an error messages will be allocated and saved in `err_msg`
-err_msg: *Zcu.ErrorMsg,
/// List of all locals' types generated throughout this declaration
/// used to emit locals count at start of 'code' section.
locals: std.ArrayListUnmanaged(u8),
@@ -732,10 +729,9 @@ pub fn deinit(func: *CodeGen) void {
func.* = undefined;
}
-/// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig
-fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError {
- func.err_msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args);
- return error.CodegenFail;
+fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } {
+ const msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args);
+ return func.pt.zcu.codegenFailMsg(func.owner_nav, msg);
}
/// Resolves the `WValue` for the given instruction `inst`
@@ -1173,9 +1169,9 @@ pub fn generate(
func_index: InternPool.Index,
air: Air,
liveness: Liveness,
- code: *std.ArrayList(u8),
+ code: *std.ArrayListUnmanaged(u8),
debug_output: link.File.DebugInfoOutput,
-) codegen.CodeGenError!codegen.Result {
+) codegen.CodeGenError!void {
const zcu = pt.zcu;
const gpa = zcu.gpa;
const func = zcu.funcInfo(func_index);
@@ -1189,7 +1185,6 @@ pub fn generate(
.code = code,
.owner_nav = func.owner_nav,
.src_loc = src_loc,
- .err_msg = undefined,
.locals = .{},
.target = target,
.bin_file = bin_file.cast(.wasm).?,
@@ -1199,11 +1194,9 @@ pub fn generate(
defer code_gen.deinit();
genFunc(&code_gen) catch |err| switch (err) {
- error.CodegenFail => return codegen.Result{ .fail = code_gen.err_msg },
- else => |e| return e,
+ error.CodegenFail => return error.CodegenFail,
+ else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}),
};
-
- return codegen.Result.ok;
}
fn genFunc(func: *CodeGen) InnerError!void {
src/arch/wasm/Mir.zig
@@ -80,15 +80,15 @@ pub const Inst = struct {
///
/// Uses `nop`
@"return" = 0x0F,
- /// Calls a function using `nav_index`.
- call_nav,
- /// Calls a function using `func_index`.
- call_func,
/// Calls a function pointer by its function signature
/// and index into the function table.
///
/// Uses `label`
call_indirect = 0x11,
+ /// Calls a function using `nav_index`.
+ call_nav,
+ /// Calls a function using `func_index`.
+ call_func,
/// Calls a function by its index.
///
/// The function is the auto-generated tag name function for the type
src/codegen/c.zig
@@ -3052,12 +3052,12 @@ pub fn genDeclValue(
try w.writeAll(";\n");
}
-pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void {
+pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void {
const zcu = dg.pt.zcu;
const ip = &zcu.intern_pool;
const fwd = dg.fwdDeclWriter();
- const main_name = zcu.all_exports.items[export_indices[0]].opts.name;
+ const main_name = export_indices[0].ptr(zcu).opts.name;
try fwd.writeAll("#define ");
switch (exported) {
.nav => |nav| try dg.renderNavName(fwd, nav),
@@ -3069,7 +3069,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
const exported_val = exported.getValue(zcu);
if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| {
- const @"export" = &zcu.all_exports.items[export_index];
+ const @"export" = export_index.ptr(zcu);
try fwd.writeAll("zig_extern ");
if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn ");
try dg.renderFunctionSignature(
@@ -3091,7 +3091,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const
else => true,
};
for (export_indices) |export_index| {
- const @"export" = &zcu.all_exports.items[export_index];
+ const @"export" = export_index.ptr(zcu);
try fwd.writeAll("zig_extern ");
if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage ");
const extern_name = @"export".opts.name.toSlice(ip);
src/codegen/llvm.zig
@@ -1810,7 +1810,7 @@ pub const Object = struct {
self: *Object,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) link.File.UpdateExportsError!void {
assert(std.meta.eql(pt, self.pt));
const zcu = pt.zcu;
src/link/Elf/ZigObject.zig
@@ -1745,7 +1745,7 @@ pub fn updateExports(
elf_file: *Elf,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) link.File.UpdateExportsError!void {
const tracy = trace(@src());
defer tracy.end();
src/link/MachO/ZigObject.zig
@@ -1246,7 +1246,7 @@ pub fn updateExports(
macho_file: *MachO,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) link.File.UpdateExportsError!void {
const tracy = trace(@src());
defer tracy.end();
src/link/Wasm/Flush.zig
@@ -137,13 +137,12 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) anyerror!void {
// Merge and order the data segments. Depends on garbage collection so that
// unused segments can be omitted.
- try f.ensureUnusedCapacity(gpa, wasm.object_data_segments.items.len);
+ try f.data_segments.ensureUnusedCapacity(gpa, wasm.object_data_segments.items.len);
for (wasm.object_data_segments.items, 0..) |*ds, i| {
if (!ds.flags.alive) continue;
+ const data_segment_index: Wasm.DataSegment.Index = @enumFromInt(i);
any_passive_inits = any_passive_inits or ds.flags.is_passive or (import_memory and !isBss(wasm, ds.name));
- f.data_segments.putAssumeCapacityNoClobber(@intCast(i), .{
- .offset = undefined,
- });
+ f.data_segments.putAssumeCapacityNoClobber(data_segment_index, .{ .offset = undefined });
}
try wasm.functions.ensureUnusedCapacity(gpa, 3);
@@ -1082,8 +1081,8 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8)
// try writeCustomSectionHeader(binary_bytes.items, header_offset, size);
//}
-fn isBss(wasm: *Wasm, name: String) bool {
- const s = name.slice(wasm);
+fn isBss(wasm: *Wasm, optional_name: Wasm.OptionalString) bool {
+ const s = optional_name.slice(wasm) orelse return false;
return mem.eql(u8, s, ".bss") or mem.startsWith(u8, s, ".bss.");
}
src/link/C.zig
@@ -840,7 +840,7 @@ pub fn updateExports(
self: *C,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) !void {
const zcu = pt.zcu;
const gpa = zcu.gpa;
src/link/Elf.zig
@@ -2393,7 +2393,7 @@ pub fn updateExports(
self: *Elf,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) link.File.UpdateExportsError!void {
if (build_options.skip_non_native and builtin.object_format != .elf) {
@panic("Attempted to compile for object format that was disabled by build configuration");
src/link/MachO.zig
@@ -3056,7 +3056,7 @@ pub fn updateExports(
self: *MachO,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) link.File.UpdateExportsError!void {
if (build_options.skip_non_native and builtin.object_format != .macho) {
@panic("Attempted to compile for object format that was disabled by build configuration");
src/link/NvPtx.zig
@@ -100,7 +100,7 @@ pub fn updateExports(
self: *NvPtx,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) !void {
if (build_options.skip_non_native and builtin.object_format != .nvptx)
@panic("Attempted to compile for object format that was disabled by build configuration");
src/link/Plan9.zig
@@ -60,7 +60,7 @@ fn_nav_table: std.AutoArrayHashMapUnmanaged(
data_nav_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u8) = .empty,
/// When `updateExports` is called, we store the export indices here, to be used
/// during flush.
-nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u32) = .empty,
+nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []Zcu.Export.Index) = .empty,
lazy_syms: LazySymbolTable = .{},
@@ -1007,7 +1007,7 @@ pub fn updateExports(
self: *Plan9,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) !void {
const gpa = self.base.comp.gpa;
switch (exported) {
@@ -1018,7 +1018,7 @@ pub fn updateExports(
gpa.free(kv.value);
}
try self.nav_exports.ensureUnusedCapacity(gpa, 1);
- const duped_indices = try gpa.dupe(u32, export_indices);
+ const duped_indices = try gpa.dupe(Zcu.Export.Index, export_indices);
self.nav_exports.putAssumeCapacityNoClobber(nav, duped_indices);
},
}
src/link/SpirV.zig
@@ -155,7 +155,7 @@ pub fn updateExports(
self: *SpirV,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) !void {
const zcu = pt.zcu;
const ip = &zcu.intern_pool;
@@ -190,7 +190,7 @@ pub fn updateExports(
};
for (export_indices) |export_idx| {
- const exp = zcu.all_exports.items[export_idx];
+ const exp = export_idx.ptr(zcu);
try self.object.spv.declareEntryPoint(
spv_decl_index,
exp.opts.name.toSlice(ip),
src/link/Wasm.zig
@@ -56,6 +56,10 @@ base: link.File,
/// string_table entries for them. Alternately those sites could be moved to
/// use a different byte array for this purpose.
string_bytes: std.ArrayListUnmanaged(u8),
+/// Sometimes we have logic that wants to borrow string bytes to store
+/// arbitrary things in there. In this case it is not allowed to intern new
+/// strings during this time. This safety lock is used to detect misuses.
+string_bytes_lock: std.debug.SafetyLock = .{},
/// Omitted when serializing linker state.
string_table: String.Table,
/// Symbol name of the entry function to export
@@ -202,6 +206,10 @@ any_exports_updated: bool = true,
/// Index into `objects`.
pub const ObjectIndex = enum(u32) {
_,
+
+ pub fn ptr(index: ObjectIndex, wasm: *const Wasm) *Object {
+ return &wasm.objects.items[@intFromEnum(index)];
+ }
};
/// Index into `functions`.
@@ -269,12 +277,26 @@ pub const SourceLocation = enum(u32) {
};
}
+ pub fn unpack(sl: SourceLocation, wasm: *const Wasm) Unpacked {
+ return switch (sl) {
+ .zig_object_nofile => .zig_object_nofile,
+ .none => .none,
+ _ => {
+ const i = @intFromEnum(sl);
+ if (i < wasm.objects.items.len) return .{ .object_index = @enumFromInt(i) };
+ const sl_index = i - wasm.objects.items.len;
+ _ = sl_index;
+ @panic("TODO");
+ },
+ };
+ }
+
pub fn addError(sl: SourceLocation, wasm: *Wasm, comptime f: []const u8, args: anytype) void {
const diags = &wasm.base.comp.link_diags;
switch (sl.unpack(wasm)) {
.none => unreachable,
.zig_object_nofile => diags.addError("zig compilation unit: " ++ f, args),
- .object_index => |i| diags.addError("{}: " ++ f, .{wasm.objects.items[i].path} ++ args),
+ .object_index => |i| diags.addError("{}: " ++ f, .{i.ptr(wasm).path} ++ args),
.source_location_index => @panic("TODO"),
}
}
@@ -520,6 +542,10 @@ pub const FunctionImport = extern struct {
/// Index into `object_function_imports`.
pub const Index = enum(u32) {
_,
+
+ pub fn ptr(index: FunctionImport.Index, wasm: *const Wasm) *FunctionImport {
+ return &wasm.object_function_imports.items[@intFromEnum(index)];
+ }
};
};
@@ -543,7 +569,8 @@ pub const GlobalImport = extern struct {
source_location: SourceLocation,
resolution: Resolution,
- /// Represents a synthetic global, or a global from an object.
+ /// Represents a synthetic global, a global from an object, or a global
+ /// from the Zcu.
pub const Resolution = enum(u32) {
unresolved,
__heap_base,
@@ -556,6 +583,68 @@ pub const GlobalImport = extern struct {
// Next, index into `object_globals`.
// Next, index into `navs`.
_,
+
+ const first_object_global = @intFromEnum(Resolution.__zig_error_name_table) + 1;
+
+ pub const Unpacked = union(enum) {
+ unresolved,
+ __heap_base,
+ __heap_end,
+ __stack_pointer,
+ __tls_align,
+ __tls_base,
+ __tls_size,
+ __zig_error_name_table,
+ object_global: ObjectGlobalIndex,
+ nav: Nav.Index,
+ };
+
+ pub fn unpack(r: Resolution, wasm: *const Wasm) Unpacked {
+ return switch (r) {
+ .unresolved => .unresolved,
+ .__wasm_apply_global_tls_relocs => .__wasm_apply_global_tls_relocs,
+ .__wasm_call_ctors => .__wasm_call_ctors,
+ .__wasm_init_memory => .__wasm_init_memory,
+ .__wasm_init_tls => .__wasm_init_tls,
+ .__zig_error_names => .__zig_error_names,
+ _ => {
+ const i: u32 = @intFromEnum(r);
+ const object_global_index = i - first_object_global;
+ if (object_global_index < wasm.object_globals.items.len)
+ return .{ .object_global = @enumFromInt(object_global_index) };
+ const nav_index = object_global_index - wasm.object_globals.items.len;
+ return .{ .nav = @enumFromInt(nav_index) };
+ },
+ };
+ }
+
+ pub fn pack(wasm: *const Wasm, unpacked: Unpacked) Resolution {
+ return switch (unpacked) {
+ .unresolved => .unresolved,
+ .__heap_base => .__heap_base,
+ .__heap_end => .__heap_end,
+ .__stack_pointer => .__stack_pointer,
+ .__tls_align => .__tls_align,
+ .__tls_base => .__tls_base,
+ .__tls_size => .__tls_size,
+ .__zig_error_name_table => .__zig_error_name_table,
+ .object_global => |i| @enumFromInt(first_object_global + @intFromEnum(i)),
+ .nav => |i| @enumFromInt(first_object_global + wasm.object_globals.items.len + @intFromEnum(i)),
+ };
+ }
+
+ pub fn fromIpNav(wasm: *const Wasm, ip_nav: InternPool.Nav.Index) Resolution {
+ return pack(wasm, .{ .nav = @enumFromInt(wasm.navs.getIndex(ip_nav).?) });
+ }
+ };
+
+ /// Index into `object_global_imports`.
+ pub const Index = enum(u32) {
+ _,
+
+ pub fn ptr(index: Index, wasm: *const Wasm) *GlobalImport {
+ return &wasm.object_global_imports.items[@intFromEnum(index)];
+ }
};
};
@@ -634,20 +723,6 @@ pub const ObjectSectionIndex = enum(u32) {
_,
};
-/// Index into `object_function_imports`.
-pub const ObjectFunctionImportIndex = enum(u32) {
- _,
-
- pub fn ptr(index: ObjectFunctionImportIndex, wasm: *const Wasm) *FunctionImport {
- return &wasm.object_function_imports.items[@intFromEnum(index)];
- }
-};
-
-/// Index into `object_global_imports`.
-pub const ObjectGlobalImportIndex = enum(u32) {
- _,
-};
-
/// Index into `object_table_imports`.
pub const ObjectTableImportIndex = enum(u32) {
_,
@@ -861,11 +936,35 @@ pub const ValtypeList = enum(u32) {
}
};
+/// Index into `imports`.
+pub const ZcuImportIndex = enum(u32) {
+ _,
+};
+
/// 0. Index into `object_function_imports`.
/// 1. Index into `imports`.
pub const FunctionImportId = enum(u32) {
_,
+ pub const Unpacked = union(enum) {
+ object_function_import: FunctionImport.Index,
+ zcu_import: ZcuImportIndex,
+ };
+
+ pub fn pack(unpacked: Unpacked, wasm: *const Wasm) FunctionImportId {
+ return switch (unpacked) {
+ .object_function_import => |i| @enumFromInt(@intFromEnum(i)),
+ .zcu_import => |i| @enumFromInt(@intFromEnum(i) - wasm.object_function_imports.entries.len),
+ };
+ }
+
+ pub fn unpack(id: FunctionImportId, wasm: *const Wasm) Unpacked {
+ const i = @intFromEnum(id);
+ if (i < wasm.object_function_imports.entries.len) return .{ .object_function_import = @enumFromInt(i) };
+ const zcu_import_i = i - wasm.object_function_imports.entries.len;
+ return .{ .zcu_import = @enumFromInt(zcu_import_i) };
+ }
+
/// This function is allowed O(N) lookup because it is only called during
/// diagnostic generation.
pub fn sourceLocation(id: FunctionImportId, wasm: *const Wasm) SourceLocation {
@@ -873,10 +972,10 @@ pub const FunctionImportId = enum(u32) {
.object_function_import => |obj_func_index| {
// TODO binary search
for (wasm.objects.items, 0..) |o, i| {
- if (o.function_imports.off <= obj_func_index and
- o.function_imports.off + o.function_imports.len > obj_func_index)
+ if (o.function_imports.off <= @intFromEnum(obj_func_index) and
+ o.function_imports.off + o.function_imports.len > @intFromEnum(obj_func_index))
{
- return .pack(wasm, .{ .object_index = @enumFromInt(i) });
+ return .pack(.{ .object_index = @enumFromInt(i) }, wasm);
}
} else unreachable;
},
@@ -890,17 +989,36 @@ pub const FunctionImportId = enum(u32) {
pub const GlobalImportId = enum(u32) {
_,
+ pub const Unpacked = union(enum) {
+ object_global_import: GlobalImport.Index,
+ zcu_import: ZcuImportIndex,
+ };
+
+ pub fn pack(unpacked: Unpacked, wasm: *const Wasm) GlobalImportId {
+ return switch (unpacked) {
+ .object_global_import => |i| @enumFromInt(@intFromEnum(i)),
+ .zcu_import => |i| @enumFromInt(@intFromEnum(i) - wasm.object_global_imports.entries.len),
+ };
+ }
+
+ pub fn unpack(id: GlobalImportId, wasm: *const Wasm) Unpacked {
+ const i = @intFromEnum(id);
+ if (i < wasm.object_global_imports.entries.len) return .{ .object_global_import = @enumFromInt(i) };
+ const zcu_import_i = i - wasm.object_global_imports.entries.len;
+ return .{ .zcu_import = @enumFromInt(zcu_import_i) };
+ }
+
/// This function is allowed O(N) lookup because it is only called during
/// diagnostic generation.
pub fn sourceLocation(id: GlobalImportId, wasm: *const Wasm) SourceLocation {
switch (id.unpack(wasm)) {
- .object_global_import => |obj_func_index| {
+ .object_global_import => |obj_global_index| {
// TODO binary search
for (wasm.objects.items, 0..) |o, i| {
- if (o.global_imports.off <= obj_func_index and
- o.global_imports.off + o.global_imports.len > obj_func_index)
+ if (o.global_imports.off <= @intFromEnum(obj_global_index) and
+ o.global_imports.off + o.global_imports.len > @intFromEnum(obj_global_index))
{
- return .pack(wasm, .{ .object_index = @enumFromInt(i) });
+ return .pack(.{ .object_index = @enumFromInt(i) }, wasm);
}
} else unreachable;
},
@@ -1330,23 +1448,13 @@ pub fn deinit(wasm: *Wasm) void {
wasm.object_memories.deinit(gpa);
wasm.object_data_segments.deinit(gpa);
- wasm.object_relocatable_codes.deinit(gpa);
wasm.object_custom_segments.deinit(gpa);
- wasm.object_symbols.deinit(gpa);
- wasm.object_named_segments.deinit(gpa);
wasm.object_init_funcs.deinit(gpa);
wasm.object_comdats.deinit(gpa);
- wasm.object_relocations.deinit(gpa);
wasm.object_relocations_table.deinit(gpa);
wasm.object_comdat_symbols.deinit(gpa);
wasm.objects.deinit(gpa);
- wasm.synthetic_symbols.deinit(gpa);
- wasm.undefs.deinit(gpa);
- wasm.discarded.deinit(gpa);
- wasm.segments.deinit(gpa);
- wasm.segment_info.deinit(gpa);
-
wasm.func_types.deinit(gpa);
wasm.function_exports.deinit(gpa);
wasm.function_imports.deinit(gpa);
@@ -1354,8 +1462,6 @@ pub fn deinit(wasm: *Wasm) void {
wasm.globals.deinit(gpa);
wasm.global_imports.deinit(gpa);
wasm.table_imports.deinit(gpa);
- wasm.output_globals.deinit(gpa);
- wasm.exports.deinit(gpa);
wasm.string_bytes.deinit(gpa);
wasm.string_table.deinit(gpa);
@@ -1374,12 +1480,11 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index,
const nav_index = func.owner_nav;
const code_start: u32 = @intCast(wasm.string_bytes.items.len);
- const relocs_start: u32 = @intCast(wasm.relocations.items.len);
+ const relocs_start: u32 = @intCast(wasm.relocations.len);
wasm.string_bytes_lock.lock();
- const wasm_codegen = @import("../../arch/wasm/CodeGen.zig");
dev.check(.wasm_backend);
- const result = try wasm_codegen.generate(
+ try CodeGen.generate(
&wasm.base,
pt,
zcu.navSrcLoc(nav_index),
@@ -1391,18 +1496,12 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index,
);
const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start);
- const relocs_len: u32 = @intCast(wasm.relocations.items.len - relocs_start);
+ const relocs_len: u32 = @intCast(wasm.relocations.len - relocs_start);
wasm.string_bytes_lock.unlock();
- const code: Nav.Code = switch (result) {
- .ok => .{
- .off = code_start,
- .len = code_len,
- },
- .fail => |em| {
- try pt.zcu.failed_codegen.put(gpa, nav_index, em);
- return;
- },
+ const code: Nav.Code = .{
+ .off = code_start,
+ .len = code_len,
};
const gop = try wasm.navs.getOrPut(gpa, nav_index);
@@ -1445,24 +1544,22 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
if (!nav_init.typeOf(zcu).hasRuntimeBits(zcu)) {
_ = wasm.imports.swapRemove(nav_index);
- if (wasm.navs.swapRemove(nav_index)) |old| {
- _ = old;
+ if (wasm.navs.swapRemove(nav_index)) {
@panic("TODO reclaim resources");
}
return;
}
if (is_extern) {
- try wasm.imports.put(nav_index, {});
- if (wasm.navs.swapRemove(nav_index)) |old| {
- _ = old;
+ try wasm.imports.put(gpa, nav_index, {});
+ if (wasm.navs.swapRemove(nav_index)) {
@panic("TODO reclaim resources");
}
return;
}
const code_start: u32 = @intCast(wasm.string_bytes.items.len);
- const relocs_start: u32 = @intCast(wasm.relocations.items.len);
+ const relocs_start: u32 = @intCast(wasm.relocations.len);
wasm.string_bytes_lock.lock();
const res = try codegen.generateSymbol(
@@ -1475,7 +1572,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index
);
const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start);
- const relocs_len: u32 = @intCast(wasm.relocations.items.len - relocs_start);
+ const relocs_len: u32 = @intCast(wasm.relocations.len - relocs_start);
wasm.string_bytes_lock.unlock();
const code: Nav.Code = switch (res) {
@@ -1531,7 +1628,7 @@ pub fn updateExports(
wasm: *Wasm,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) !void {
if (build_options.skip_non_native and builtin.object_format != .wasm) {
@panic("Attempted to compile for object format that was disabled by build configuration");
@@ -1668,7 +1765,7 @@ fn markFunction(
wasm: *Wasm,
name: String,
import: *FunctionImport,
- func_index: ObjectFunctionImportIndex,
+ func_index: FunctionImport.Index,
) error{OutOfMemory}!void {
if (import.flags.alive) return;
import.flags.alive = true;
@@ -1712,7 +1809,7 @@ fn markGlobal(
wasm: *Wasm,
name: String,
import: *GlobalImport,
- global_index: ObjectGlobalImportIndex,
+ global_index: GlobalImport.Index,
) !void {
if (import.flags.alive) return;
import.flags.alive = true;
src/Zcu/PerThread.zig
@@ -2815,8 +2815,8 @@ pub fn processExports(pt: Zcu.PerThread) !void {
const gpa = zcu.gpa;
// First, construct a mapping of every exported value and Nav to the indices of all its different exports.
- var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .empty;
- var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .empty;
+ var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(Zcu.Export.Index)) = .empty;
+ var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(Zcu.Export.Index)) = .empty;
defer {
for (nav_exports.values()) |*exports| {
exports.deinit(gpa);
@@ -2835,7 +2835,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count());
for (zcu.single_exports.values()) |export_idx| {
- const exp = zcu.all_exports.items[export_idx];
+ const exp = export_idx.ptr(zcu);
const value_ptr, const found_existing = switch (exp.exported) {
.nav => |nav| gop: {
const gop = try nav_exports.getOrPut(gpa, nav);
@@ -2863,7 +2863,7 @@ pub fn processExports(pt: Zcu.PerThread) !void {
},
};
if (!found_existing) value_ptr.* = .{};
- try value_ptr.append(gpa, @intCast(export_idx));
+ try value_ptr.append(gpa, @enumFromInt(export_idx));
}
}
@@ -2882,20 +2882,20 @@ pub fn processExports(pt: Zcu.PerThread) !void {
}
}
-const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32);
+const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Zcu.Export.Index);
fn processExportsInner(
pt: Zcu.PerThread,
symbol_exports: *SymbolExports,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) error{OutOfMemory}!void {
const zcu = pt.zcu;
const gpa = zcu.gpa;
const ip = &zcu.intern_pool;
for (export_indices) |export_idx| {
- const new_export = &zcu.all_exports.items[export_idx];
+ const new_export = export_idx.ptr(zcu);
const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name);
if (gop.found_existing) {
new_export.status = .failed_retryable;
@@ -2904,7 +2904,7 @@ fn processExportsInner(
new_export.opts.name.fmt(ip),
});
errdefer msg.destroy(gpa);
- const other_export = zcu.all_exports.items[gop.value_ptr.*];
+ const other_export = gop.value_ptr.ptr(zcu);
try zcu.errNote(other_export.src, msg, "other symbol here", .{});
zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg);
new_export.status = .failed;
src/link.zig
@@ -817,7 +817,7 @@ pub const File = struct {
base: *File,
pt: Zcu.PerThread,
exported: Zcu.Exported,
- export_indices: []const u32,
+ export_indices: []const Zcu.Export.Index,
) UpdateExportsError!void {
switch (base.tag) {
inline else => |tag| {
src/Sema.zig
@@ -38298,7 +38298,7 @@ pub fn flushExports(sema: *Sema) !void {
// So, pick up and delete any existing exports. This strategy performs
// redundant work, but that's okay, because this case is exceedingly rare.
if (zcu.single_exports.get(sema.owner)) |export_idx| {
- try sema.exports.append(gpa, zcu.all_exports.items[export_idx]);
+ try sema.exports.append(gpa, export_idx.ptr(zcu).*);
} else if (zcu.multi_exports.get(sema.owner)) |info| {
try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]);
}
@@ -38307,12 +38307,12 @@ pub fn flushExports(sema: *Sema) !void {
// `sema.exports` is completed; store the data into the `Zcu`.
if (sema.exports.items.len == 1) {
try zcu.single_exports.ensureUnusedCapacity(gpa, 1);
- const export_idx = zcu.free_exports.popOrNull() orelse idx: {
+ const export_idx: Zcu.Export.Index = zcu.free_exports.popOrNull() orelse idx: {
_ = try zcu.all_exports.addOne(gpa);
- break :idx zcu.all_exports.items.len - 1;
+ break :idx @enumFromInt(zcu.all_exports.items.len - 1);
};
- zcu.all_exports.items[export_idx] = sema.exports.items[0];
- zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx));
+ export_idx.ptr(zcu).* = sema.exports.items[0];
+ zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, export_idx);
} else {
try zcu.multi_exports.ensureUnusedCapacity(gpa, 1);
const exports_base = zcu.all_exports.items.len;
src/Zcu.zig
@@ -79,11 +79,11 @@ local_zir_cache: Compilation.Directory,
all_exports: std.ArrayListUnmanaged(Export) = .empty,
/// This is a list of free indices in `all_exports`. These indices may be reused by exports from
/// future semantic analysis.
-free_exports: std.ArrayListUnmanaged(u32) = .empty,
+free_exports: std.ArrayListUnmanaged(Export.Index) = .empty,
/// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of
/// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit`
/// whose analysis triggered the export.
-single_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty,
+single_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, Export.Index) = .empty,
/// Like `single_exports`, but for `AnalUnit`s which perform multiple exports.
/// The exports are `all_exports.items[index..][0..len]`.
multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
@@ -145,8 +145,7 @@ compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .empty,
/// The ErrorMsg memory is owned by the `EmbedFile`, using Module's general purpose allocator.
failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .empty,
-/// Key is index into `all_exports`.
-failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .empty,
+failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty,
/// If analysis failed due to a cimport error, the corresponding Clang errors
/// are stored here.
cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .empty,
@@ -3101,7 +3100,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
const gpa = zcu.gpa;
const exports_base, const exports_len = if (zcu.single_exports.fetchSwapRemove(anal_unit)) |kv|
- .{ kv.value, 1 }
+ .{ @intFromEnum(kv.value), 1 }
else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info|
.{ info.value.index, info.value.len }
else
@@ -3115,11 +3114,12 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
// This case is needed because in some rare edge cases, `Sema` wants to add and delete exports
// within a single update.
if (dev.env.supports(.incremental)) {
- for (exports, exports_base..) |exp, export_idx| {
+ for (exports, exports_base..) |exp, export_index_usize| {
+ const export_idx: Export.Index = @enumFromInt(export_index_usize);
if (zcu.comp.bin_file) |lf| {
lf.deleteExport(exp.exported, exp.opts.name);
}
- if (zcu.failed_exports.fetchSwapRemove(@intCast(export_idx))) |failed_kv| {
+ if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| {
failed_kv.value.destroy(gpa);
}
}
@@ -3131,7 +3131,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void {
return;
};
for (exports_base..exports_base + exports_len) |export_idx| {
- zcu.free_exports.appendAssumeCapacity(@intCast(export_idx));
+ zcu.free_exports.appendAssumeCapacity(@enumFromInt(export_idx));
}
}
@@ -3277,7 +3277,7 @@ fn lockAndClearFileCompileError(zcu: *Zcu, file: *File) void {
pub fn handleUpdateExports(
zcu: *Zcu,
- export_indices: []const u32,
+ export_indices: []const Export.Index,
result: link.File.UpdateExportsError!void,
) Allocator.Error!void {
const gpa = zcu.gpa;
@@ -3285,12 +3285,10 @@ pub fn handleUpdateExports(
error.OutOfMemory => return error.OutOfMemory,
error.AnalysisFail => {
const export_idx = export_indices[0];
- const new_export = &zcu.all_exports.items[export_idx];
+ const new_export = export_idx.ptr(zcu);
new_export.status = .failed_retryable;
try zcu.failed_exports.ensureUnusedCapacity(gpa, 1);
- const msg = try ErrorMsg.create(gpa, new_export.src, "unable to export: {s}", .{
- @errorName(err),
- });
+ const msg = try ErrorMsg.create(gpa, new_export.src, "unable to export: {s}", .{@errorName(err)});
zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg);
},
};