| author | |
| committer | |
| log | 943dac3e8558712096d55a30897057d75444178c |
| tree | 71642efb143c8811cd59c407479dfacbc9723942 |
| parent | 9bf715de74a7d5badeae932afb594b7c6b33afa3 |
18 files changed, 213 insertions(+), 126 deletions(-)
src/Sema.zig+5-5| ... | ... | @@ -38298,7 +38298,7 @@ pub fn flushExports(sema: *Sema) !void { |
| 38298 | 38298 | // So, pick up and delete any existing exports. This strategy performs |
| 38299 | 38299 | // redundant work, but that's okay, because this case is exceedingly rare. |
| 38300 | 38300 | if (zcu.single_exports.get(sema.owner)) |export_idx| { |
| 38301 | try sema.exports.append(gpa, zcu.all_exports.items[export_idx]); | |
| 38301 | try sema.exports.append(gpa, export_idx.ptr(zcu).*); | |
| 38302 | 38302 | } else if (zcu.multi_exports.get(sema.owner)) |info| { |
| 38303 | 38303 | try sema.exports.appendSlice(gpa, zcu.all_exports.items[info.index..][0..info.len]); |
| 38304 | 38304 | } |
| ... | ... | @@ -38307,12 +38307,12 @@ pub fn flushExports(sema: *Sema) !void { |
| 38307 | 38307 | // `sema.exports` is completed; store the data into the `Zcu`. |
| 38308 | 38308 | if (sema.exports.items.len == 1) { |
| 38309 | 38309 | try zcu.single_exports.ensureUnusedCapacity(gpa, 1); |
| 38310 | const export_idx = zcu.free_exports.popOrNull() orelse idx: { | |
| 38310 | const export_idx: Zcu.Export.Index = zcu.free_exports.popOrNull() orelse idx: { | |
| 38311 | 38311 | _ = try zcu.all_exports.addOne(gpa); |
| 38312 | break :idx zcu.all_exports.items.len - 1; | |
| 38312 | break :idx @enumFromInt(zcu.all_exports.items.len - 1); | |
| 38313 | 38313 | }; |
| 38314 | zcu.all_exports.items[export_idx] = sema.exports.items[0]; | |
| 38315 | zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, @intCast(export_idx)); | |
| 38314 | export_idx.ptr(zcu).* = sema.exports.items[0]; | |
| 38315 | zcu.single_exports.putAssumeCapacityNoClobber(sema.owner, export_idx); | |
| 38316 | 38316 | } else { |
| 38317 | 38317 | try zcu.multi_exports.ensureUnusedCapacity(gpa, 1); |
| 38318 | 38318 | const exports_base = zcu.all_exports.items.len; |
src/Zcu.zig+11-13| ... | ... | @@ -79,11 +79,11 @@ local_zir_cache: Compilation.Directory, |
| 79 | 79 | all_exports: std.ArrayListUnmanaged(Export) = .empty, |
| 80 | 80 | /// This is a list of free indices in `all_exports`. These indices may be reused by exports from |
| 81 | 81 | /// future semantic analysis. |
| 82 | free_exports: std.ArrayListUnmanaged(u32) = .empty, | |
| 82 | free_exports: std.ArrayListUnmanaged(Export.Index) = .empty, | |
| 83 | 83 | /// Maps from an `AnalUnit` which performs a single export, to the index into `all_exports` of |
| 84 | 84 | /// the export it performs. Note that the key is not the `Decl` being exported, but the `AnalUnit` |
| 85 | 85 | /// whose analysis triggered the export. |
| 86 | single_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, u32) = .empty, | |
| 86 | single_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, Export.Index) = .empty, | |
| 87 | 87 | /// Like `single_exports`, but for `AnalUnit`s which perform multiple exports. |
| 88 | 88 | /// The exports are `all_exports.items[index..][0..len]`. |
| 89 | 89 | multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| ... | ... | @@ -145,8 +145,7 @@ compile_log_sources: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 145 | 145 | failed_files: std.AutoArrayHashMapUnmanaged(*File, ?*ErrorMsg) = .empty, |
| 146 | 146 | /// The ErrorMsg memory is owned by the `EmbedFile`, using Module's general purpose allocator. |
| 147 | 147 | failed_embed_files: std.AutoArrayHashMapUnmanaged(*EmbedFile, *ErrorMsg) = .empty, |
| 148 | /// Key is index into `all_exports`. | |
| 149 | failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .empty, | |
| 148 | failed_exports: std.AutoArrayHashMapUnmanaged(Export.Index, *ErrorMsg) = .empty, | |
| 150 | 149 | /// If analysis failed due to a cimport error, the corresponding Clang errors |
| 151 | 150 | /// are stored here. |
| 152 | 151 | cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .empty, |
| ... | ... | @@ -3101,7 +3100,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 3101 | 3100 | const gpa = zcu.gpa; |
| 3102 | 3101 | |
| 3103 | 3102 | const exports_base, const exports_len = if (zcu.single_exports.fetchSwapRemove(anal_unit)) |kv| |
| 3104 | .{ kv.value, 1 } | |
| 3103 | .{ @intFromEnum(kv.value), 1 } | |
| 3105 | 3104 | else if (zcu.multi_exports.fetchSwapRemove(anal_unit)) |info| |
| 3106 | 3105 | .{ info.value.index, info.value.len } |
| 3107 | 3106 | else |
| ... | ... | @@ -3115,11 +3114,12 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 3115 | 3114 | // This case is needed because in some rare edge cases, `Sema` wants to add and delete exports |
| 3116 | 3115 | // within a single update. |
| 3117 | 3116 | if (dev.env.supports(.incremental)) { |
| 3118 | for (exports, exports_base..) |exp, export_idx| { | |
| 3117 | for (exports, exports_base..) |exp, export_index_usize| { | |
| 3118 | const export_idx: Export.Index = @enumFromInt(export_index_usize); | |
| 3119 | 3119 | if (zcu.comp.bin_file) |lf| { |
| 3120 | 3120 | lf.deleteExport(exp.exported, exp.opts.name); |
| 3121 | 3121 | } |
| 3122 | if (zcu.failed_exports.fetchSwapRemove(@intCast(export_idx))) |failed_kv| { | |
| 3122 | if (zcu.failed_exports.fetchSwapRemove(export_idx)) |failed_kv| { | |
| 3123 | 3123 | failed_kv.value.destroy(gpa); |
| 3124 | 3124 | } |
| 3125 | 3125 | } |
| ... | ... | @@ -3131,7 +3131,7 @@ pub fn deleteUnitExports(zcu: *Zcu, anal_unit: AnalUnit) void { |
| 3131 | 3131 | return; |
| 3132 | 3132 | }; |
| 3133 | 3133 | for (exports_base..exports_base + exports_len) |export_idx| { |
| 3134 | zcu.free_exports.appendAssumeCapacity(@intCast(export_idx)); | |
| 3134 | zcu.free_exports.appendAssumeCapacity(@enumFromInt(export_idx)); | |
| 3135 | 3135 | } |
| 3136 | 3136 | } |
| 3137 | 3137 | |
| ... | ... | @@ -3277,7 +3277,7 @@ fn lockAndClearFileCompileError(zcu: *Zcu, file: *File) void { |
| 3277 | 3277 | |
| 3278 | 3278 | pub fn handleUpdateExports( |
| 3279 | 3279 | zcu: *Zcu, |
| 3280 | export_indices: []const u32, | |
| 3280 | export_indices: []const Export.Index, | |
| 3281 | 3281 | result: link.File.UpdateExportsError!void, |
| 3282 | 3282 | ) Allocator.Error!void { |
| 3283 | 3283 | const gpa = zcu.gpa; |
| ... | ... | @@ -3285,12 +3285,10 @@ pub fn handleUpdateExports( |
| 3285 | 3285 | error.OutOfMemory => return error.OutOfMemory, |
| 3286 | 3286 | error.AnalysisFail => { |
| 3287 | 3287 | const export_idx = export_indices[0]; |
| 3288 | const new_export = &zcu.all_exports.items[export_idx]; | |
| 3288 | const new_export = export_idx.ptr(zcu); | |
| 3289 | 3289 | new_export.status = .failed_retryable; |
| 3290 | 3290 | try zcu.failed_exports.ensureUnusedCapacity(gpa, 1); |
| 3291 | const msg = try ErrorMsg.create(gpa, new_export.src, "unable to export: {s}", .{ | |
| 3292 | @errorName(err), | |
| 3293 | }); | |
| 3291 | const msg = try ErrorMsg.create(gpa, new_export.src, "unable to export: {s}", .{@errorName(err)}); | |
| 3294 | 3292 | zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg); |
| 3295 | 3293 | }, |
| 3296 | 3294 | }; |
src/Zcu/PerThread.zig+8-8| ... | ... | @@ -2815,8 +2815,8 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2815 | 2815 | const gpa = zcu.gpa; |
| 2816 | 2816 | |
| 2817 | 2817 | // First, construct a mapping of every exported value and Nav to the indices of all its different exports. |
| 2818 | var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(u32)) = .empty; | |
| 2819 | var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(u32)) = .empty; | |
| 2818 | var nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, std.ArrayListUnmanaged(Zcu.Export.Index)) = .empty; | |
| 2819 | var uav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Index, std.ArrayListUnmanaged(Zcu.Export.Index)) = .empty; | |
| 2820 | 2820 | defer { |
| 2821 | 2821 | for (nav_exports.values()) |*exports| { |
| 2822 | 2822 | exports.deinit(gpa); |
| ... | ... | @@ -2835,7 +2835,7 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2835 | 2835 | try nav_exports.ensureTotalCapacity(gpa, zcu.single_exports.count() + zcu.multi_exports.count()); |
| 2836 | 2836 | |
| 2837 | 2837 | for (zcu.single_exports.values()) |export_idx| { |
| 2838 | const exp = zcu.all_exports.items[export_idx]; | |
| 2838 | const exp = export_idx.ptr(zcu); | |
| 2839 | 2839 | const value_ptr, const found_existing = switch (exp.exported) { |
| 2840 | 2840 | .nav => |nav| gop: { |
| 2841 | 2841 | const gop = try nav_exports.getOrPut(gpa, nav); |
| ... | ... | @@ -2863,7 +2863,7 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2863 | 2863 | }, |
| 2864 | 2864 | }; |
| 2865 | 2865 | if (!found_existing) value_ptr.* = .{}; |
| 2866 | try value_ptr.append(gpa, @intCast(export_idx)); | |
| 2866 | try value_ptr.append(gpa, @enumFromInt(export_idx)); | |
| 2867 | 2867 | } |
| 2868 | 2868 | } |
| 2869 | 2869 | |
| ... | ... | @@ -2882,20 +2882,20 @@ pub fn processExports(pt: Zcu.PerThread) !void { |
| 2882 | 2882 | } |
| 2883 | 2883 | } |
| 2884 | 2884 | |
| 2885 | const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, u32); | |
| 2885 | const SymbolExports = std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, Zcu.Export.Index); | |
| 2886 | 2886 | |
| 2887 | 2887 | fn processExportsInner( |
| 2888 | 2888 | pt: Zcu.PerThread, |
| 2889 | 2889 | symbol_exports: *SymbolExports, |
| 2890 | 2890 | exported: Zcu.Exported, |
| 2891 | export_indices: []const u32, | |
| 2891 | export_indices: []const Zcu.Export.Index, | |
| 2892 | 2892 | ) error{OutOfMemory}!void { |
| 2893 | 2893 | const zcu = pt.zcu; |
| 2894 | 2894 | const gpa = zcu.gpa; |
| 2895 | 2895 | const ip = &zcu.intern_pool; |
| 2896 | 2896 | |
| 2897 | 2897 | for (export_indices) |export_idx| { |
| 2898 | const new_export = &zcu.all_exports.items[export_idx]; | |
| 2898 | const new_export = export_idx.ptr(zcu); | |
| 2899 | 2899 | const gop = try symbol_exports.getOrPut(gpa, new_export.opts.name); |
| 2900 | 2900 | if (gop.found_existing) { |
| 2901 | 2901 | new_export.status = .failed_retryable; |
| ... | ... | @@ -2904,7 +2904,7 @@ fn processExportsInner( |
| 2904 | 2904 | new_export.opts.name.fmt(ip), |
| 2905 | 2905 | }); |
| 2906 | 2906 | errdefer msg.destroy(gpa); |
| 2907 | const other_export = zcu.all_exports.items[gop.value_ptr.*]; | |
| 2907 | const other_export = gop.value_ptr.ptr(zcu); | |
| 2908 | 2908 | try zcu.errNote(other_export.src, msg, "other symbol here", .{}); |
| 2909 | 2909 | zcu.failed_exports.putAssumeCapacityNoClobber(export_idx, msg); |
| 2910 | 2910 | new_export.status = .failed; |
src/arch/wasm/CodeGen.zig+8-15| ... | ... | @@ -1,7 +1,6 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | const Allocator = std.mem.Allocator; |
| 4 | const ArrayList = std.ArrayList; | |
| 5 | 4 | const assert = std.debug.assert; |
| 6 | 5 | const testing = std.testing; |
| 7 | 6 | const leb = std.leb; |
| ... | ... | @@ -631,7 +630,7 @@ blocks: std.AutoArrayHashMapUnmanaged(Air.Inst.Index, struct { |
| 631 | 630 | /// Maps `loop` instructions to their label. `br` to here repeats the loop. |
| 632 | 631 | loops: std.AutoHashMapUnmanaged(Air.Inst.Index, u32) = .empty, |
| 633 | 632 | /// `bytes` contains the wasm bytecode belonging to the 'code' section. |
| 634 | code: *ArrayList(u8), | |
| 633 | code: *std.ArrayListUnmanaged(u8), | |
| 635 | 634 | /// The index the next local generated will have |
| 636 | 635 | /// NOTE: arguments share the index with locals therefore the first variable |
| 637 | 636 | /// will have the index that comes after the last argument's index |
| ... | ... | @@ -639,8 +638,6 @@ local_index: u32 = 0, |
| 639 | 638 | /// The index of the current argument. |
| 640 | 639 | /// Used to track which argument is being referenced in `airArg`. |
| 641 | 640 | arg_index: u32 = 0, |
| 642 | /// If codegen fails, an error messages will be allocated and saved in `err_msg` | |
| 643 | err_msg: *Zcu.ErrorMsg, | |
| 644 | 641 | /// List of all locals' types generated throughout this declaration |
| 645 | 642 | /// used to emit locals count at start of 'code' section. |
| 646 | 643 | locals: std.ArrayListUnmanaged(u8), |
| ... | ... | @@ -732,10 +729,9 @@ pub fn deinit(func: *CodeGen) void { |
| 732 | 729 | func.* = undefined; |
| 733 | 730 | } |
| 734 | 731 | |
| 735 | /// Sets `err_msg` on `CodeGen` and returns `error.CodegenFail` which is caught in link/Wasm.zig | |
| 736 | fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) InnerError { | |
| 737 | func.err_msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args); | |
| 738 | return error.CodegenFail; | |
| 732 | fn fail(func: *CodeGen, comptime fmt: []const u8, args: anytype) error{ OutOfMemory, CodegenFail } { | |
| 733 | const msg = try Zcu.ErrorMsg.create(func.gpa, func.src_loc, fmt, args); | |
| 734 | return func.pt.zcu.codegenFailMsg(func.owner_nav, msg); | |
| 739 | 735 | } |
| 740 | 736 | |
| 741 | 737 | /// Resolves the `WValue` for the given instruction `inst` |
| ... | ... | @@ -1173,9 +1169,9 @@ pub fn generate( |
| 1173 | 1169 | func_index: InternPool.Index, |
| 1174 | 1170 | air: Air, |
| 1175 | 1171 | liveness: Liveness, |
| 1176 | code: *std.ArrayList(u8), | |
| 1172 | code: *std.ArrayListUnmanaged(u8), | |
| 1177 | 1173 | debug_output: link.File.DebugInfoOutput, |
| 1178 | ) codegen.CodeGenError!codegen.Result { | |
| 1174 | ) codegen.CodeGenError!void { | |
| 1179 | 1175 | const zcu = pt.zcu; |
| 1180 | 1176 | const gpa = zcu.gpa; |
| 1181 | 1177 | const func = zcu.funcInfo(func_index); |
| ... | ... | @@ -1189,7 +1185,6 @@ pub fn generate( |
| 1189 | 1185 | .code = code, |
| 1190 | 1186 | .owner_nav = func.owner_nav, |
| 1191 | 1187 | .src_loc = src_loc, |
| 1192 | .err_msg = undefined, | |
| 1193 | 1188 | .locals = .{}, |
| 1194 | 1189 | .target = target, |
| 1195 | 1190 | .bin_file = bin_file.cast(.wasm).?, |
| ... | ... | @@ -1199,11 +1194,9 @@ pub fn generate( |
| 1199 | 1194 | defer code_gen.deinit(); |
| 1200 | 1195 | |
| 1201 | 1196 | genFunc(&code_gen) catch |err| switch (err) { |
| 1202 | error.CodegenFail => return codegen.Result{ .fail = code_gen.err_msg }, | |
| 1203 | else => |e| return e, | |
| 1197 | error.CodegenFail => return error.CodegenFail, | |
| 1198 | else => |e| return code_gen.fail("failed to generate function: {s}", .{@errorName(e)}), | |
| 1204 | 1199 | }; |
| 1205 | ||
| 1206 | return codegen.Result.ok; | |
| 1207 | 1200 | } |
| 1208 | 1201 | |
| 1209 | 1202 | fn genFunc(func: *CodeGen) InnerError!void { |
src/arch/wasm/Mir.zig+4-4| ... | ... | @@ -80,15 +80,15 @@ pub const Inst = struct { |
| 80 | 80 | /// |
| 81 | 81 | /// Uses `nop` |
| 82 | 82 | @"return" = 0x0F, |
| 83 | /// Calls a function using `nav_index`. | |
| 84 | call_nav, | |
| 85 | /// Calls a function using `func_index`. | |
| 86 | call_func, | |
| 87 | 83 | /// Calls a function pointer by its function signature |
| 88 | 84 | /// and index into the function table. |
| 89 | 85 | /// |
| 90 | 86 | /// Uses `label` |
| 91 | 87 | call_indirect = 0x11, |
| 88 | /// Calls a function using `nav_index`. | |
| 89 | call_nav, | |
| 90 | /// Calls a function using `func_index`. | |
| 91 | call_func, | |
| 92 | 92 | /// Calls a function by its index. |
| 93 | 93 | /// |
| 94 | 94 | /// The function is the auto-generated tag name function for the type |
src/codegen/c.zig+4-4| ... | ... | @@ -3052,12 +3052,12 @@ pub fn genDeclValue( |
| 3052 | 3052 | try w.writeAll(";\n"); |
| 3053 | 3053 | } |
| 3054 | 3054 | |
| 3055 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const u32) !void { | |
| 3055 | pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const Zcu.Export.Index) !void { | |
| 3056 | 3056 | const zcu = dg.pt.zcu; |
| 3057 | 3057 | const ip = &zcu.intern_pool; |
| 3058 | 3058 | const fwd = dg.fwdDeclWriter(); |
| 3059 | 3059 | |
| 3060 | const main_name = zcu.all_exports.items[export_indices[0]].opts.name; | |
| 3060 | const main_name = export_indices[0].ptr(zcu).opts.name; | |
| 3061 | 3061 | try fwd.writeAll("#define "); |
| 3062 | 3062 | switch (exported) { |
| 3063 | 3063 | .nav => |nav| try dg.renderNavName(fwd, nav), |
| ... | ... | @@ -3069,7 +3069,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const |
| 3069 | 3069 | |
| 3070 | 3070 | const exported_val = exported.getValue(zcu); |
| 3071 | 3071 | if (ip.isFunctionType(exported_val.typeOf(zcu).toIntern())) return for (export_indices) |export_index| { |
| 3072 | const @"export" = &zcu.all_exports.items[export_index]; | |
| 3072 | const @"export" = export_index.ptr(zcu); | |
| 3073 | 3073 | try fwd.writeAll("zig_extern "); |
| 3074 | 3074 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage_fn "); |
| 3075 | 3075 | try dg.renderFunctionSignature( |
| ... | ... | @@ -3091,7 +3091,7 @@ pub fn genExports(dg: *DeclGen, exported: Zcu.Exported, export_indices: []const |
| 3091 | 3091 | else => true, |
| 3092 | 3092 | }; |
| 3093 | 3093 | for (export_indices) |export_index| { |
| 3094 | const @"export" = &zcu.all_exports.items[export_index]; | |
| 3094 | const @"export" = export_index.ptr(zcu); | |
| 3095 | 3095 | try fwd.writeAll("zig_extern "); |
| 3096 | 3096 | if (@"export".opts.linkage == .weak) try fwd.writeAll("zig_weak_linkage "); |
| 3097 | 3097 | const extern_name = @"export".opts.name.toSlice(ip); |
src/codegen/llvm.zig+1-1| ... | ... | @@ -1810,7 +1810,7 @@ pub const Object = struct { |
| 1810 | 1810 | self: *Object, |
| 1811 | 1811 | pt: Zcu.PerThread, |
| 1812 | 1812 | exported: Zcu.Exported, |
| 1813 | export_indices: []const u32, | |
| 1813 | export_indices: []const Zcu.Export.Index, | |
| 1814 | 1814 | ) link.File.UpdateExportsError!void { |
| 1815 | 1815 | assert(std.meta.eql(pt, self.pt)); |
| 1816 | 1816 | const zcu = pt.zcu; |
src/link.zig+1-1| ... | ... | @@ -817,7 +817,7 @@ pub const File = struct { |
| 817 | 817 | base: *File, |
| 818 | 818 | pt: Zcu.PerThread, |
| 819 | 819 | exported: Zcu.Exported, |
| 820 | export_indices: []const u32, | |
| 820 | export_indices: []const Zcu.Export.Index, | |
| 821 | 821 | ) UpdateExportsError!void { |
| 822 | 822 | switch (base.tag) { |
| 823 | 823 | inline else => |tag| { |
src/link/C.zig+1-1| ... | ... | @@ -840,7 +840,7 @@ pub fn updateExports( |
| 840 | 840 | self: *C, |
| 841 | 841 | pt: Zcu.PerThread, |
| 842 | 842 | exported: Zcu.Exported, |
| 843 | export_indices: []const u32, | |
| 843 | export_indices: []const Zcu.Export.Index, | |
| 844 | 844 | ) !void { |
| 845 | 845 | const zcu = pt.zcu; |
| 846 | 846 | const gpa = zcu.gpa; |
src/link/Elf.zig+1-1| ... | ... | @@ -2393,7 +2393,7 @@ pub fn updateExports( |
| 2393 | 2393 | self: *Elf, |
| 2394 | 2394 | pt: Zcu.PerThread, |
| 2395 | 2395 | exported: Zcu.Exported, |
| 2396 | export_indices: []const u32, | |
| 2396 | export_indices: []const Zcu.Export.Index, | |
| 2397 | 2397 | ) link.File.UpdateExportsError!void { |
| 2398 | 2398 | if (build_options.skip_non_native and builtin.object_format != .elf) { |
| 2399 | 2399 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
src/link/Elf/ZigObject.zig+1-1| ... | ... | @@ -1745,7 +1745,7 @@ pub fn updateExports( |
| 1745 | 1745 | elf_file: *Elf, |
| 1746 | 1746 | pt: Zcu.PerThread, |
| 1747 | 1747 | exported: Zcu.Exported, |
| 1748 | export_indices: []const u32, | |
| 1748 | export_indices: []const Zcu.Export.Index, | |
| 1749 | 1749 | ) link.File.UpdateExportsError!void { |
| 1750 | 1750 | const tracy = trace(@src()); |
| 1751 | 1751 | defer tracy.end(); |
src/link/MachO.zig+1-1| ... | ... | @@ -3056,7 +3056,7 @@ pub fn updateExports( |
| 3056 | 3056 | self: *MachO, |
| 3057 | 3057 | pt: Zcu.PerThread, |
| 3058 | 3058 | exported: Zcu.Exported, |
| 3059 | export_indices: []const u32, | |
| 3059 | export_indices: []const Zcu.Export.Index, | |
| 3060 | 3060 | ) link.File.UpdateExportsError!void { |
| 3061 | 3061 | if (build_options.skip_non_native and builtin.object_format != .macho) { |
| 3062 | 3062 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
src/link/MachO/ZigObject.zig+1-1| ... | ... | @@ -1246,7 +1246,7 @@ pub fn updateExports( |
| 1246 | 1246 | macho_file: *MachO, |
| 1247 | 1247 | pt: Zcu.PerThread, |
| 1248 | 1248 | exported: Zcu.Exported, |
| 1249 | export_indices: []const u32, | |
| 1249 | export_indices: []const Zcu.Export.Index, | |
| 1250 | 1250 | ) link.File.UpdateExportsError!void { |
| 1251 | 1251 | const tracy = trace(@src()); |
| 1252 | 1252 | defer tracy.end(); |
src/link/NvPtx.zig+1-1| ... | ... | @@ -100,7 +100,7 @@ pub fn updateExports( |
| 100 | 100 | self: *NvPtx, |
| 101 | 101 | pt: Zcu.PerThread, |
| 102 | 102 | exported: Zcu.Exported, |
| 103 | export_indices: []const u32, | |
| 103 | export_indices: []const Zcu.Export.Index, | |
| 104 | 104 | ) !void { |
| 105 | 105 | if (build_options.skip_non_native and builtin.object_format != .nvptx) |
| 106 | 106 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
src/link/Plan9.zig+3-3| ... | ... | @@ -60,7 +60,7 @@ fn_nav_table: std.AutoArrayHashMapUnmanaged( |
| 60 | 60 | data_nav_table: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u8) = .empty, |
| 61 | 61 | /// When `updateExports` is called, we store the export indices here, to be used |
| 62 | 62 | /// during flush. |
| 63 | nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []u32) = .empty, | |
| 63 | nav_exports: std.AutoArrayHashMapUnmanaged(InternPool.Nav.Index, []Zcu.Export.Index) = .empty, | |
| 64 | 64 | |
| 65 | 65 | lazy_syms: LazySymbolTable = .{}, |
| 66 | 66 | |
| ... | ... | @@ -1007,7 +1007,7 @@ pub fn updateExports( |
| 1007 | 1007 | self: *Plan9, |
| 1008 | 1008 | pt: Zcu.PerThread, |
| 1009 | 1009 | exported: Zcu.Exported, |
| 1010 | export_indices: []const u32, | |
| 1010 | export_indices: []const Zcu.Export.Index, | |
| 1011 | 1011 | ) !void { |
| 1012 | 1012 | const gpa = self.base.comp.gpa; |
| 1013 | 1013 | switch (exported) { |
| ... | ... | @@ -1018,7 +1018,7 @@ pub fn updateExports( |
| 1018 | 1018 | gpa.free(kv.value); |
| 1019 | 1019 | } |
| 1020 | 1020 | try self.nav_exports.ensureUnusedCapacity(gpa, 1); |
| 1021 | const duped_indices = try gpa.dupe(u32, export_indices); | |
| 1021 | const duped_indices = try gpa.dupe(Zcu.Export.Index, export_indices); | |
| 1022 | 1022 | self.nav_exports.putAssumeCapacityNoClobber(nav, duped_indices); |
| 1023 | 1023 | }, |
| 1024 | 1024 | } |
src/link/SpirV.zig+2-2| ... | ... | @@ -155,7 +155,7 @@ pub fn updateExports( |
| 155 | 155 | self: *SpirV, |
| 156 | 156 | pt: Zcu.PerThread, |
| 157 | 157 | exported: Zcu.Exported, |
| 158 | export_indices: []const u32, | |
| 158 | export_indices: []const Zcu.Export.Index, | |
| 159 | 159 | ) !void { |
| 160 | 160 | const zcu = pt.zcu; |
| 161 | 161 | const ip = &zcu.intern_pool; |
| ... | ... | @@ -190,7 +190,7 @@ pub fn updateExports( |
| 190 | 190 | }; |
| 191 | 191 | |
| 192 | 192 | for (export_indices) |export_idx| { |
| 193 | const exp = zcu.all_exports.items[export_idx]; | |
| 193 | const exp = export_idx.ptr(zcu); | |
| 194 | 194 | try self.object.spv.declareEntryPoint( |
| 195 | 195 | spv_decl_index, |
| 196 | 196 | exp.opts.name.toSlice(ip), |
src/link/Wasm.zig+155-58| ... | ... | @@ -56,6 +56,10 @@ base: link.File, |
| 56 | 56 | /// string_table entries for them. Alternately those sites could be moved to |
| 57 | 57 | /// use a different byte array for this purpose. |
| 58 | 58 | string_bytes: std.ArrayListUnmanaged(u8), |
| 59 | /// Sometimes we have logic that wants to borrow string bytes to store | |
| 60 | /// arbitrary things in there. In this case it is not allowed to intern new | |
| 61 | /// strings during this time. This safety lock is used to detect misuses. | |
| 62 | string_bytes_lock: std.debug.SafetyLock = .{}, | |
| 59 | 63 | /// Omitted when serializing linker state. |
| 60 | 64 | string_table: String.Table, |
| 61 | 65 | /// Symbol name of the entry function to export |
| ... | ... | @@ -202,6 +206,10 @@ any_exports_updated: bool = true, |
| 202 | 206 | /// Index into `objects`. |
| 203 | 207 | pub const ObjectIndex = enum(u32) { |
| 204 | 208 | _, |
| 209 | ||
| 210 | pub fn ptr(index: ObjectIndex, wasm: *const Wasm) *Object { | |
| 211 | return &wasm.objects.items[@intFromEnum(index)]; | |
| 212 | } | |
| 205 | 213 | }; |
| 206 | 214 | |
| 207 | 215 | /// Index into `functions`. |
| ... | ... | @@ -269,12 +277,26 @@ pub const SourceLocation = enum(u32) { |
| 269 | 277 | }; |
| 270 | 278 | } |
| 271 | 279 | |
| 280 | pub fn unpack(sl: SourceLocation, wasm: *const Wasm) Unpacked { | |
| 281 | return switch (sl) { | |
| 282 | .zig_object_nofile => .zig_object_nofile, | |
| 283 | .none => .none, | |
| 284 | _ => { | |
| 285 | const i = @intFromEnum(sl); | |
| 286 | if (i < wasm.objects.items.len) return .{ .object_index = @enumFromInt(i) }; | |
| 287 | const sl_index = i - wasm.objects.items.len; | |
| 288 | _ = sl_index; | |
| 289 | @panic("TODO"); | |
| 290 | }, | |
| 291 | }; | |
| 292 | } | |
| 293 | ||
| 272 | 294 | pub fn addError(sl: SourceLocation, wasm: *Wasm, comptime f: []const u8, args: anytype) void { |
| 273 | 295 | const diags = &wasm.base.comp.link_diags; |
| 274 | 296 | switch (sl.unpack(wasm)) { |
| 275 | 297 | .none => unreachable, |
| 276 | 298 | .zig_object_nofile => diags.addError("zig compilation unit: " ++ f, args), |
| 277 | .object_index => |i| diags.addError("{}: " ++ f, .{wasm.objects.items[i].path} ++ args), | |
| 299 | .object_index => |i| diags.addError("{}: " ++ f, .{i.ptr(wasm).path} ++ args), | |
| 278 | 300 | .source_location_index => @panic("TODO"), |
| 279 | 301 | } |
| 280 | 302 | } |
| ... | ... | @@ -520,6 +542,10 @@ pub const FunctionImport = extern struct { |
| 520 | 542 | /// Index into `object_function_imports`. |
| 521 | 543 | pub const Index = enum(u32) { |
| 522 | 544 | _, |
| 545 | ||
| 546 | pub fn ptr(index: FunctionImport.Index, wasm: *const Wasm) *FunctionImport { | |
| 547 | return &wasm.object_function_imports.items[@intFromEnum(index)]; | |
| 548 | } | |
| 523 | 549 | }; |
| 524 | 550 | }; |
| 525 | 551 | |
| ... | ... | @@ -543,7 +569,8 @@ pub const GlobalImport = extern struct { |
| 543 | 569 | source_location: SourceLocation, |
| 544 | 570 | resolution: Resolution, |
| 545 | 571 | |
| 546 | /// Represents a synthetic global, or a global from an object. | |
| 572 | /// Represents a synthetic global, a global from an object, or a global | |
| 573 | /// from the Zcu. | |
| 547 | 574 | pub const Resolution = enum(u32) { |
| 548 | 575 | unresolved, |
| 549 | 576 | __heap_base, |
| ... | ... | @@ -556,6 +583,68 @@ pub const GlobalImport = extern struct { |
| 556 | 583 | // Next, index into `object_globals`. |
| 557 | 584 | // Next, index into `navs`. |
| 558 | 585 | _, |
| 586 | ||
| 587 | const first_object_global = @intFromEnum(Resolution.__zig_error_name_table) + 1; | |
| 588 | ||
| 589 | pub const Unpacked = union(enum) { | |
| 590 | unresolved, | |
| 591 | __heap_base, | |
| 592 | __heap_end, | |
| 593 | __stack_pointer, | |
| 594 | __tls_align, | |
| 595 | __tls_base, | |
| 596 | __tls_size, | |
| 597 | __zig_error_name_table, | |
| 598 | object_global: ObjectGlobalIndex, | |
| 599 | nav: Nav.Index, | |
| 600 | }; | |
| 601 | ||
| 602 | pub fn unpack(r: Resolution, wasm: *const Wasm) Unpacked { | |
| 603 | return switch (r) { | |
| 604 | .unresolved => .unresolved, | |
| 605 | .__wasm_apply_global_tls_relocs => .__wasm_apply_global_tls_relocs, | |
| 606 | .__wasm_call_ctors => .__wasm_call_ctors, | |
| 607 | .__wasm_init_memory => .__wasm_init_memory, | |
| 608 | .__wasm_init_tls => .__wasm_init_tls, | |
| 609 | .__zig_error_names => .__zig_error_names, | |
| 610 | _ => { | |
| 611 | const i: u32 = @intFromEnum(r); | |
| 612 | const object_global_index = i - first_object_global; | |
| 613 | if (object_global_index < wasm.object_globals.items.len) | |
| 614 | return .{ .object_global = @enumFromInt(object_global_index) }; | |
| 615 | const nav_index = object_global_index - wasm.object_globals.items.len; | |
| 616 | return .{ .nav = @enumFromInt(nav_index) }; | |
| 617 | }, | |
| 618 | }; | |
| 619 | } | |
| 620 | ||
| 621 | pub fn pack(wasm: *const Wasm, unpacked: Unpacked) Resolution { | |
| 622 | return switch (unpacked) { | |
| 623 | .unresolved => .unresolved, | |
| 624 | .__heap_base => .__heap_base, | |
| 625 | .__heap_end => .__heap_end, | |
| 626 | .__stack_pointer => .__stack_pointer, | |
| 627 | .__tls_align => .__tls_align, | |
| 628 | .__tls_base => .__tls_base, | |
| 629 | .__tls_size => .__tls_size, | |
| 630 | .__zig_error_name_table => .__zig_error_name_table, | |
| 631 | .object_global => |i| @enumFromInt(first_object_global + @intFromEnum(i)), | |
| 632 | .nav => |i| @enumFromInt(first_object_global + wasm.object_globals.items.len + @intFromEnum(i)), | |
| 633 | }; | |
| 634 | } | |
| 635 | ||
| 636 | pub fn fromIpNav(wasm: *const Wasm, ip_nav: InternPool.Nav.Index) Resolution { | |
| 637 | return pack(wasm, .{ .nav = @enumFromInt(wasm.navs.getIndex(ip_nav).?) }); | |
| 638 | } | |
| 639 | }; | |
| 640 | ||
| 641 | /// Index into `object_global_imports`. | |
| 642 | pub const Index = enum(u32) { | |
| 643 | _, | |
| 644 | ||
| 645 | pub fn ptr(index: Index, wasm: *const Wasm) *GlobalImport { | |
| 646 | return &wasm.object_global_imports.items[@intFromEnum(index)]; | |
| 647 | } | |
| 559 | 648 | }; |
| 560 | 649 | }; |
| 561 | 650 | |
| ... | ... | @@ -634,20 +723,6 @@ pub const ObjectSectionIndex = enum(u32) { |
| 634 | 723 | _, |
| 635 | 724 | }; |
| 636 | 725 | |
| 637 | /// Index into `object_function_imports`. | |
| 638 | pub const ObjectFunctionImportIndex = enum(u32) { | |
| 639 | _, | |
| 640 | ||
| 641 | pub fn ptr(index: ObjectFunctionImportIndex, wasm: *const Wasm) *FunctionImport { | |
| 642 | return &wasm.object_function_imports.items[@intFromEnum(index)]; | |
| 643 | } | |
| 644 | }; | |
| 645 | ||
| 646 | /// Index into `object_global_imports`. | |
| 647 | pub const ObjectGlobalImportIndex = enum(u32) { | |
| 648 | _, | |
| 649 | }; | |
| 650 | ||
| 651 | 726 | /// Index into `object_table_imports`. |
| 652 | 727 | pub const ObjectTableImportIndex = enum(u32) { |
| 653 | 728 | _, |
| ... | ... | @@ -861,11 +936,35 @@ pub const ValtypeList = enum(u32) { |
| 861 | 936 | } |
| 862 | 937 | }; |
| 863 | 938 | |
| 939 | /// Index into `imports`. | |
| 940 | pub const ZcuImportIndex = enum(u32) { | |
| 941 | _, | |
| 942 | }; | |
| 943 | ||
| 864 | 944 | /// 0. Index into `object_function_imports`. |
| 865 | 945 | /// 1. Index into `imports`. |
| 866 | 946 | pub const FunctionImportId = enum(u32) { |
| 867 | 947 | _, |
| 868 | 948 | |
| 949 | pub const Unpacked = union(enum) { | |
| 950 | object_function_import: FunctionImport.Index, | |
| 951 | zcu_import: ZcuImportIndex, | |
| 952 | }; | |
| 953 | ||
| 954 | pub fn pack(unpacked: Unpacked, wasm: *const Wasm) FunctionImportId { | |
| 955 | return switch (unpacked) { | |
| 956 | .object_function_import => |i| @enumFromInt(@intFromEnum(i)), | |
| 957 | .zcu_import => |i| @enumFromInt(@intFromEnum(i) - wasm.object_function_imports.entries.len), | |
| 958 | }; | |
| 959 | } | |
| 960 | ||
| 961 | pub fn unpack(id: FunctionImportId, wasm: *const Wasm) Unpacked { | |
| 962 | const i = @intFromEnum(id); | |
| 963 | if (i < wasm.object_function_imports.entries.len) return .{ .object_function_import = @enumFromInt(i) }; | |
| 964 | const zcu_import_i = i - wasm.object_function_imports.entries.len; | |
| 965 | return .{ .zcu_import = @enumFromInt(zcu_import_i) }; | |
| 966 | } | |
| 967 | ||
| 869 | 968 | /// This function is allowed O(N) lookup because it is only called during |
| 870 | 969 | /// diagnostic generation. |
| 871 | 970 | pub fn sourceLocation(id: FunctionImportId, wasm: *const Wasm) SourceLocation { |
| ... | ... | @@ -873,10 +972,10 @@ pub const FunctionImportId = enum(u32) { |
| 873 | 972 | .object_function_import => |obj_func_index| { |
| 874 | 973 | // TODO binary search |
| 875 | 974 | for (wasm.objects.items, 0..) |o, i| { |
| 876 | if (o.function_imports.off <= obj_func_index and | |
| 877 | o.function_imports.off + o.function_imports.len > obj_func_index) | |
| 975 | if (o.function_imports.off <= @intFromEnum(obj_func_index) and | |
| 976 | o.function_imports.off + o.function_imports.len > @intFromEnum(obj_func_index)) | |
| 878 | 977 | { |
| 879 | return .pack(wasm, .{ .object_index = @enumFromInt(i) }); | |
| 978 | return .pack(.{ .object_index = @enumFromInt(i) }, wasm); | |
| 880 | 979 | } |
| 881 | 980 | } else unreachable; |
| 882 | 981 | }, |
| ... | ... | @@ -890,17 +989,36 @@ pub const FunctionImportId = enum(u32) { |
| 890 | 989 | pub const GlobalImportId = enum(u32) { |
| 891 | 990 | _, |
| 892 | 991 | |
| 992 | pub const Unpacked = union(enum) { | |
| 993 | object_global_import: GlobalImport.Index, | |
| 994 | zcu_import: ZcuImportIndex, | |
| 995 | }; | |
| 996 | ||
| 997 | pub fn pack(unpacked: Unpacked, wasm: *const Wasm) GlobalImportId { | |
| 998 | return switch (unpacked) { | |
| 999 | .object_global_import => |i| @enumFromInt(@intFromEnum(i)), | |
| 1000 | .zcu_import => |i| @enumFromInt(@intFromEnum(i) - wasm.object_global_imports.entries.len), | |
| 1001 | }; | |
| 1002 | } | |
| 1003 | ||
| 1004 | pub fn unpack(id: GlobalImportId, wasm: *const Wasm) Unpacked { | |
| 1005 | const i = @intFromEnum(id); | |
| 1006 | if (i < wasm.object_global_imports.entries.len) return .{ .object_global_import = @enumFromInt(i) }; | |
| 1007 | const zcu_import_i = i - wasm.object_global_imports.entries.len; | |
| 1008 | return .{ .zcu_import = @enumFromInt(zcu_import_i) }; | |
| 1009 | } | |
| 1010 | ||
| 893 | 1011 | /// This function is allowed O(N) lookup because it is only called during |
| 894 | 1012 | /// diagnostic generation. |
| 895 | 1013 | pub fn sourceLocation(id: GlobalImportId, wasm: *const Wasm) SourceLocation { |
| 896 | 1014 | switch (id.unpack(wasm)) { |
| 897 | .object_global_import => |obj_func_index| { | |
| 1015 | .object_global_import => |obj_global_index| { | |
| 898 | 1016 | // TODO binary search |
| 899 | 1017 | for (wasm.objects.items, 0..) |o, i| { |
| 900 | if (o.global_imports.off <= obj_func_index and | |
| 901 | o.global_imports.off + o.global_imports.len > obj_func_index) | |
| 1018 | if (o.global_imports.off <= @intFromEnum(obj_global_index) and | |
| 1019 | o.global_imports.off + o.global_imports.len > @intFromEnum(obj_global_index)) | |
| 902 | 1020 | { |
| 903 | return .pack(wasm, .{ .object_index = @enumFromInt(i) }); | |
| 1021 | return .pack(.{ .object_index = @enumFromInt(i) }, wasm); | |
| 904 | 1022 | } |
| 905 | 1023 | } else unreachable; |
| 906 | 1024 | }, |
| ... | ... | @@ -1330,23 +1448,13 @@ pub fn deinit(wasm: *Wasm) void { |
| 1330 | 1448 | wasm.object_memories.deinit(gpa); |
| 1331 | 1449 | |
| 1332 | 1450 | wasm.object_data_segments.deinit(gpa); |
| 1333 | wasm.object_relocatable_codes.deinit(gpa); | |
| 1334 | 1451 | wasm.object_custom_segments.deinit(gpa); |
| 1335 | wasm.object_symbols.deinit(gpa); | |
| 1336 | wasm.object_named_segments.deinit(gpa); | |
| 1337 | 1452 | wasm.object_init_funcs.deinit(gpa); |
| 1338 | 1453 | wasm.object_comdats.deinit(gpa); |
| 1339 | wasm.object_relocations.deinit(gpa); | |
| 1340 | 1454 | wasm.object_relocations_table.deinit(gpa); |
| 1341 | 1455 | wasm.object_comdat_symbols.deinit(gpa); |
| 1342 | 1456 | wasm.objects.deinit(gpa); |
| 1343 | 1457 | |
| 1344 | wasm.synthetic_symbols.deinit(gpa); | |
| 1345 | wasm.undefs.deinit(gpa); | |
| 1346 | wasm.discarded.deinit(gpa); | |
| 1347 | wasm.segments.deinit(gpa); | |
| 1348 | wasm.segment_info.deinit(gpa); | |
| 1349 | ||
| 1350 | 1458 | wasm.func_types.deinit(gpa); |
| 1351 | 1459 | wasm.function_exports.deinit(gpa); |
| 1352 | 1460 | wasm.function_imports.deinit(gpa); |
| ... | ... | @@ -1354,8 +1462,6 @@ pub fn deinit(wasm: *Wasm) void { |
| 1354 | 1462 | wasm.globals.deinit(gpa); |
| 1355 | 1463 | wasm.global_imports.deinit(gpa); |
| 1356 | 1464 | wasm.table_imports.deinit(gpa); |
| 1357 | wasm.output_globals.deinit(gpa); | |
| 1358 | wasm.exports.deinit(gpa); | |
| 1359 | 1465 | |
| 1360 | 1466 | wasm.string_bytes.deinit(gpa); |
| 1361 | 1467 | wasm.string_table.deinit(gpa); |
| ... | ... | @@ -1374,12 +1480,11 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 1374 | 1480 | const nav_index = func.owner_nav; |
| 1375 | 1481 | |
| 1376 | 1482 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); |
| 1377 | const relocs_start: u32 = @intCast(wasm.relocations.items.len); | |
| 1483 | const relocs_start: u32 = @intCast(wasm.relocations.len); | |
| 1378 | 1484 | wasm.string_bytes_lock.lock(); |
| 1379 | 1485 | |
| 1380 | const wasm_codegen = @import("../../arch/wasm/CodeGen.zig"); | |
| 1381 | 1486 | dev.check(.wasm_backend); |
| 1382 | const result = try wasm_codegen.generate( | |
| 1487 | try CodeGen.generate( | |
| 1383 | 1488 | &wasm.base, |
| 1384 | 1489 | pt, |
| 1385 | 1490 | zcu.navSrcLoc(nav_index), |
| ... | ... | @@ -1391,18 +1496,12 @@ pub fn updateFunc(wasm: *Wasm, pt: Zcu.PerThread, func_index: InternPool.Index, |
| 1391 | 1496 | ); |
| 1392 | 1497 | |
| 1393 | 1498 | const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start); |
| 1394 | const relocs_len: u32 = @intCast(wasm.relocations.items.len - relocs_start); | |
| 1499 | const relocs_len: u32 = @intCast(wasm.relocations.len - relocs_start); | |
| 1395 | 1500 | wasm.string_bytes_lock.unlock(); |
| 1396 | 1501 | |
| 1397 | const code: Nav.Code = switch (result) { | |
| 1398 | .ok => .{ | |
| 1399 | .off = code_start, | |
| 1400 | .len = code_len, | |
| 1401 | }, | |
| 1402 | .fail => |em| { | |
| 1403 | try pt.zcu.failed_codegen.put(gpa, nav_index, em); | |
| 1404 | return; | |
| 1405 | }, | |
| 1502 | const code: Nav.Code = .{ | |
| 1503 | .off = code_start, | |
| 1504 | .len = code_len, | |
| 1406 | 1505 | }; |
| 1407 | 1506 | |
| 1408 | 1507 | 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 |
| 1445 | 1544 | |
| 1446 | 1545 | if (!nav_init.typeOf(zcu).hasRuntimeBits(zcu)) { |
| 1447 | 1546 | _ = wasm.imports.swapRemove(nav_index); |
| 1448 | if (wasm.navs.swapRemove(nav_index)) |old| { | |
| 1449 | _ = old; | |
| 1547 | if (wasm.navs.swapRemove(nav_index)) { | |
| 1450 | 1548 | @panic("TODO reclaim resources"); |
| 1451 | 1549 | } |
| 1452 | 1550 | return; |
| 1453 | 1551 | } |
| 1454 | 1552 | |
| 1455 | 1553 | if (is_extern) { |
| 1456 | try wasm.imports.put(nav_index, {}); | |
| 1457 | if (wasm.navs.swapRemove(nav_index)) |old| { | |
| 1458 | _ = old; | |
| 1554 | try wasm.imports.put(gpa, nav_index, {}); | |
| 1555 | if (wasm.navs.swapRemove(nav_index)) { | |
| 1459 | 1556 | @panic("TODO reclaim resources"); |
| 1460 | 1557 | } |
| 1461 | 1558 | return; |
| 1462 | 1559 | } |
| 1463 | 1560 | |
| 1464 | 1561 | const code_start: u32 = @intCast(wasm.string_bytes.items.len); |
| 1465 | const relocs_start: u32 = @intCast(wasm.relocations.items.len); | |
| 1562 | const relocs_start: u32 = @intCast(wasm.relocations.len); | |
| 1466 | 1563 | wasm.string_bytes_lock.lock(); |
| 1467 | 1564 | |
| 1468 | 1565 | const res = try codegen.generateSymbol( |
| ... | ... | @@ -1475,7 +1572,7 @@ pub fn updateNav(wasm: *Wasm, pt: Zcu.PerThread, nav_index: InternPool.Nav.Index |
| 1475 | 1572 | ); |
| 1476 | 1573 | |
| 1477 | 1574 | const code_len: u32 = @intCast(wasm.string_bytes.items.len - code_start); |
| 1478 | const relocs_len: u32 = @intCast(wasm.relocations.items.len - relocs_start); | |
| 1575 | const relocs_len: u32 = @intCast(wasm.relocations.len - relocs_start); | |
| 1479 | 1576 | wasm.string_bytes_lock.unlock(); |
| 1480 | 1577 | |
| 1481 | 1578 | const code: Nav.Code = switch (res) { |
| ... | ... | @@ -1531,7 +1628,7 @@ pub fn updateExports( |
| 1531 | 1628 | wasm: *Wasm, |
| 1532 | 1629 | pt: Zcu.PerThread, |
| 1533 | 1630 | exported: Zcu.Exported, |
| 1534 | export_indices: []const u32, | |
| 1631 | export_indices: []const Zcu.Export.Index, | |
| 1535 | 1632 | ) !void { |
| 1536 | 1633 | if (build_options.skip_non_native and builtin.object_format != .wasm) { |
| 1537 | 1634 | @panic("Attempted to compile for object format that was disabled by build configuration"); |
| ... | ... | @@ -1668,7 +1765,7 @@ fn markFunction( |
| 1668 | 1765 | wasm: *Wasm, |
| 1669 | 1766 | name: String, |
| 1670 | 1767 | import: *FunctionImport, |
| 1671 | func_index: ObjectFunctionImportIndex, | |
| 1768 | func_index: FunctionImport.Index, | |
| 1672 | 1769 | ) error{OutOfMemory}!void { |
| 1673 | 1770 | if (import.flags.alive) return; |
| 1674 | 1771 | import.flags.alive = true; |
| ... | ... | @@ -1712,7 +1809,7 @@ fn markGlobal( |
| 1712 | 1809 | wasm: *Wasm, |
| 1713 | 1810 | name: String, |
| 1714 | 1811 | import: *GlobalImport, |
| 1715 | global_index: ObjectGlobalImportIndex, | |
| 1812 | global_index: GlobalImport.Index, | |
| 1716 | 1813 | ) !void { |
| 1717 | 1814 | if (import.flags.alive) return; |
| 1718 | 1815 | import.flags.alive = true; |
src/link/Wasm/Flush.zig+5-6| ... | ... | @@ -137,13 +137,12 @@ pub fn finish(f: *Flush, wasm: *Wasm, arena: Allocator) anyerror!void { |
| 137 | 137 | |
| 138 | 138 | // Merge and order the data segments. Depends on garbage collection so that |
| 139 | 139 | // unused segments can be omitted. |
| 140 | try f.ensureUnusedCapacity(gpa, wasm.object_data_segments.items.len); | |
| 140 | try f.data_segments.ensureUnusedCapacity(gpa, wasm.object_data_segments.items.len); | |
| 141 | 141 | for (wasm.object_data_segments.items, 0..) |*ds, i| { |
| 142 | 142 | if (!ds.flags.alive) continue; |
| 143 | const data_segment_index: Wasm.DataSegment.Index = @enumFromInt(i); | |
| 143 | 144 | any_passive_inits = any_passive_inits or ds.flags.is_passive or (import_memory and !isBss(wasm, ds.name)); |
| 144 | f.data_segments.putAssumeCapacityNoClobber(@intCast(i), .{ | |
| 145 | .offset = undefined, | |
| 146 | }); | |
| 145 | f.data_segments.putAssumeCapacityNoClobber(data_segment_index, .{ .offset = undefined }); | |
| 147 | 146 | } |
| 148 | 147 | |
| 149 | 148 | try wasm.functions.ensureUnusedCapacity(gpa, 3); |
| ... | ... | @@ -1082,8 +1081,8 @@ fn emitProducerSection(gpa: Allocator, binary_bytes: *std.ArrayListUnmanaged(u8) |
| 1082 | 1081 | // try writeCustomSectionHeader(binary_bytes.items, header_offset, size); |
| 1083 | 1082 | //} |
| 1084 | 1083 | |
| 1085 | fn isBss(wasm: *Wasm, name: String) bool { | |
| 1086 | const s = name.slice(wasm); | |
| 1084 | fn isBss(wasm: *Wasm, optional_name: Wasm.OptionalString) bool { | |
| 1085 | const s = optional_name.slice(wasm) orelse return false; | |
| 1087 | 1086 | return mem.eql(u8, s, ".bss") or mem.startsWith(u8, s, ".bss."); |
| 1088 | 1087 | } |
| 1089 | 1088 |