authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2024-07-11 23:27:13+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-07-11 23:27:13+01:00
log80d7e260d78400b841f15e3350473650b87931a5
tree3035bae743da24cbe1d5046469fea0a5542a8829
parent45be80364659332807b527670514332a4b835f84
parent77810f288216ef3e35f3d0df4a04351297560a5e
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20570 from jacobly0/fix-races

InternPool: fix more races blocking a separate codegen/linker thread

27 files changed, 1472 insertions(+), 1004 deletions(-)

src/Air.zig+6-1
...@@ -1034,7 +1034,12 @@ pub const Inst = struct {...@@ -1034,7 +1034,12 @@ pub const Inst = struct {
1034 ty: Type,1034 ty: Type,
1035 arg: struct {1035 arg: struct {
1036 ty: Ref,1036 ty: Ref,
1037 src_index: u32,1037 /// Index into `extra` of a null-terminated string representing the parameter name.
1038 /// This is `.none` if debug info is stripped.
1039 name: enum(u32) {
1040 none = std.math.maxInt(u32),
1041 _,
1042 },
1038 },1043 },
1039 ty_op: struct {1044 ty_op: struct {
1040 ty: Ref,1045 ty: Ref,
src/Compilation.zig+51-78
...@@ -1877,6 +1877,7 @@ pub fn destroy(comp: *Compilation) void {...@@ -1877,6 +1877,7 @@ pub fn destroy(comp: *Compilation) void {
1877 if (comp.module) |zcu| zcu.deinit();1877 if (comp.module) |zcu| zcu.deinit();
1878 comp.cache_use.deinit();1878 comp.cache_use.deinit();
1879 comp.work_queue.deinit();1879 comp.work_queue.deinit();
1880 if (!InternPool.single_threaded) comp.codegen_work.queue.deinit();
1880 comp.c_object_work_queue.deinit();1881 comp.c_object_work_queue.deinit();
1881 if (!build_options.only_core_functionality) {1882 if (!build_options.only_core_functionality) {
1882 comp.win32_resource_work_queue.deinit();1883 comp.win32_resource_work_queue.deinit();
...@@ -2119,12 +2120,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2119,12 +2120,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2119 }2120 }
21202121
2121 if (comp.module) |zcu| {2122 if (comp.module) |zcu| {
2123 const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main };
2124
2122 zcu.compile_log_text.shrinkAndFree(gpa, 0);2125 zcu.compile_log_text.shrinkAndFree(gpa, 0);
21232126
2124 // Make sure std.zig is inside the import_table. We unconditionally need2127 // Make sure std.zig is inside the import_table. We unconditionally need
2125 // it for start.zig.2128 // it for start.zig.
2126 const std_mod = zcu.std_mod;2129 const std_mod = zcu.std_mod;
2127 _ = try zcu.importPkg(std_mod);2130 _ = try pt.importPkg(std_mod);
21282131
2129 // Normally we rely on importing std to in turn import the root source file2132 // Normally we rely on importing std to in turn import the root source file
2130 // in the start code, but when using the stage1 backend that won't happen,2133 // in the start code, but when using the stage1 backend that won't happen,
...@@ -2133,20 +2136,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {...@@ -2133,20 +2136,19 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void {
2133 // Likewise, in the case of `zig test`, the test runner is the root source file,2136 // Likewise, in the case of `zig test`, the test runner is the root source file,
2134 // and so there is nothing to import the main file.2137 // and so there is nothing to import the main file.
2135 if (comp.config.is_test) {2138 if (comp.config.is_test) {
2136 _ = try zcu.importPkg(zcu.main_mod);2139 _ = try pt.importPkg(zcu.main_mod);
2137 }2140 }
21382141
2139 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {2142 if (zcu.root_mod.deps.get("compiler_rt")) |compiler_rt_mod| {
2140 _ = try zcu.importPkg(compiler_rt_mod);2143 _ = try pt.importPkg(compiler_rt_mod);
2141 }2144 }
21422145
2143 // Put a work item in for every known source file to detect if2146 // Put a work item in for every known source file to detect if
2144 // it changed, and, if so, re-compute ZIR and then queue the job2147 // it changed, and, if so, re-compute ZIR and then queue the job
2145 // to update it.2148 // to update it.
2146 try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());2149 try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count());
2147 for (zcu.import_table.values(), 0..) |file, file_index_usize| {2150 for (zcu.import_table.values()) |file_index| {
2148 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);2151 if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue;
2149 if (file.mod.isBuiltin()) continue;
2150 comp.astgen_work_queue.writeItemAssumeCapacity(file_index);2152 comp.astgen_work_queue.writeItemAssumeCapacity(file_index);
2151 }2153 }
21522154
...@@ -2641,7 +2643,8 @@ fn resolveEmitLoc(...@@ -2641,7 +2643,8 @@ fn resolveEmitLoc(
2641 return slice.ptr;2643 return slice.ptr;
2642}2644}
26432645
2644fn reportMultiModuleErrors(zcu: *Zcu) !void {2646fn reportMultiModuleErrors(pt: Zcu.PerThread) !void {
2647 const zcu = pt.zcu;
2645 const gpa = zcu.gpa;2648 const gpa = zcu.gpa;
2646 const ip = &zcu.intern_pool;2649 const ip = &zcu.intern_pool;
2647 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to2650 // Some cases can give you a whole bunch of multi-module errors, which it's not helpful to
...@@ -2651,14 +2654,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2651,14 +2654,13 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2651 // Attach the "some omitted" note to the final error message2654 // Attach the "some omitted" note to the final error message
2652 var last_err: ?*Zcu.ErrorMsg = null;2655 var last_err: ?*Zcu.ErrorMsg = null;
26532656
2654 for (zcu.import_table.values(), 0..) |file, file_index_usize| {2657 for (zcu.import_table.values()) |file_index| {
2658 const file = zcu.fileByIndex(file_index);
2655 if (!file.multi_pkg) continue;2659 if (!file.multi_pkg) continue;
26562660
2657 num_errors += 1;2661 num_errors += 1;
2658 if (num_errors > max_errors) continue;2662 if (num_errors > max_errors) continue;
26592663
2660 const file_index: Zcu.File.Index = @enumFromInt(file_index_usize);
2661
2662 const err = err_blk: {2664 const err = err_blk: {
2663 // Like with errors, let's cap the number of notes to prevent a huge error spew.2665 // Like with errors, let's cap the number of notes to prevent a huge error spew.
2664 const max_notes = 5;2666 const max_notes = 5;
...@@ -2674,7 +2676,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2674,7 +2676,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2674 .import => |import| try Zcu.ErrorMsg.init(2676 .import => |import| try Zcu.ErrorMsg.init(
2675 gpa,2677 gpa,
2676 .{2678 .{
2677 .base_node_inst = try ip.trackZir(gpa, import.file, .main_struct_inst),2679 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2680 .file = import.file,
2681 .inst = .main_struct_inst,
2682 }),
2678 .offset = .{ .token_abs = import.token },2683 .offset = .{ .token_abs = import.token },
2679 },2684 },
2680 "imported from module {s}",2685 "imported from module {s}",
...@@ -2683,7 +2688,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2683,7 +2688,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2683 .root => |pkg| try Zcu.ErrorMsg.init(2688 .root => |pkg| try Zcu.ErrorMsg.init(
2684 gpa,2689 gpa,
2685 .{2690 .{
2686 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2691 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2692 .file = file_index,
2693 .inst = .main_struct_inst,
2694 }),
2687 .offset = .entire_file,2695 .offset = .entire_file,
2688 },2696 },
2689 "root of module {s}",2697 "root of module {s}",
...@@ -2697,7 +2705,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2697,7 +2705,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2697 notes[num_notes] = try Zcu.ErrorMsg.init(2705 notes[num_notes] = try Zcu.ErrorMsg.init(
2698 gpa,2706 gpa,
2699 .{2707 .{
2700 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2708 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2709 .file = file_index,
2710 .inst = .main_struct_inst,
2711 }),
2701 .offset = .entire_file,2712 .offset = .entire_file,
2702 },2713 },
2703 "{} more references omitted",2714 "{} more references omitted",
...@@ -2709,7 +2720,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2709,7 +2720,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2709 const err = try Zcu.ErrorMsg.create(2720 const err = try Zcu.ErrorMsg.create(
2710 gpa,2721 gpa,
2711 .{2722 .{
2712 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),2723 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2724 .file = file_index,
2725 .inst = .main_struct_inst,
2726 }),
2713 .offset = .entire_file,2727 .offset = .entire_file,
2714 },2728 },
2715 "file exists in multiple modules",2729 "file exists in multiple modules",
...@@ -2749,8 +2763,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {...@@ -2749,8 +2763,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void {
2749 // to add this flag after reporting the errors however, as otherwise2763 // to add this flag after reporting the errors however, as otherwise
2750 // we'd get an error for every single downstream file, which wouldn't be2764 // we'd get an error for every single downstream file, which wouldn't be
2751 // very useful.2765 // very useful.
2752 for (zcu.import_table.values()) |file| {2766 for (zcu.import_table.values()) |file_index| {
2753 if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu);2767 const file = zcu.fileByIndex(file_index);
2768 if (file.multi_pkg) file.recursiveMarkMultiPkg(pt);
2754 }2769 }
2755}2770}
27562771
...@@ -2774,7 +2789,7 @@ const Header = extern struct {...@@ -2774,7 +2789,7 @@ const Header = extern struct {
2774 //extra_len: u32,2789 //extra_len: u32,
2775 //limbs_len: u32,2790 //limbs_len: u32,
2776 //string_bytes_len: u32,2791 //string_bytes_len: u32,
2777 tracked_insts_len: u32,2792 //tracked_insts_len: u32,
2778 src_hash_deps_len: u32,2793 src_hash_deps_len: u32,
2779 decl_val_deps_len: u32,2794 decl_val_deps_len: u32,
2780 namespace_deps_len: u32,2795 namespace_deps_len: u32,
...@@ -2782,7 +2797,7 @@ const Header = extern struct {...@@ -2782,7 +2797,7 @@ const Header = extern struct {
2782 first_dependency_len: u32,2797 first_dependency_len: u32,
2783 dep_entries_len: u32,2798 dep_entries_len: u32,
2784 free_dep_entries_len: u32,2799 free_dep_entries_len: u32,
2785 files_len: u32,2800 //files_len: u32,
2786 },2801 },
2787};2802};
27882803
...@@ -2803,7 +2818,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2803,7 +2818,7 @@ pub fn saveState(comp: *Compilation) !void {
2803 //.extra_len = @intCast(ip.extra.items.len),2818 //.extra_len = @intCast(ip.extra.items.len),
2804 //.limbs_len = @intCast(ip.limbs.items.len),2819 //.limbs_len = @intCast(ip.limbs.items.len),
2805 //.string_bytes_len = @intCast(ip.string_bytes.items.len),2820 //.string_bytes_len = @intCast(ip.string_bytes.items.len),
2806 .tracked_insts_len = @intCast(ip.tracked_insts.count()),2821 //.tracked_insts_len = @intCast(ip.tracked_insts.count()),
2807 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),2822 .src_hash_deps_len = @intCast(ip.src_hash_deps.count()),
2808 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),2823 .decl_val_deps_len = @intCast(ip.decl_val_deps.count()),
2809 .namespace_deps_len = @intCast(ip.namespace_deps.count()),2824 .namespace_deps_len = @intCast(ip.namespace_deps.count()),
...@@ -2811,7 +2826,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2811,7 +2826,7 @@ pub fn saveState(comp: *Compilation) !void {
2811 .first_dependency_len = @intCast(ip.first_dependency.count()),2826 .first_dependency_len = @intCast(ip.first_dependency.count()),
2812 .dep_entries_len = @intCast(ip.dep_entries.items.len),2827 .dep_entries_len = @intCast(ip.dep_entries.items.len),
2813 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),2828 .free_dep_entries_len = @intCast(ip.free_dep_entries.items.len),
2814 .files_len = @intCast(ip.files.entries.len),2829 //.files_len = @intCast(ip.files.entries.len),
2815 },2830 },
2816 };2831 };
2817 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));2832 addBuf(&bufs_list, &bufs_len, mem.asBytes(&header));
...@@ -2820,7 +2835,7 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2820,7 +2835,7 @@ pub fn saveState(comp: *Compilation) !void {
2820 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));2835 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data)));
2821 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));2836 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag)));
2822 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);2837 //addBuf(&bufs_list, &bufs_len, ip.string_bytes.items);
2823 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));2838 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.tracked_insts.keys()));
28242839
2825 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));2840 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys()));
2826 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values()));2841 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values()));
...@@ -2836,8 +2851,8 @@ pub fn saveState(comp: *Compilation) !void {...@@ -2836,8 +2851,8 @@ pub fn saveState(comp: *Compilation) !void {
2836 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));2851 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items));
2837 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));2852 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items));
28382853
2839 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));2854 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys()));
2840 addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));2855 //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values()));
28412856
2842 // TODO: compilation errors2857 // TODO: compilation errors
2843 // TODO: namespaces2858 // TODO: namespaces
...@@ -2929,7 +2944,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {...@@ -2929,7 +2944,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
2929 }2944 }
2930 }2945 }
29312946
2932 if (zcu.global_error_set.entries.len - 1 > zcu.error_limit) {2947 if (zcu.intern_pool.global_error_set.mutate.list.len > zcu.error_limit) {
2933 total += 1;2948 total += 1;
2934 }2949 }
2935 }2950 }
...@@ -3058,7 +3073,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {...@@ -3058,7 +3073,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
3058 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);3073 try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
3059 }3074 }
30603075
3061 const actual_error_count = zcu.global_error_set.entries.len - 1;3076 const actual_error_count = zcu.intern_pool.global_error_set.mutate.list.len;
3062 if (actual_error_count > zcu.error_limit) {3077 if (actual_error_count > zcu.error_limit) {
3063 try bundle.addRootErrorMessage(.{3078 try bundle.addRootErrorMessage(.{
3064 .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{3079 .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{
...@@ -3443,11 +3458,12 @@ fn performAllTheWorkInner(...@@ -3443,11 +3458,12 @@ fn performAllTheWorkInner(
3443 }3458 }
3444 }3459 }
34453460
3446 if (comp.module) |mod| {3461 if (comp.module) |zcu| {
3447 try reportMultiModuleErrors(mod);3462 const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main };
3448 try mod.flushRetryableFailures();3463 try reportMultiModuleErrors(pt);
3449 mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);3464 try zcu.flushRetryableFailures();
3450 mod.codegen_prog_node = main_progress_node.start("Code Generation", 0);3465 zcu.sema_prog_node = main_progress_node.start("Semantic Analysis", 0);
3466 zcu.codegen_prog_node = main_progress_node.start("Code Generation", 0);
3451 }3467 }
34523468
3453 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});3469 if (!InternPool.single_threaded) comp.thread_pool.spawnWgId(&comp.work_queue_wait_group, codegenThread, .{comp});
...@@ -4131,14 +4147,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye...@@ -4131,14 +4147,6 @@ fn workerDocsWasmFallible(comp: *Compilation, prog_node: std.Progress.Node) anye
4131 };4147 };
4132}4148}
41334149
4134const AstGenSrc = union(enum) {
4135 root,
4136 import: struct {
4137 importing_file: Zcu.File.Index,
4138 import_tok: std.zig.Ast.TokenIndex,
4139 },
4140};
4141
4142fn workerAstGenFile(4150fn workerAstGenFile(
4143 tid: usize,4151 tid: usize,
4144 comp: *Compilation,4152 comp: *Compilation,
...@@ -4148,7 +4156,7 @@ fn workerAstGenFile(...@@ -4148,7 +4156,7 @@ fn workerAstGenFile(
4148 root_decl: Zcu.Decl.OptionalIndex,4156 root_decl: Zcu.Decl.OptionalIndex,
4149 prog_node: std.Progress.Node,4157 prog_node: std.Progress.Node,
4150 wg: *WaitGroup,4158 wg: *WaitGroup,
4151 src: AstGenSrc,4159 src: Zcu.AstGenSrc,
4152) void {4160) void {
4153 const child_prog_node = prog_node.start(file.sub_file_path, 0);4161 const child_prog_node = prog_node.start(file.sub_file_path, 0);
4154 defer child_prog_node.end();4162 defer child_prog_node.end();
...@@ -4158,7 +4166,7 @@ fn workerAstGenFile(...@@ -4158,7 +4166,7 @@ fn workerAstGenFile(
4158 error.AnalysisFail => return,4166 error.AnalysisFail => return,
4159 else => {4167 else => {
4160 file.status = .retryable_failure;4168 file.status = .retryable_failure;
4161 comp.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {4169 pt.reportRetryableAstGenError(src, file_index, err) catch |oom| switch (oom) {
4162 // Swallowing this error is OK because it's implied to be OOM when4170 // Swallowing this error is OK because it's implied to be OOM when
4163 // there is a missing `failed_files` error message.4171 // there is a missing `failed_files` error message.
4164 error.OutOfMemory => {},4172 error.OutOfMemory => {},
...@@ -4189,9 +4197,9 @@ fn workerAstGenFile(...@@ -4189,9 +4197,9 @@ fn workerAstGenFile(
4189 comp.mutex.lock();4197 comp.mutex.lock();
4190 defer comp.mutex.unlock();4198 defer comp.mutex.unlock();
41914199
4192 const res = pt.zcu.importFile(file, import_path) catch continue;4200 const res = pt.importFile(file, import_path) catch continue;
4193 if (!res.is_pkg) {4201 if (!res.is_pkg) {
4194 res.file.addReference(pt.zcu.*, .{ .import = .{4202 res.file.addReference(pt.zcu, .{ .import = .{
4195 .file = file_index,4203 .file = file_index,
4196 .token = item.data.token,4204 .token = item.data.token,
4197 } }) catch continue;4205 } }) catch continue;
...@@ -4204,7 +4212,7 @@ fn workerAstGenFile(...@@ -4204,7 +4212,7 @@ fn workerAstGenFile(
4204 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{4212 log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
4205 file.sub_file_path, import_path, import_result.file.sub_file_path,4213 file.sub_file_path, import_path, import_result.file.sub_file_path,
4206 });4214 });
4207 const sub_src: AstGenSrc = .{ .import = .{4215 const sub_src: Zcu.AstGenSrc = .{ .import = .{
4208 .importing_file = file_index,4216 .importing_file = file_index,
4209 .import_tok = item.data.token,4217 .import_tok = item.data.token,
4210 } };4218 } };
...@@ -4557,41 +4565,6 @@ fn reportRetryableWin32ResourceError(...@@ -4557,41 +4565,6 @@ fn reportRetryableWin32ResourceError(
4557 }4565 }
4558}4566}
45594567
4560fn reportRetryableAstGenError(
4561 comp: *Compilation,
4562 src: AstGenSrc,
4563 file_index: Zcu.File.Index,
4564 err: anyerror,
4565) error{OutOfMemory}!void {
4566 const zcu = comp.module.?;
4567 const gpa = zcu.gpa;
4568
4569 const file = zcu.fileByIndex(file_index);
4570 file.status = .retryable_failure;
4571
4572 const src_loc: Zcu.LazySrcLoc = switch (src) {
4573 .root => .{
4574 .base_node_inst = try zcu.intern_pool.trackZir(gpa, file_index, .main_struct_inst),
4575 .offset = .entire_file,
4576 },
4577 .import => |info| .{
4578 .base_node_inst = try zcu.intern_pool.trackZir(gpa, info.importing_file, .main_struct_inst),
4579 .offset = .{ .token_abs = info.import_tok },
4580 },
4581 };
4582
4583 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
4584 file.mod.root, file.sub_file_path, @errorName(err),
4585 });
4586 errdefer err_msg.destroy(gpa);
4587
4588 {
4589 comp.mutex.lock();
4590 defer comp.mutex.unlock();
4591 try zcu.failed_files.putNoClobber(gpa, file, err_msg);
4592 }
4593}
4594
4595fn reportRetryableEmbedFileError(4568fn reportRetryableEmbedFileError(
4596 comp: *Compilation,4569 comp: *Compilation,
4597 embed_file: *Zcu.EmbedFile,4570 embed_file: *Zcu.EmbedFile,
src/InternPool.zig+649-220
...@@ -1,12 +1,13 @@...@@ -1,12 +1,13 @@
1//! All interned objects have both a value and a type.1//! All interned objects have both a value and a type.
2//! This data structure is self-contained, with the following exceptions:2//! This data structure is self-contained.
3//! * Module.Namespace has a pointer to Module.File
43
5/// One item per thread, indexed by `tid`, which is dense and unique per thread.4/// One item per thread, indexed by `tid`, which is dense and unique per thread.
6locals: []Local = &.{},5locals: []Local = &.{},
7/// Length must be a power of two and represents the number of simultaneous6/// Length must be a power of two and represents the number of simultaneous
8/// writers that can mutate any single sharded data structure.7/// writers that can mutate any single sharded data structure.
9shards: []Shard = &.{},8shards: []Shard = &.{},
9/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
10global_error_set: GlobalErrorSet = GlobalErrorSet.empty,
10/// Cached number of active bits in a `tid`.11/// Cached number of active bits in a `tid`.
11tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,12tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0,
12/// Cached shift amount to put a `tid` in the top bits of a 31-bit value.13/// Cached shift amount to put a `tid` in the top bits of a 31-bit value.
...@@ -14,17 +15,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th...@@ -14,17 +15,6 @@ tid_shift_31: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_th
14/// Cached shift amount to put a `tid` in the top bits of a 32-bit value.15/// Cached shift amount to put a `tid` in the top bits of a 32-bit value.
15tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,16tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31,
1617
17/// Some types such as enums, structs, and unions need to store mappings from field names
18/// to field index, or value to field index. In such cases, they will store the underlying
19/// field names and values directly, relying on one of these maps, stored separately,
20/// to provide lookup.
21/// These are not serialized; it is computed upon deserialization.
22maps: std.ArrayListUnmanaged(FieldMap) = .{},
23
24/// An index into `tracked_insts` gives a reference to a single ZIR instruction which
25/// persists across incremental updates.
26tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{},
27
28/// Dependencies on the source code hash associated with a ZIR instruction.18/// Dependencies on the source code hash associated with a ZIR instruction.
29/// * For a `declaration`, this is the entire declaration body.19/// * For a `declaration`, this is the entire declaration body.
30/// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations).20/// * For a `struct_decl`, `union_decl`, etc, this is the source of the fields (but not declarations).
...@@ -60,17 +50,6 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},...@@ -60,17 +50,6 @@ dep_entries: std.ArrayListUnmanaged(DepEntry) = .{},
60/// garbage collection pass.50/// garbage collection pass.
61free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},51free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{},
6252
63/// Elements are ordered identically to the `import_table` field of `Zcu`.
64///
65/// Unlike `import_table`, this data is serialized as part of incremental
66/// compilation state.
67///
68/// Key is the hash of the path to this file, used to store
69/// `InternPool.TrackedInst`.
70///
71/// Value is the `Decl` of the struct that represents this `File`.
72files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{},
73
74/// Whether a multi-threaded intern pool is useful.53/// Whether a multi-threaded intern pool is useful.
75/// Currently `false` until the intern pool is actually accessed54/// Currently `false` until the intern pool is actually accessed
76/// from multiple threads to reduce the cost of this data structure.55/// from multiple threads to reduce the cost of this data structure.
...@@ -79,10 +58,6 @@ const want_multi_threaded = false;...@@ -79,10 +58,6 @@ const want_multi_threaded = false;
79/// Whether a single-threaded intern pool impl is in use.58/// Whether a single-threaded intern pool impl is in use.
80pub const single_threaded = builtin.single_threaded or !want_multi_threaded;59pub const single_threaded = builtin.single_threaded or !want_multi_threaded;
8160
82pub const FileIndex = enum(u32) {
83 _,
84};
85
86pub const TrackedInst = extern struct {61pub const TrackedInst = extern struct {
87 file: FileIndex,62 file: FileIndex,
88 inst: Zir.Inst.Index,63 inst: Zir.Inst.Index,
...@@ -92,12 +67,15 @@ pub const TrackedInst = extern struct {...@@ -92,12 +67,15 @@ pub const TrackedInst = extern struct {
92 }67 }
93 pub const Index = enum(u32) {68 pub const Index = enum(u32) {
94 _,69 _,
95 pub fn resolveFull(i: TrackedInst.Index, ip: *const InternPool) TrackedInst {70 pub fn resolveFull(tracked_inst_index: TrackedInst.Index, ip: *const InternPool) TrackedInst {
96 return ip.tracked_insts.keys()[@intFromEnum(i)];71 const tracked_inst_unwrapped = tracked_inst_index.unwrap(ip);
72 const tracked_insts = ip.getLocalShared(tracked_inst_unwrapped.tid).tracked_insts.acquire();
73 return tracked_insts.view().items(.@"0")[tracked_inst_unwrapped.index];
97 }74 }
98 pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index {75 pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index {
99 return i.resolveFull(ip).inst;76 return i.resolveFull(ip).inst;
100 }77 }
78
101 pub fn toOptional(i: TrackedInst.Index) Optional {79 pub fn toOptional(i: TrackedInst.Index) Optional {
102 return @enumFromInt(@intFromEnum(i));80 return @enumFromInt(@intFromEnum(i));
103 }81 }
...@@ -111,21 +89,124 @@ pub const TrackedInst = extern struct {...@@ -111,21 +89,124 @@ pub const TrackedInst = extern struct {
111 };89 };
112 }90 }
113 };91 };
92
93 pub const Unwrapped = struct {
94 tid: Zcu.PerThread.Id,
95 index: u32,
96
97 pub fn wrap(unwrapped: Unwrapped, ip: *const InternPool) TrackedInst.Index {
98 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
99 assert(unwrapped.index <= ip.getIndexMask(u32));
100 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
101 unwrapped.index);
102 }
103 };
104 pub fn unwrap(tracked_inst_index: TrackedInst.Index, ip: *const InternPool) Unwrapped {
105 return .{
106 .tid = @enumFromInt(@intFromEnum(tracked_inst_index) >> ip.tid_shift_32 & ip.getTidMask()),
107 .index = @intFromEnum(tracked_inst_index) & ip.getIndexMask(u32),
108 };
109 }
114 };110 };
115};111};
116112
117pub fn trackZir(113pub fn trackZir(
118 ip: *InternPool,114 ip: *InternPool,
119 gpa: Allocator,115 gpa: Allocator,
120 file: FileIndex,116 tid: Zcu.PerThread.Id,
121 inst: Zir.Inst.Index,117 key: TrackedInst,
122) Allocator.Error!TrackedInst.Index {118) Allocator.Error!TrackedInst.Index {
123 const key: TrackedInst = .{119 const full_hash = Hash.hash(0, std.mem.asBytes(&key));
124 .file = file,120 const hash: u32 = @truncate(full_hash >> 32);
125 .inst = inst,121 const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))];
126 };122 var map = shard.shared.tracked_inst_map.acquire();
127 const gop = try ip.tracked_insts.getOrPut(gpa, key);123 const Map = @TypeOf(map);
128 return @enumFromInt(gop.index);124 var map_mask = map.header().mask();
125 var map_index = hash;
126 while (true) : (map_index += 1) {
127 map_index &= map_mask;
128 const entry = &map.entries[map_index];
129 const index = entry.acquire().unwrap() orelse break;
130 if (entry.hash != hash) continue;
131 if (std.meta.eql(index.resolveFull(ip), key)) return index;
132 }
133 shard.mutate.tracked_inst_map.mutex.lock();
134 defer shard.mutate.tracked_inst_map.mutex.unlock();
135 if (map.entries != shard.shared.tracked_inst_map.entries) {
136 shard.mutate.tracked_inst_map.len += 1;
137 map = shard.shared.tracked_inst_map;
138 map_mask = map.header().mask();
139 map_index = hash;
140 }
141 while (true) : (map_index += 1) {
142 map_index &= map_mask;
143 const entry = &map.entries[map_index];
144 const index = entry.acquire().unwrap() orelse break;
145 if (entry.hash != hash) continue;
146 if (std.meta.eql(index.resolveFull(ip), key)) return index;
147 }
148 defer shard.mutate.tracked_inst_map.len += 1;
149 const local = ip.getLocal(tid);
150 local.mutate.tracked_insts.mutex.lock();
151 defer local.mutate.tracked_insts.mutex.unlock();
152 const list = local.getMutableTrackedInsts(gpa);
153 try list.ensureUnusedCapacity(1);
154 const map_header = map.header().*;
155 if (shard.mutate.tracked_inst_map.len < map_header.capacity * 3 / 5) {
156 const entry = &map.entries[map_index];
157 entry.hash = hash;
158 const index = (TrackedInst.Index.Unwrapped{
159 .tid = tid,
160 .index = list.mutate.len,
161 }).wrap(ip);
162 list.appendAssumeCapacity(.{key});
163 entry.release(index.toOptional());
164 return index;
165 }
166 const arena_state = &local.mutate.arena;
167 var arena = arena_state.promote(gpa);
168 defer arena_state.* = arena.state;
169 const new_map_capacity = map_header.capacity * 2;
170 const new_map_buf = try arena.allocator().alignedAlloc(
171 u8,
172 Map.alignment,
173 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
174 );
175 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
176 new_map.header().* = .{ .capacity = new_map_capacity };
177 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
178 const new_map_mask = new_map.header().mask();
179 map_index = 0;
180 while (map_index < map_header.capacity) : (map_index += 1) {
181 const entry = &map.entries[map_index];
182 const index = entry.value.unwrap() orelse continue;
183 const item_hash = entry.hash;
184 var new_map_index = item_hash;
185 while (true) : (new_map_index += 1) {
186 new_map_index &= new_map_mask;
187 const new_entry = &new_map.entries[new_map_index];
188 if (new_entry.value != .none) continue;
189 new_entry.* = .{
190 .value = index.toOptional(),
191 .hash = item_hash,
192 };
193 break;
194 }
195 }
196 map = new_map;
197 map_index = hash;
198 while (true) : (map_index += 1) {
199 map_index &= new_map_mask;
200 if (map.entries[map_index].value == .none) break;
201 }
202 const index = (TrackedInst.Index.Unwrapped{
203 .tid = tid,
204 .index = list.mutate.len,
205 }).wrap(ip);
206 list.appendAssumeCapacity(.{key});
207 map.entries[map_index] = .{ .value = index.toOptional(), .hash = hash };
208 shard.shared.tracked_inst_map.release(new_map);
209 return index;
129}210}
130211
131/// Analysis Unit. Represents a single entity which undergoes semantic analysis.212/// Analysis Unit. Represents a single entity which undergoes semantic analysis.
...@@ -337,9 +418,12 @@ const Local = struct {...@@ -337,9 +418,12 @@ const Local = struct {
337 arena: std.heap.ArenaAllocator.State,418 arena: std.heap.ArenaAllocator.State,
338419
339 items: ListMutate,420 items: ListMutate,
340 extra: ListMutate,421 extra: MutexListMutate,
341 limbs: ListMutate,422 limbs: ListMutate,
342 strings: ListMutate,423 strings: ListMutate,
424 tracked_insts: MutexListMutate,
425 files: ListMutate,
426 maps: ListMutate,
343427
344 decls: BucketListMutate,428 decls: BucketListMutate,
345 namespaces: BucketListMutate,429 namespaces: BucketListMutate,
...@@ -350,6 +434,9 @@ const Local = struct {...@@ -350,6 +434,9 @@ const Local = struct {
350 extra: Extra,434 extra: Extra,
351 limbs: Limbs,435 limbs: Limbs,
352 strings: Strings,436 strings: Strings,
437 tracked_insts: TrackedInsts,
438 files: List(File),
439 maps: Maps,
353440
354 decls: Decls,441 decls: Decls,
355 namespaces: Namespaces,442 namespaces: Namespaces,
...@@ -370,16 +457,18 @@ const Local = struct {...@@ -370,16 +457,18 @@ const Local = struct {
370 else => @compileError("unsupported host"),457 else => @compileError("unsupported host"),
371 };458 };
372 const Strings = List(struct { u8 });459 const Strings = List(struct { u8 });
460 const TrackedInsts = List(struct { TrackedInst });
461 const Maps = List(struct { FieldMap });
373462
374 const decls_bucket_width = 8;463 const decls_bucket_width = 8;
375 const decls_bucket_mask = (1 << decls_bucket_width) - 1;464 const decls_bucket_mask = (1 << decls_bucket_width) - 1;
376 const decl_next_free_field = "src_namespace";465 const decl_next_free_field = "src_namespace";
377 const Decls = List(struct { *[1 << decls_bucket_width]Module.Decl });466 const Decls = List(struct { *[1 << decls_bucket_width]Zcu.Decl });
378467
379 const namespaces_bucket_width = 8;468 const namespaces_bucket_width = 8;
380 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;469 const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1;
381 const namespace_next_free_field = "decl_index";470 const namespace_next_free_field = "decl_index";
382 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Module.Namespace });471 const Namespaces = List(struct { *[1 << namespaces_bucket_width]Zcu.Namespace });
383472
384 const ListMutate = struct {473 const ListMutate = struct {
385 len: u32,474 len: u32,
...@@ -389,6 +478,16 @@ const Local = struct {...@@ -389,6 +478,16 @@ const Local = struct {
389 };478 };
390 };479 };
391480
481 const MutexListMutate = struct {
482 mutex: std.Thread.Mutex,
483 list: ListMutate,
484
485 const empty: MutexListMutate = .{
486 .mutex = .{},
487 .list = ListMutate.empty,
488 };
489 };
490
392 const BucketListMutate = struct {491 const BucketListMutate = struct {
393 last_bucket_len: u32,492 last_bucket_len: u32,
394 buckets_list: ListMutate,493 buckets_list: ListMutate,
...@@ -410,7 +509,7 @@ const Local = struct {...@@ -410,7 +509,7 @@ const Local = struct {
410509
411 const ListSelf = @This();510 const ListSelf = @This();
412 const Mutable = struct {511 const Mutable = struct {
413 gpa: std.mem.Allocator,512 gpa: Allocator,
414 arena: *std.heap.ArenaAllocator.State,513 arena: *std.heap.ArenaAllocator.State,
415 mutate: *ListMutate,514 mutate: *ListMutate,
416 list: *ListSelf,515 list: *ListSelf,
...@@ -435,14 +534,17 @@ const Local = struct {...@@ -435,14 +534,17 @@ const Local = struct {
435 .is_tuple = elem_info.is_tuple,534 .is_tuple = elem_info.is_tuple,
436 } });535 } });
437 }536 }
438 fn SliceElem(comptime opts: struct { is_const: bool = false }) type {537 fn PtrElem(comptime opts: struct {
538 size: std.builtin.Type.Pointer.Size,
539 is_const: bool = false,
540 }) type {
439 const elem_info = @typeInfo(Elem).Struct;541 const elem_info = @typeInfo(Elem).Struct;
440 const elem_fields = elem_info.fields;542 const elem_fields = elem_info.fields;
441 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;543 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
442 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{544 for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{
443 .name = elem_field.name,545 .name = elem_field.name,
444 .type = @Type(.{ .Pointer = .{546 .type = @Type(.{ .Pointer = .{
445 .size = .Slice,547 .size = opts.size,
446 .is_const = opts.is_const,548 .is_const = opts.is_const,
447 .is_volatile = false,549 .is_volatile = false,
448 .alignment = 0,550 .alignment = 0,
...@@ -463,6 +565,23 @@ const Local = struct {...@@ -463,6 +565,23 @@ const Local = struct {
463 } });565 } });
464 }566 }
465567
568 pub fn addOne(mutable: Mutable) Allocator.Error!PtrElem(.{ .size = .One }) {
569 try mutable.ensureUnusedCapacity(1);
570 return mutable.addOneAssumeCapacity();
571 }
572
573 pub fn addOneAssumeCapacity(mutable: Mutable) PtrElem(.{ .size = .One }) {
574 const index = mutable.mutate.len;
575 assert(index < mutable.list.header().capacity);
576 mutable.mutate.len = index + 1;
577 const mutable_view = mutable.view().slice();
578 var ptr: PtrElem(.{ .size = .One }) = undefined;
579 inline for (fields) |field| {
580 @field(ptr, @tagName(field)) = &mutable_view.items(field)[index];
581 }
582 return ptr;
583 }
584
466 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {585 pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void {
467 try mutable.ensureUnusedCapacity(1);586 try mutable.ensureUnusedCapacity(1);
468 mutable.appendAssumeCapacity(elem);587 mutable.appendAssumeCapacity(elem);
...@@ -476,14 +595,14 @@ const Local = struct {...@@ -476,14 +595,14 @@ const Local = struct {
476595
477 pub fn appendSliceAssumeCapacity(596 pub fn appendSliceAssumeCapacity(
478 mutable: Mutable,597 mutable: Mutable,
479 slice: SliceElem(.{ .is_const = true }),598 slice: PtrElem(.{ .size = .Slice, .is_const = true }),
480 ) void {599 ) void {
481 if (fields.len == 0) return;600 if (fields.len == 0) return;
482 const start = mutable.mutate.len;601 const start = mutable.mutate.len;
483 const slice_len = @field(slice, @tagName(fields[0])).len;602 const slice_len = @field(slice, @tagName(fields[0])).len;
484 assert(slice_len <= mutable.list.header().capacity - start);603 assert(slice_len <= mutable.list.header().capacity - start);
485 mutable.mutate.len = @intCast(start + slice_len);604 mutable.mutate.len = @intCast(start + slice_len);
486 const mutable_view = mutable.view();605 const mutable_view = mutable.view().slice();
487 inline for (fields) |field| {606 inline for (fields) |field| {
488 const field_slice = @field(slice, @tagName(field));607 const field_slice = @field(slice, @tagName(field));
489 assert(field_slice.len == slice_len);608 assert(field_slice.len == slice_len);
...@@ -500,7 +619,7 @@ const Local = struct {...@@ -500,7 +619,7 @@ const Local = struct {
500 const start = mutable.mutate.len;619 const start = mutable.mutate.len;
501 assert(len <= mutable.list.header().capacity - start);620 assert(len <= mutable.list.header().capacity - start);
502 mutable.mutate.len = @intCast(start + len);621 mutable.mutate.len = @intCast(start + len);
503 const mutable_view = mutable.view();622 const mutable_view = mutable.view().slice();
504 inline for (fields) |field| {623 inline for (fields) |field| {
505 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));624 @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field)));
506 }625 }
...@@ -515,7 +634,7 @@ const Local = struct {...@@ -515,7 +634,7 @@ const Local = struct {
515 const start = mutable.mutate.len;634 const start = mutable.mutate.len;
516 assert(len <= mutable.list.header().capacity - start);635 assert(len <= mutable.list.header().capacity - start);
517 mutable.mutate.len = @intCast(start + len);636 mutable.mutate.len = @intCast(start + len);
518 const mutable_view = mutable.view();637 const mutable_view = mutable.view().slice();
519 var ptr_array: PtrArrayElem(len) = undefined;638 var ptr_array: PtrArrayElem(len) = undefined;
520 inline for (fields) |field| {639 inline for (fields) |field| {
521 @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len];640 @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len];
...@@ -523,17 +642,17 @@ const Local = struct {...@@ -523,17 +642,17 @@ const Local = struct {
523 return ptr_array;642 return ptr_array;
524 }643 }
525644
526 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!SliceElem(.{}) {645 pub fn addManyAsSlice(mutable: Mutable, len: usize) Allocator.Error!PtrElem(.{ .size = .Slice }) {
527 try mutable.ensureUnusedCapacity(len);646 try mutable.ensureUnusedCapacity(len);
528 return mutable.addManyAsSliceAssumeCapacity(len);647 return mutable.addManyAsSliceAssumeCapacity(len);
529 }648 }
530649
531 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) {650 pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) PtrElem(.{ .size = .Slice }) {
532 const start = mutable.mutate.len;651 const start = mutable.mutate.len;
533 assert(len <= mutable.list.header().capacity - start);652 assert(len <= mutable.list.header().capacity - start);
534 mutable.mutate.len = @intCast(start + len);653 mutable.mutate.len = @intCast(start + len);
535 const mutable_view = mutable.view();654 const mutable_view = mutable.view().slice();
536 var slice: SliceElem(.{}) = undefined;655 var slice: PtrElem(.{ .size = .Slice }) = undefined;
537 inline for (fields) |field| {656 inline for (fields) |field| {
538 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];657 @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len];
539 }658 }
...@@ -578,7 +697,7 @@ const Local = struct {...@@ -578,7 +697,7 @@ const Local = struct {
578 mutable.list.release(new_list);697 mutable.list.release(new_list);
579 }698 }
580699
581 fn view(mutable: Mutable) View {700 pub fn view(mutable: Mutable) View {
582 const capacity = mutable.list.header().capacity;701 const capacity = mutable.list.header().capacity;
583 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`702 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
584 return .{703 return .{
...@@ -602,7 +721,7 @@ const Local = struct {...@@ -602,7 +721,7 @@ const Local = struct {
602 const View = std.MultiArrayList(Elem);721 const View = std.MultiArrayList(Elem);
603722
604 /// Must be called when accessing from another thread.723 /// Must be called when accessing from another thread.
605 fn acquire(list: *const ListSelf) ListSelf {724 pub fn acquire(list: *const ListSelf) ListSelf {
606 return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) };725 return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) };
607 }726 }
608 fn release(list: *ListSelf, new_list: ListSelf) void {727 fn release(list: *ListSelf, new_list: ListSelf) void {
...@@ -616,7 +735,7 @@ const Local = struct {...@@ -616,7 +735,7 @@ const Local = struct {
616 return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);735 return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset);
617 }736 }
618737
619 fn view(list: ListSelf) View {738 pub fn view(list: ListSelf) View {
620 const capacity = list.header().capacity;739 const capacity = list.header().capacity;
621 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`740 assert(capacity > 0); // optimizes `MultiArrayList.Slice.items`
622 return .{741 return .{
...@@ -628,7 +747,7 @@ const Local = struct {...@@ -628,7 +747,7 @@ const Local = struct {
628 };747 };
629 }748 }
630749
631 pub fn getMutableItems(local: *Local, gpa: std.mem.Allocator) List(Item).Mutable {750 pub fn getMutableItems(local: *Local, gpa: Allocator) List(Item).Mutable {
632 return .{751 return .{
633 .gpa = gpa,752 .gpa = gpa,
634 .arena = &local.mutate.arena,753 .arena = &local.mutate.arena,
...@@ -637,11 +756,11 @@ const Local = struct {...@@ -637,11 +756,11 @@ const Local = struct {
637 };756 };
638 }757 }
639758
640 pub fn getMutableExtra(local: *Local, gpa: std.mem.Allocator) Extra.Mutable {759 pub fn getMutableExtra(local: *Local, gpa: Allocator) Extra.Mutable {
641 return .{760 return .{
642 .gpa = gpa,761 .gpa = gpa,
643 .arena = &local.mutate.arena,762 .arena = &local.mutate.arena,
644 .mutate = &local.mutate.extra,763 .mutate = &local.mutate.extra.list,
645 .list = &local.shared.extra,764 .list = &local.shared.extra,
646 };765 };
647 }766 }
...@@ -650,7 +769,7 @@ const Local = struct {...@@ -650,7 +769,7 @@ const Local = struct {
650 /// On 64-bit systems, this array is used for big integers and associated metadata.769 /// On 64-bit systems, this array is used for big integers and associated metadata.
651 /// Use the helper methods instead of accessing this directly in order to not770 /// Use the helper methods instead of accessing this directly in order to not
652 /// violate the above mechanism.771 /// violate the above mechanism.
653 pub fn getMutableLimbs(local: *Local, gpa: std.mem.Allocator) Limbs.Mutable {772 pub fn getMutableLimbs(local: *Local, gpa: Allocator) Limbs.Mutable {
654 return switch (@sizeOf(Limb)) {773 return switch (@sizeOf(Limb)) {
655 @sizeOf(u32) => local.getMutableExtra(gpa),774 @sizeOf(u32) => local.getMutableExtra(gpa),
656 @sizeOf(u64) => .{775 @sizeOf(u64) => .{
...@@ -668,7 +787,7 @@ const Local = struct {...@@ -668,7 +787,7 @@ const Local = struct {
668 /// is referencing the data here whether they want to store both index and length,787 /// is referencing the data here whether they want to store both index and length,
669 /// thus allowing null bytes, or store only index, and use null-termination. The788 /// thus allowing null bytes, or store only index, and use null-termination. The
670 /// `strings` array is agnostic to either usage.789 /// `strings` array is agnostic to either usage.
671 pub fn getMutableStrings(local: *Local, gpa: std.mem.Allocator) Strings.Mutable {790 pub fn getMutableStrings(local: *Local, gpa: Allocator) Strings.Mutable {
672 return .{791 return .{
673 .gpa = gpa,792 .gpa = gpa,
674 .arena = &local.mutate.arena,793 .arena = &local.mutate.arena,
...@@ -677,6 +796,49 @@ const Local = struct {...@@ -677,6 +796,49 @@ const Local = struct {
677 };796 };
678 }797 }
679798
799 /// An index into `tracked_insts` gives a reference to a single ZIR instruction which
800 /// persists across incremental updates.
801 pub fn getMutableTrackedInsts(local: *Local, gpa: Allocator) TrackedInsts.Mutable {
802 return .{
803 .gpa = gpa,
804 .arena = &local.mutate.arena,
805 .mutate = &local.mutate.tracked_insts.list,
806 .list = &local.shared.tracked_insts,
807 };
808 }
809
810 /// Elements are ordered identically to the `import_table` field of `Zcu`.
811 ///
812 /// Unlike `import_table`, this data is serialized as part of incremental
813 /// compilation state.
814 ///
815 /// Key is the hash of the path to this file, used to store
816 /// `InternPool.TrackedInst`.
817 ///
818 /// Value is the `Decl` of the struct that represents this `File`.
819 pub fn getMutableFiles(local: *Local, gpa: Allocator) List(File).Mutable {
820 return .{
821 .gpa = gpa,
822 .arena = &local.mutate.arena,
823 .mutate = &local.mutate.files,
824 .list = &local.shared.files,
825 };
826 }
827
828 /// Some types such as enums, structs, and unions need to store mappings from field names
829 /// to field index, or value to field index. In such cases, they will store the underlying
830 /// field names and values directly, relying on one of these maps, stored separately,
831 /// to provide lookup.
832 /// These are not serialized; it is computed upon deserialization.
833 pub fn getMutableMaps(local: *Local, gpa: Allocator) Maps.Mutable {
834 return .{
835 .gpa = gpa,
836 .arena = &local.mutate.arena,
837 .mutate = &local.mutate.maps,
838 .list = &local.shared.maps,
839 };
840 }
841
680 /// Rather than allocating Decl objects with an Allocator, we instead allocate842 /// Rather than allocating Decl objects with an Allocator, we instead allocate
681 /// them with this BucketList. This provides four advantages:843 /// them with this BucketList. This provides four advantages:
682 /// * Stable memory so that one thread can access a Decl object while another844 /// * Stable memory so that one thread can access a Decl object while another
...@@ -687,7 +849,7 @@ const Local = struct {...@@ -687,7 +849,7 @@ const Local = struct {
687 /// serialization trivial.849 /// serialization trivial.
688 /// * It provides a unique integer to be used for anonymous symbol names, avoiding850 /// * It provides a unique integer to be used for anonymous symbol names, avoiding
689 /// multi-threaded contention on an atomic counter.851 /// multi-threaded contention on an atomic counter.
690 pub fn getMutableDecls(local: *Local, gpa: std.mem.Allocator) Decls.Mutable {852 pub fn getMutableDecls(local: *Local, gpa: Allocator) Decls.Mutable {
691 return .{853 return .{
692 .gpa = gpa,854 .gpa = gpa,
693 .arena = &local.mutate.arena,855 .arena = &local.mutate.arena,
...@@ -697,7 +859,7 @@ const Local = struct {...@@ -697,7 +859,7 @@ const Local = struct {
697 }859 }
698860
699 /// Same pattern as with `getMutableDecls`.861 /// Same pattern as with `getMutableDecls`.
700 pub fn getMutableNamespaces(local: *Local, gpa: std.mem.Allocator) Namespaces.Mutable {862 pub fn getMutableNamespaces(local: *Local, gpa: Allocator) Namespaces.Mutable {
701 return .{863 return .{
702 .gpa = gpa,864 .gpa = gpa,
703 .arena = &local.mutate.arena,865 .arena = &local.mutate.arena,
...@@ -719,11 +881,13 @@ const Shard = struct {...@@ -719,11 +881,13 @@ const Shard = struct {
719 shared: struct {881 shared: struct {
720 map: Map(Index),882 map: Map(Index),
721 string_map: Map(OptionalNullTerminatedString),883 string_map: Map(OptionalNullTerminatedString),
884 tracked_inst_map: Map(TrackedInst.Index.Optional),
722 } align(std.atomic.cache_line),885 } align(std.atomic.cache_line),
723 mutate: struct {886 mutate: struct {
724 // TODO: measure cost of sharing unrelated mutate state887 // TODO: measure cost of sharing unrelated mutate state
725 map: Mutate align(std.atomic.cache_line),888 map: Mutate align(std.atomic.cache_line),
726 string_map: Mutate align(std.atomic.cache_line),889 string_map: Mutate align(std.atomic.cache_line),
890 tracked_inst_map: Mutate align(std.atomic.cache_line),
727 },891 },
728892
729 const Mutate = struct {893 const Mutate = struct {
...@@ -812,8 +976,6 @@ const Hash = std.hash.Wyhash;...@@ -812,8 +976,6 @@ const Hash = std.hash.Wyhash;
812976
813const InternPool = @This();977const InternPool = @This();
814const Zcu = @import("Zcu.zig");978const Zcu = @import("Zcu.zig");
815/// Deprecated.
816const Module = Zcu;
817const Zir = std.zig.Zir;979const Zir = std.zig.Zir;
818980
819/// An index into `maps` which might be `none`.981/// An index into `maps` which might be `none`.
...@@ -831,9 +993,37 @@ pub const OptionalMapIndex = enum(u32) {...@@ -831,9 +993,37 @@ pub const OptionalMapIndex = enum(u32) {
831pub const MapIndex = enum(u32) {993pub const MapIndex = enum(u32) {
832 _,994 _,
833995
996 pub fn get(map_index: MapIndex, ip: *InternPool) *FieldMap {
997 const unwrapped_map_index = map_index.unwrap(ip);
998 const maps = ip.getLocalShared(unwrapped_map_index.tid).maps.acquire();
999 return &maps.view().items(.@"0")[unwrapped_map_index.index];
1000 }
1001
1002 pub fn getConst(map_index: MapIndex, ip: *const InternPool) FieldMap {
1003 return map_index.get(@constCast(ip)).*;
1004 }
1005
834 pub fn toOptional(i: MapIndex) OptionalMapIndex {1006 pub fn toOptional(i: MapIndex) OptionalMapIndex {
835 return @enumFromInt(@intFromEnum(i));1007 return @enumFromInt(@intFromEnum(i));
836 }1008 }
1009
1010 const Unwrapped = struct {
1011 tid: Zcu.PerThread.Id,
1012 index: u32,
1013
1014 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) MapIndex {
1015 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
1016 assert(unwrapped.index <= ip.getIndexMask(u32));
1017 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1018 unwrapped.index);
1019 }
1020 };
1021 fn unwrap(map_index: MapIndex, ip: *const InternPool) Unwrapped {
1022 return .{
1023 .tid = @enumFromInt(@intFromEnum(map_index) >> ip.tid_shift_32 & ip.getTidMask()),
1024 .index = @intFromEnum(map_index) & ip.getIndexMask(u32),
1025 };
1026 }
837};1027};
8381028
839pub const RuntimeIndex = enum(u32) {1029pub const RuntimeIndex = enum(u32) {
...@@ -938,6 +1128,34 @@ pub const OptionalNamespaceIndex = enum(u32) {...@@ -938,6 +1128,34 @@ pub const OptionalNamespaceIndex = enum(u32) {
938 }1128 }
939};1129};
9401130
1131pub const FileIndex = enum(u32) {
1132 _,
1133
1134 const Unwrapped = struct {
1135 tid: Zcu.PerThread.Id,
1136 index: u32,
1137
1138 fn wrap(unwrapped: Unwrapped, ip: *const InternPool) FileIndex {
1139 assert(@intFromEnum(unwrapped.tid) <= ip.getTidMask());
1140 assert(unwrapped.index <= ip.getIndexMask(u32));
1141 return @enumFromInt(@as(u32, @intFromEnum(unwrapped.tid)) << ip.tid_shift_32 |
1142 unwrapped.index);
1143 }
1144 };
1145 pub fn unwrap(file_index: FileIndex, ip: *const InternPool) Unwrapped {
1146 return .{
1147 .tid = @enumFromInt(@intFromEnum(file_index) >> ip.tid_shift_32 & ip.getTidMask()),
1148 .index = @intFromEnum(file_index) & ip.getIndexMask(u32),
1149 };
1150 }
1151};
1152
1153const File = struct {
1154 bin_digest: Cache.BinDigest,
1155 file: *Zcu.File,
1156 root_decl: OptionalDeclIndex,
1157};
1158
941/// An index into `strings`.1159/// An index into `strings`.
942pub const String = enum(u32) {1160pub const String = enum(u32) {
943 /// An empty string.1161 /// An empty string.
...@@ -1240,7 +1458,7 @@ pub const Key = union(enum) {...@@ -1240,7 +1458,7 @@ pub const Key = union(enum) {
12401458
1241 /// Look up field index based on field name.1459 /// Look up field index based on field name.
1242 pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 {1460 pub fn nameIndex(self: ErrorSetType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
1243 const map = &ip.maps.items[@intFromEnum(self.names_map.unwrap().?)];1461 const map = self.names_map.unwrap().?.getConst(ip);
1244 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };1462 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };
1245 const field_index = map.getIndexAdapted(name, adapter) orelse return null;1463 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
1246 return @intCast(field_index);1464 return @intCast(field_index);
...@@ -2665,7 +2883,7 @@ pub const LoadedStructType = struct {...@@ -2665,7 +2883,7 @@ pub const LoadedStructType = struct {
2665 if (i >= self.field_types.len) return null;2883 if (i >= self.field_types.len) return null;
2666 return i;2884 return i;
2667 };2885 };
2668 const map = &ip.maps.items[@intFromEnum(names_map)];2886 const map = names_map.getConst(ip);
2669 const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) };2887 const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) };
2670 const field_index = map.getIndexAdapted(name, adapter) orelse return null;2888 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
2671 return @intCast(field_index);2889 return @intCast(field_index);
...@@ -2783,20 +3001,25 @@ pub const LoadedStructType = struct {...@@ -2783,20 +3001,25 @@ pub const LoadedStructType = struct {
2783 }3001 }
27843002
2785 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {3003 pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool {
2786 switch (s.layout) {3004 const local = ip.getLocal(s.tid);
2787 .@"packed" => {3005 local.mutate.extra.mutex.lock();
2788 const flag = &s.packedFlagsPtr(ip).field_inits_wip;3006 defer local.mutate.extra.mutex.unlock();
2789 if (flag.*) return true;3007 return switch (s.layout) {
2790 flag.* = true;3008 .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw(
2791 return false;3009 u32,
2792 },3010 @as(*u32, @ptrCast(s.packedFlagsPtr(ip))),
2793 .auto, .@"extern" => {3011 .Or,
2794 const flag = &s.flagsPtr(ip).field_inits_wip;3012 @bitCast(Tag.TypeStructPacked.Flags{ .field_inits_wip = true }),
2795 if (flag.*) return true;3013 .acq_rel,
2796 flag.* = true;3014 ))).field_inits_wip,
2797 return false;3015 .auto, .@"extern" => @as(Tag.TypeStruct.Flags, @bitCast(@atomicRmw(
2798 },3016 u32,
2799 }3017 @as(*u32, @ptrCast(s.flagsPtr(ip))),
3018 .Or,
3019 @bitCast(Tag.TypeStruct.Flags{ .field_inits_wip = true }),
3020 .acq_rel,
3021 ))).field_inits_wip,
3022 };
2800 }3023 }
28013024
2802 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void {3025 pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void {
...@@ -2962,6 +3185,7 @@ pub const LoadedStructType = struct {...@@ -2962,6 +3185,7 @@ pub const LoadedStructType = struct {
2962pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {3185pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2963 const unwrapped_index = index.unwrap(ip);3186 const unwrapped_index = index.unwrap(ip);
2964 const extra_list = unwrapped_index.getExtra(ip);3187 const extra_list = unwrapped_index.getExtra(ip);
3188 const extra_items = extra_list.view().items(.@"0");
2965 const item = unwrapped_index.getItem(ip);3189 const item = unwrapped_index.getItem(ip);
2966 switch (item.tag) {3190 switch (item.tag) {
2967 .type_struct => {3191 .type_struct => {
...@@ -2982,10 +3206,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2982,10 +3206,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2982 .names_map = .none,3206 .names_map = .none,
2983 .captures = CaptureValue.Slice.empty,3207 .captures = CaptureValue.Slice.empty,
2984 };3208 };
2985 const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data);3209 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]);
2986 const fields_len = extra.data.fields_len;3210 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
2987 var extra_index = extra.end;3211 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?];
2988 const captures_len = if (extra.data.flags.any_captures) c: {3212 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));
3213 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
3214 const captures_len = if (flags.any_captures) c: {
2989 const len = extra_list.view().items(.@"0")[extra_index];3215 const len = extra_list.view().items(.@"0")[extra_index];
2990 extra_index += 1;3216 extra_index += 1;
2991 break :c len;3217 break :c len;
...@@ -2996,7 +3222,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -2996,7 +3222,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
2996 .len = captures_len,3222 .len = captures_len,
2997 };3223 };
2998 extra_index += captures_len;3224 extra_index += captures_len;
2999 if (extra.data.flags.is_reified) {3225 if (flags.is_reified) {
3000 extra_index += 2; // PackedU643226 extra_index += 2; // PackedU64
3001 }3227 }
3002 const field_types: Index.Slice = .{3228 const field_types: Index.Slice = .{
...@@ -3005,7 +3231,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3005,7 +3231,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3005 .len = fields_len,3231 .len = fields_len,
3006 };3232 };
3007 extra_index += fields_len;3233 extra_index += fields_len;
3008 const names_map: OptionalMapIndex, const names = if (!extra.data.flags.is_tuple) n: {3234 const names_map: OptionalMapIndex, const names = if (!flags.is_tuple) n: {
3009 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);3235 const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
3010 extra_index += 1;3236 extra_index += 1;
3011 const names: NullTerminatedString.Slice = .{3237 const names: NullTerminatedString.Slice = .{
...@@ -3016,7 +3242,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3016,7 +3242,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3016 extra_index += fields_len;3242 extra_index += fields_len;
3017 break :n .{ names_map, names };3243 break :n .{ names_map, names };
3018 } else .{ .none, NullTerminatedString.Slice.empty };3244 } else .{ .none, NullTerminatedString.Slice.empty };
3019 const inits: Index.Slice = if (extra.data.flags.any_default_inits) i: {3245 const inits: Index.Slice = if (flags.any_default_inits) i: {
3020 const inits: Index.Slice = .{3246 const inits: Index.Slice = .{
3021 .tid = unwrapped_index.tid,3247 .tid = unwrapped_index.tid,
3022 .start = extra_index,3248 .start = extra_index,
...@@ -3025,12 +3251,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3025,12 +3251,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3025 extra_index += fields_len;3251 extra_index += fields_len;
3026 break :i inits;3252 break :i inits;
3027 } else Index.Slice.empty;3253 } else Index.Slice.empty;
3028 const namespace: OptionalNamespaceIndex = if (extra.data.flags.has_namespace) n: {3254 const namespace: OptionalNamespaceIndex = if (flags.has_namespace) n: {
3029 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);3255 const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]);
3030 extra_index += 1;3256 extra_index += 1;
3031 break :n n.toOptional();3257 break :n n.toOptional();
3032 } else .none;3258 } else .none;
3033 const aligns: Alignment.Slice = if (extra.data.flags.any_aligned_fields) a: {3259 const aligns: Alignment.Slice = if (flags.any_aligned_fields) a: {
3034 const a: Alignment.Slice = .{3260 const a: Alignment.Slice = .{
3035 .tid = unwrapped_index.tid,3261 .tid = unwrapped_index.tid,
3036 .start = extra_index,3262 .start = extra_index,
...@@ -3039,7 +3265,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3039,7 +3265,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3039 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;3265 extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable;
3040 break :a a;3266 break :a a;
3041 } else Alignment.Slice.empty;3267 } else Alignment.Slice.empty;
3042 const comptime_bits: LoadedStructType.ComptimeBits = if (extra.data.flags.any_comptime_fields) c: {3268 const comptime_bits: LoadedStructType.ComptimeBits = if (flags.any_comptime_fields) c: {
3043 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;3269 const len = std.math.divCeil(u32, fields_len, 32) catch unreachable;
3044 const c: LoadedStructType.ComptimeBits = .{3270 const c: LoadedStructType.ComptimeBits = .{
3045 .tid = unwrapped_index.tid,3271 .tid = unwrapped_index.tid,
...@@ -3049,7 +3275,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3049,7 +3275,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3049 extra_index += len;3275 extra_index += len;
3050 break :c c;3276 break :c c;
3051 } else LoadedStructType.ComptimeBits.empty;3277 } else LoadedStructType.ComptimeBits.empty;
3052 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!extra.data.flags.is_extern) ro: {3278 const runtime_order: LoadedStructType.RuntimeOrder.Slice = if (!flags.is_extern) ro: {
3053 const ro: LoadedStructType.RuntimeOrder.Slice = .{3279 const ro: LoadedStructType.RuntimeOrder.Slice = .{
3054 .tid = unwrapped_index.tid,3280 .tid = unwrapped_index.tid,
3055 .start = extra_index,3281 .start = extra_index,
...@@ -3070,10 +3296,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3070,10 +3296,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3070 return .{3296 return .{
3071 .tid = unwrapped_index.tid,3297 .tid = unwrapped_index.tid,
3072 .extra_index = item.data,3298 .extra_index = item.data,
3073 .decl = extra.data.decl.toOptional(),3299 .decl = decl.toOptional(),
3074 .namespace = namespace,3300 .namespace = namespace,
3075 .zir_index = extra.data.zir_index.toOptional(),3301 .zir_index = zir_index.toOptional(),
3076 .layout = if (extra.data.flags.is_extern) .@"extern" else .auto,3302 .layout = if (flags.is_extern) .@"extern" else .auto,
3077 .field_names = names,3303 .field_names = names,
3078 .field_types = field_types,3304 .field_types = field_types,
3079 .field_inits = inits,3305 .field_inits = inits,
...@@ -3086,11 +3312,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3086,11 +3312,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3086 };3312 };
3087 },3313 },
3088 .type_struct_packed, .type_struct_packed_inits => {3314 .type_struct_packed, .type_struct_packed_inits => {
3089 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, item.data);3315 const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "decl").?]);
3316 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
3317 const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "fields_len").?];
3318 const namespace: OptionalNamespaceIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "namespace").?]);
3319 const names_map: MapIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "names_map").?]);
3320 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));
3321 var extra_index = item.data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
3090 const has_inits = item.tag == .type_struct_packed_inits;3322 const has_inits = item.tag == .type_struct_packed_inits;
3091 const fields_len = extra.data.fields_len;3323 const captures_len = if (flags.any_captures) c: {
3092 var extra_index = extra.end;
3093 const captures_len = if (extra.data.flags.any_captures) c: {
3094 const len = extra_list.view().items(.@"0")[extra_index];3324 const len = extra_list.view().items(.@"0")[extra_index];
3095 extra_index += 1;3325 extra_index += 1;
3096 break :c len;3326 break :c len;
...@@ -3101,7 +3331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3101,7 +3331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3101 .len = captures_len,3331 .len = captures_len,
3102 };3332 };
3103 extra_index += captures_len;3333 extra_index += captures_len;
3104 if (extra.data.flags.is_reified) {3334 if (flags.is_reified) {
3105 extra_index += 2; // PackedU643335 extra_index += 2; // PackedU64
3106 }3336 }
3107 const field_types: Index.Slice = .{3337 const field_types: Index.Slice = .{
...@@ -3128,9 +3358,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3128,9 +3358,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3128 return .{3358 return .{
3129 .tid = unwrapped_index.tid,3359 .tid = unwrapped_index.tid,
3130 .extra_index = item.data,3360 .extra_index = item.data,
3131 .decl = extra.data.decl.toOptional(),3361 .decl = decl.toOptional(),
3132 .namespace = extra.data.namespace,3362 .namespace = namespace,
3133 .zir_index = extra.data.zir_index.toOptional(),3363 .zir_index = zir_index.toOptional(),
3134 .layout = .@"packed",3364 .layout = .@"packed",
3135 .field_names = field_names,3365 .field_names = field_names,
3136 .field_types = field_types,3366 .field_types = field_types,
...@@ -3139,7 +3369,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {...@@ -3139,7 +3369,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType {
3139 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,3369 .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty,
3140 .comptime_bits = LoadedStructType.ComptimeBits.empty,3370 .comptime_bits = LoadedStructType.ComptimeBits.empty,
3141 .offsets = LoadedStructType.Offsets.empty,3371 .offsets = LoadedStructType.Offsets.empty,
3142 .names_map = extra.data.names_map.toOptional(),3372 .names_map = names_map.toOptional(),
3143 .captures = captures,3373 .captures = captures,
3144 };3374 };
3145 },3375 },
...@@ -3183,7 +3413,7 @@ const LoadedEnumType = struct {...@@ -3183,7 +3413,7 @@ const LoadedEnumType = struct {
31833413
3184 /// Look up field index based on field name.3414 /// Look up field index based on field name.
3185 pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {3415 pub fn nameIndex(self: LoadedEnumType, ip: *const InternPool, name: NullTerminatedString) ?u32 {
3186 const map = &ip.maps.items[@intFromEnum(self.names_map)];3416 const map = self.names_map.getConst(ip);
3187 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };3417 const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) };
3188 const field_index = map.getIndexAdapted(name, adapter) orelse return null;3418 const field_index = map.getIndexAdapted(name, adapter) orelse return null;
3189 return @intCast(field_index);3419 return @intCast(field_index);
...@@ -3203,7 +3433,7 @@ const LoadedEnumType = struct {...@@ -3203,7 +3433,7 @@ const LoadedEnumType = struct {
3203 else => unreachable,3433 else => unreachable,
3204 };3434 };
3205 if (self.values_map.unwrap()) |values_map| {3435 if (self.values_map.unwrap()) |values_map| {
3206 const map = &ip.maps.items[@intFromEnum(values_map)];3436 const map = values_map.getConst(ip);
3207 const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) };3437 const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) };
3208 const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null;3438 const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null;
3209 return @intCast(field_index);3439 return @intCast(field_index);
...@@ -4476,11 +4706,11 @@ pub const Tag = enum(u8) {...@@ -4476,11 +4706,11 @@ pub const Tag = enum(u8) {
4476 flags: Flags,4706 flags: Flags,
44774707
4478 pub const Flags = packed struct(u32) {4708 pub const Flags = packed struct(u32) {
4479 any_captures: bool,4709 any_captures: bool = false,
4480 /// Dependency loop detection when resolving field inits.4710 /// Dependency loop detection when resolving field inits.
4481 field_inits_wip: bool,4711 field_inits_wip: bool = false,
4482 inits_resolved: bool,4712 inits_resolved: bool = false,
4483 is_reified: bool,4713 is_reified: bool = false,
4484 _: u28 = 0,4714 _: u28 = 0,
4485 };4715 };
4486 };4716 };
...@@ -4526,36 +4756,36 @@ pub const Tag = enum(u8) {...@@ -4526,36 +4756,36 @@ pub const Tag = enum(u8) {
4526 size: u32,4756 size: u32,
45274757
4528 pub const Flags = packed struct(u32) {4758 pub const Flags = packed struct(u32) {
4529 any_captures: bool,4759 any_captures: bool = false,
4530 is_extern: bool,4760 is_extern: bool = false,
4531 known_non_opv: bool,4761 known_non_opv: bool = false,
4532 requires_comptime: RequiresComptime,4762 requires_comptime: RequiresComptime = @enumFromInt(0),
4533 is_tuple: bool,4763 is_tuple: bool = false,
4534 assumed_runtime_bits: bool,4764 assumed_runtime_bits: bool = false,
4535 assumed_pointer_aligned: bool,4765 assumed_pointer_aligned: bool = false,
4536 has_namespace: bool,4766 has_namespace: bool = false,
4537 any_comptime_fields: bool,4767 any_comptime_fields: bool = false,
4538 any_default_inits: bool,4768 any_default_inits: bool = false,
4539 any_aligned_fields: bool,4769 any_aligned_fields: bool = false,
4540 /// `.none` until layout_resolved4770 /// `.none` until layout_resolved
4541 alignment: Alignment,4771 alignment: Alignment = @enumFromInt(0),
4542 /// Dependency loop detection when resolving struct alignment.4772 /// Dependency loop detection when resolving struct alignment.
4543 alignment_wip: bool,4773 alignment_wip: bool = false,
4544 /// Dependency loop detection when resolving field types.4774 /// Dependency loop detection when resolving field types.
4545 field_types_wip: bool,4775 field_types_wip: bool = false,
4546 /// Dependency loop detection when resolving struct layout.4776 /// Dependency loop detection when resolving struct layout.
4547 layout_wip: bool,4777 layout_wip: bool = false,
4548 /// Indicates whether `size`, `alignment`, runtime field order, and4778 /// Indicates whether `size`, `alignment`, runtime field order, and
4549 /// field offets are populated.4779 /// field offets are populated.
4550 layout_resolved: bool,4780 layout_resolved: bool = false,
4551 /// Dependency loop detection when resolving field inits.4781 /// Dependency loop detection when resolving field inits.
4552 field_inits_wip: bool,4782 field_inits_wip: bool = false,
4553 /// Indicates whether `field_inits` has been resolved.4783 /// Indicates whether `field_inits` has been resolved.
4554 inits_resolved: bool,4784 inits_resolved: bool = false,
4555 // The types and all its fields have had their layout resolved. Even through pointer,4785 // The types and all its fields have had their layout resolved. Even through pointer = false,
4556 // which `layout_resolved` does not ensure.4786 // which `layout_resolved` does not ensure.
4557 fully_resolved: bool,4787 fully_resolved: bool = false,
4558 is_reified: bool,4788 is_reified: bool = false,
4559 _: u6 = 0,4789 _: u6 = 0,
4560 };4790 };
4561 };4791 };
...@@ -4599,12 +4829,12 @@ pub const FuncAnalysis = packed struct(u32) {...@@ -4599,12 +4829,12 @@ pub const FuncAnalysis = packed struct(u32) {
4599 /// inline, which means no runtime version of the function will be generated.4829 /// inline, which means no runtime version of the function will be generated.
4600 inline_only,4830 inline_only,
4601 in_progress,4831 in_progress,
4602 /// There will be a corresponding ErrorMsg in Module.failed_decls4832 /// There will be a corresponding ErrorMsg in Zcu.failed_decls
4603 sema_failure,4833 sema_failure,
4604 /// This function might be OK but it depends on another Decl which did not4834 /// This function might be OK but it depends on another Decl which did not
4605 /// successfully complete semantic analysis.4835 /// successfully complete semantic analysis.
4606 dependency_failure,4836 dependency_failure,
4607 /// There will be a corresponding ErrorMsg in Module.failed_decls.4837 /// There will be a corresponding ErrorMsg in Zcu.failed_decls.
4608 /// Indicates that semantic analysis succeeded, but code generation for4838 /// Indicates that semantic analysis succeeded, but code generation for
4609 /// this function failed.4839 /// this function failed.
4610 codegen_failure,4840 codegen_failure,
...@@ -5201,6 +5431,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5201,6 +5431,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5201 .extra = Local.Extra.empty,5431 .extra = Local.Extra.empty,
5202 .limbs = Local.Limbs.empty,5432 .limbs = Local.Limbs.empty,
5203 .strings = Local.Strings.empty,5433 .strings = Local.Strings.empty,
5434 .tracked_insts = Local.TrackedInsts.empty,
5435 .files = Local.List(File).empty,
5436 .maps = Local.Maps.empty,
52045437
5205 .decls = Local.Decls.empty,5438 .decls = Local.Decls.empty,
5206 .namespaces = Local.Namespaces.empty,5439 .namespaces = Local.Namespaces.empty,
...@@ -5209,9 +5442,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5209,9 +5442,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5209 .arena = .{},5442 .arena = .{},
52105443
5211 .items = Local.ListMutate.empty,5444 .items = Local.ListMutate.empty,
5212 .extra = Local.ListMutate.empty,5445 .extra = Local.MutexListMutate.empty,
5213 .limbs = Local.ListMutate.empty,5446 .limbs = Local.ListMutate.empty,
5214 .strings = Local.ListMutate.empty,5447 .strings = Local.ListMutate.empty,
5448 .tracked_insts = Local.MutexListMutate.empty,
5449 .files = Local.ListMutate.empty,
5450 .maps = Local.ListMutate.empty,
52155451
5216 .decls = Local.BucketListMutate.empty,5452 .decls = Local.BucketListMutate.empty,
5217 .namespaces = Local.BucketListMutate.empty,5453 .namespaces = Local.BucketListMutate.empty,
...@@ -5226,10 +5462,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5226,10 +5462,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5226 .shared = .{5462 .shared = .{
5227 .map = Shard.Map(Index).empty,5463 .map = Shard.Map(Index).empty,
5228 .string_map = Shard.Map(OptionalNullTerminatedString).empty,5464 .string_map = Shard.Map(OptionalNullTerminatedString).empty,
5465 .tracked_inst_map = Shard.Map(TrackedInst.Index.Optional).empty,
5229 },5466 },
5230 .mutate = .{5467 .mutate = .{
5231 .map = Shard.Mutate.empty,5468 .map = Shard.Mutate.empty,
5232 .string_map = Shard.Mutate.empty,5469 .string_map = Shard.Mutate.empty,
5470 .tracked_inst_map = Shard.Mutate.empty,
5233 },5471 },
5234 });5472 });
52355473
...@@ -5267,11 +5505,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {...@@ -5267,11 +5505,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void {
5267}5505}
52685506
5269pub fn deinit(ip: *InternPool, gpa: Allocator) void {5507pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5270 for (ip.maps.items) |*map| map.deinit(gpa);
5271 ip.maps.deinit(gpa);
5272
5273 ip.tracked_insts.deinit(gpa);
5274
5275 ip.src_hash_deps.deinit(gpa);5508 ip.src_hash_deps.deinit(gpa);
5276 ip.decl_val_deps.deinit(gpa);5509 ip.decl_val_deps.deinit(gpa);
5277 ip.func_ies_deps.deinit(gpa);5510 ip.func_ies_deps.deinit(gpa);
...@@ -5283,8 +5516,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -5283,8 +5516,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5283 ip.dep_entries.deinit(gpa);5516 ip.dep_entries.deinit(gpa);
5284 ip.free_dep_entries.deinit(gpa);5517 ip.free_dep_entries.deinit(gpa);
52855518
5286 ip.files.deinit(gpa);
5287
5288 gpa.free(ip.shards);5519 gpa.free(ip.shards);
5289 for (ip.locals) |*local| {5520 for (ip.locals) |*local| {
5290 const buckets_len = local.mutate.namespaces.buckets_list.len;5521 const buckets_len = local.mutate.namespaces.buckets_list.len;
...@@ -5301,6 +5532,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {...@@ -5301,6 +5532,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void {
5301 namespace.usingnamespace_set.deinit(gpa);5532 namespace.usingnamespace_set.deinit(gpa);
5302 }5533 }
5303 };5534 };
5535 const maps = local.getMutableMaps(gpa);
5536 if (maps.mutate.len > 0) for (maps.view().items(.@"0")) |*map| map.deinit(gpa);
5304 local.mutate.arena.promote(gpa).deinit();5537 local.mutate.arena.promote(gpa).deinit();
5305 }5538 }
5306 gpa.free(ip.locals);5539 gpa.free(ip.locals);
...@@ -5400,40 +5633,46 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {...@@ -5400,40 +5633,46 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key {
5400 .type_struct => .{ .struct_type = ns: {5633 .type_struct => .{ .struct_type = ns: {
5401 if (data == 0) break :ns .empty_struct;5634 if (data == 0) break :ns .empty_struct;
5402 const extra_list = unwrapped_index.getExtra(ip);5635 const extra_list = unwrapped_index.getExtra(ip);
5403 const extra = extraDataTrail(extra_list, Tag.TypeStruct, data);5636 const extra_items = extra_list.view().items(.@"0");
5404 if (extra.data.flags.is_reified) {5637 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]);
5405 assert(!extra.data.flags.any_captures);5638 const flags: Tag.TypeStruct.Flags = @bitCast(@atomicLoad(u32, &extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "flags").?], .monotonic));
5639 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStruct).Struct.fields.len);
5640 if (flags.is_reified) {
5641 assert(!flags.any_captures);
5406 break :ns .{ .reified = .{5642 break :ns .{ .reified = .{
5407 .zir_index = extra.data.zir_index,5643 .zir_index = zir_index,
5408 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),5644 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
5409 } };5645 } };
5410 }5646 }
5411 break :ns .{ .declared = .{5647 break :ns .{ .declared = .{
5412 .zir_index = extra.data.zir_index,5648 .zir_index = zir_index,
5413 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5649 .captures = .{ .owned = if (flags.any_captures) .{
5414 .tid = unwrapped_index.tid,5650 .tid = unwrapped_index.tid,
5415 .start = extra.end + 1,5651 .start = end_extra_index + 1,
5416 .len = extra_list.view().items(.@"0")[extra.end],5652 .len = extra_list.view().items(.@"0")[end_extra_index],
5417 } else CaptureValue.Slice.empty },5653 } else CaptureValue.Slice.empty },
5418 } };5654 } };
5419 } },5655 } },
54205656
5421 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {5657 .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: {
5422 const extra_list = unwrapped_index.getExtra(ip);5658 const extra_list = unwrapped_index.getExtra(ip);
5423 const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data);5659 const extra_items = extra_list.view().items(.@"0");
5424 if (extra.data.flags.is_reified) {5660 const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]);
5425 assert(!extra.data.flags.any_captures);5661 const flags: Tag.TypeStructPacked.Flags = @bitCast(@atomicLoad(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "flags").?], .monotonic));
5662 const end_extra_index = data + @as(u32, @typeInfo(Tag.TypeStructPacked).Struct.fields.len);
5663 if (flags.is_reified) {
5664 assert(!flags.any_captures);
5426 break :ns .{ .reified = .{5665 break :ns .{ .reified = .{
5427 .zir_index = extra.data.zir_index,5666 .zir_index = zir_index,
5428 .type_hash = extraData(extra_list, PackedU64, extra.end).get(),5667 .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(),
5429 } };5668 } };
5430 }5669 }
5431 break :ns .{ .declared = .{5670 break :ns .{ .declared = .{
5432 .zir_index = extra.data.zir_index,5671 .zir_index = zir_index,
5433 .captures = .{ .owned = if (extra.data.flags.any_captures) .{5672 .captures = .{ .owned = if (flags.any_captures) .{
5434 .tid = unwrapped_index.tid,5673 .tid = unwrapped_index.tid,
5435 .start = extra.end + 1,5674 .start = end_extra_index + 1,
5436 .len = extra_list.view().items(.@"0")[extra.end],5675 .len = extra_items[end_extra_index],
5437 } else CaptureValue.Slice.empty },5676 } else CaptureValue.Slice.empty },
5438 } };5677 } };
5439 } },5678 } },
...@@ -5914,27 +6153,32 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke...@@ -5914,27 +6153,32 @@ fn extraFuncDecl(tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Ke
5914}6153}
59156154
5916fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {6155fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func {
5917 const P = Tag.FuncInstance;6156 const extra_items = extra.view().items(.@"0");
5918 const fi = extraDataTrail(extra, P, extra_index);6157 const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?;
5919 const func_decl = ip.funcDeclInfo(fi.data.generic_owner);6158 const analysis: FuncAnalysis = @bitCast(@atomicLoad(u32, &extra_items[analysis_extra_index], .monotonic));
6159 const owner_decl: DeclIndex = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "owner_decl").?]);
6160 const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]);
6161 const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]);
6162 const func_decl = ip.funcDeclInfo(generic_owner);
6163 const end_extra_index = extra_index + @as(u32, @typeInfo(Tag.FuncInstance).Struct.fields.len);
5920 return .{6164 return .{
5921 .tid = tid,6165 .tid = tid,
5922 .ty = fi.data.ty,6166 .ty = ty,
5923 .uncoerced_ty = fi.data.ty,6167 .uncoerced_ty = ty,
5924 .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?,6168 .analysis_extra_index = analysis_extra_index,
5925 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,6169 .zir_body_inst_extra_index = func_decl.zir_body_inst_extra_index,
5926 .resolved_error_set_extra_index = if (fi.data.analysis.inferred_error_set) fi.end else 0,6170 .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0,
5927 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(P, "branch_quota").?,6171 .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?,
5928 .owner_decl = fi.data.owner_decl,6172 .owner_decl = owner_decl,
5929 .zir_body_inst = func_decl.zir_body_inst,6173 .zir_body_inst = func_decl.zir_body_inst,
5930 .lbrace_line = func_decl.lbrace_line,6174 .lbrace_line = func_decl.lbrace_line,
5931 .rbrace_line = func_decl.rbrace_line,6175 .rbrace_line = func_decl.rbrace_line,
5932 .lbrace_column = func_decl.lbrace_column,6176 .lbrace_column = func_decl.lbrace_column,
5933 .rbrace_column = func_decl.rbrace_column,6177 .rbrace_column = func_decl.rbrace_column,
5934 .generic_owner = fi.data.generic_owner,6178 .generic_owner = generic_owner,
5935 .comptime_args = .{6179 .comptime_args = .{
5936 .tid = tid,6180 .tid = tid,
5937 .start = fi.end + @intFromBool(fi.data.analysis.inferred_error_set),6181 .start = end_extra_index + @intFromBool(analysis.inferred_error_set),
5938 .len = ip.funcTypeParamsLen(func_decl.ty),6182 .len = ip.funcTypeParamsLen(func_decl.ty),
5939 },6183 },
5940 };6184 };
...@@ -6206,8 +6450,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All...@@ -6206,8 +6450,8 @@ pub fn get(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, key: Key) All
6206 assert(error_set_type.names_map == .none);6450 assert(error_set_type.names_map == .none);
6207 assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan));6451 assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan));
6208 const names = error_set_type.names.get(ip);6452 const names = error_set_type.names.get(ip);
6209 const names_map = try ip.addMap(gpa, names.len);6453 const names_map = try ip.addMap(gpa, tid, names.len);
6210 addStringsToMap(ip, names_map, names);6454 ip.addStringsToMap(names_map, names);
6211 const names_len = error_set_type.names.len;6455 const names_len = error_set_type.names.len;
6212 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);6456 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len);
6213 items.appendAssumeCapacity(.{6457 items.appendAssumeCapacity(.{
...@@ -7107,8 +7351,8 @@ pub fn getStructType(...@@ -7107,8 +7351,8 @@ pub fn getStructType(
7107 const items = local.getMutableItems(gpa);7351 const items = local.getMutableItems(gpa);
7108 const extra = local.getMutableExtra(gpa);7352 const extra = local.getMutableExtra(gpa);
71097353
7110 const names_map = try ip.addMap(gpa, ini.fields_len);7354 const names_map = try ip.addMap(gpa, tid, ini.fields_len);
7111 errdefer _ = ip.maps.pop();7355 errdefer local.mutate.maps.len -= 1;
71127356
7113 const zir_index = switch (ini.key) {7357 const zir_index = switch (ini.key) {
7114 inline else => |x| x.zir_index,7358 inline else => |x| x.zir_index,
...@@ -7655,17 +7899,18 @@ pub fn getErrorSetType(...@@ -7655,17 +7899,18 @@ pub fn getErrorSetType(
7655 const extra = local.getMutableExtra(gpa);7899 const extra = local.getMutableExtra(gpa);
7656 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);7900 try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len);
76577901
7902 const names_map = try ip.addMap(gpa, tid, names.len);
7903 errdefer local.mutate.maps.len -= 1;
7904
7658 // The strategy here is to add the type unconditionally, then to ask if it7905 // The strategy here is to add the type unconditionally, then to ask if it
7659 // already exists, and if so, revert the lengths of the mutated arrays.7906 // already exists, and if so, revert the lengths of the mutated arrays.
7660 // This is similar to what `getOrPutTrailingString` does.7907 // This is similar to what `getOrPutTrailingString` does.
7661 const prev_extra_len = extra.mutate.len;7908 const prev_extra_len = extra.mutate.len;
7662 errdefer extra.mutate.len = prev_extra_len;7909 errdefer extra.mutate.len = prev_extra_len;
76637910
7664 const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len);
7665
7666 const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{7911 const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{
7667 .names_len = @intCast(names.len),7912 .names_len = @intCast(names.len),
7668 .names_map = predicted_names_map,7913 .names_map = names_map,
7669 });7914 });
7670 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});7915 extra.appendSliceAssumeCapacity(.{@ptrCast(names)});
7671 errdefer extra.mutate.len = prev_extra_len;7916 errdefer extra.mutate.len = prev_extra_len;
...@@ -7685,11 +7930,7 @@ pub fn getErrorSetType(...@@ -7685,11 +7930,7 @@ pub fn getErrorSetType(
7685 });7930 });
7686 errdefer items.mutate.len -= 1;7931 errdefer items.mutate.len -= 1;
76877932
7688 const names_map = try ip.addMap(gpa, names.len);7933 ip.addStringsToMap(names_map, names);
7689 assert(names_map == predicted_names_map);
7690 errdefer _ = ip.maps.pop();
7691
7692 addStringsToMap(ip, names_map, names);
76937934
7694 return gop.put();7935 return gop.put();
7695}7936}
...@@ -7955,6 +8196,7 @@ fn finishFuncInstance(...@@ -7955,6 +8196,7 @@ fn finishFuncInstance(
7955 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));8196 const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner));
7956 const decl_index = try ip.createDecl(gpa, tid, .{8197 const decl_index = try ip.createDecl(gpa, tid, .{
7957 .name = undefined,8198 .name = undefined,
8199 .fqn = undefined,
7958 .src_namespace = fn_owner_decl.src_namespace,8200 .src_namespace = fn_owner_decl.src_namespace,
7959 .has_tv = true,8201 .has_tv = true,
7960 .owns_tv = true,8202 .owns_tv = true,
...@@ -7980,6 +8222,8 @@ fn finishFuncInstance(...@@ -7980,6 +8222,8 @@ fn finishFuncInstance(
7980 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{8222 decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{
7981 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),8223 fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index),
7982 }, .no_embedded_nulls);8224 }, .no_embedded_nulls);
8225 decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace)
8226 .internFullyQualifiedName(ip, gpa, tid, decl.name);
7983}8227}
79848228
7985pub const EnumTypeInit = struct {8229pub const EnumTypeInit = struct {
...@@ -8052,7 +8296,7 @@ pub const WipEnumType = struct {...@@ -8052,7 +8296,7 @@ pub const WipEnumType = struct {
8052 return null;8296 return null;
8053 }8297 }
8054 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));8298 assert(ip.typeOf(value) == @as(Index, @enumFromInt(extra_items[wip.tag_ty_index])));
8055 const map = &ip.maps.items[@intFromEnum(wip.values_map.unwrap().?)];8299 const map = wip.values_map.unwrap().?.get(ip);
8056 const field_index = map.count();8300 const field_index = map.count();
8057 const indexes = extra_items[wip.values_start..][0..field_index];8301 const indexes = extra_items[wip.values_start..][0..field_index];
8058 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };8302 const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) };
...@@ -8098,8 +8342,8 @@ pub fn getEnumType(...@@ -8098,8 +8342,8 @@ pub fn getEnumType(
8098 try items.ensureUnusedCapacity(1);8342 try items.ensureUnusedCapacity(1);
8099 const extra = local.getMutableExtra(gpa);8343 const extra = local.getMutableExtra(gpa);
81008344
8101 const names_map = try ip.addMap(gpa, ini.fields_len);8345 const names_map = try ip.addMap(gpa, tid, ini.fields_len);
8102 errdefer _ = ip.maps.pop();8346 errdefer local.mutate.maps.len -= 1;
81038347
8104 switch (ini.tag_mode) {8348 switch (ini.tag_mode) {
8105 .auto => {8349 .auto => {
...@@ -8152,11 +8396,11 @@ pub fn getEnumType(...@@ -8152,11 +8396,11 @@ pub fn getEnumType(
8152 },8396 },
8153 .explicit, .nonexhaustive => {8397 .explicit, .nonexhaustive => {
8154 const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: {8398 const values_map: OptionalMapIndex = if (!ini.has_values) .none else m: {
8155 const values_map = try ip.addMap(gpa, ini.fields_len);8399 const values_map = try ip.addMap(gpa, tid, ini.fields_len);
8156 break :m values_map.toOptional();8400 break :m values_map.toOptional();
8157 };8401 };
8158 errdefer if (ini.has_values) {8402 errdefer if (ini.has_values) {
8159 _ = ip.maps.pop();8403 local.mutate.maps.len -= 1;
8160 };8404 };
81618405
8162 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +8406 try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len +
...@@ -8245,8 +8489,8 @@ pub fn getGeneratedTagEnumType(...@@ -8245,8 +8489,8 @@ pub fn getGeneratedTagEnumType(
8245 try items.ensureUnusedCapacity(1);8489 try items.ensureUnusedCapacity(1);
8246 const extra = local.getMutableExtra(gpa);8490 const extra = local.getMutableExtra(gpa);
82478491
8248 const names_map = try ip.addMap(gpa, ini.names.len);8492 const names_map = try ip.addMap(gpa, tid, ini.names.len);
8249 errdefer _ = ip.maps.pop();8493 errdefer local.mutate.maps.len -= 1;
8250 ip.addStringsToMap(names_map, ini.names);8494 ip.addStringsToMap(names_map, ini.names);
82518495
8252 const fields_len: u32 = @intCast(ini.names.len);8496 const fields_len: u32 = @intCast(ini.names.len);
...@@ -8279,8 +8523,8 @@ pub fn getGeneratedTagEnumType(...@@ -8279,8 +8523,8 @@ pub fn getGeneratedTagEnumType(
8279 ini.values.len); // field values8523 ini.values.len); // field values
82808524
8281 const values_map: OptionalMapIndex = if (ini.values.len != 0) m: {8525 const values_map: OptionalMapIndex = if (ini.values.len != 0) m: {
8282 const map = try ip.addMap(gpa, ini.values.len);8526 const map = try ip.addMap(gpa, tid, ini.values.len);
8283 addIndexesToMap(ip, map, ini.values);8527 ip.addIndexesToMap(map, ini.values);
8284 break :m map.toOptional();8528 break :m map.toOptional();
8285 } else .none;8529 } else .none;
8286 // We don't clean up the values map on error!8530 // We don't clean up the values map on error!
...@@ -8311,7 +8555,9 @@ pub fn getGeneratedTagEnumType(...@@ -8311,7 +8555,9 @@ pub fn getGeneratedTagEnumType(
8311 errdefer extra.mutate.len = prev_extra_len;8555 errdefer extra.mutate.len = prev_extra_len;
8312 errdefer switch (ini.tag_mode) {8556 errdefer switch (ini.tag_mode) {
8313 .auto => {},8557 .auto => {},
8314 .explicit, .nonexhaustive => _ = if (ini.values.len != 0) ip.maps.pop(),8558 .explicit, .nonexhaustive => if (ini.values.len != 0) {
8559 local.mutate.maps.len -= 1;
8560 },
8315 };8561 };
83168562
8317 var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{8563 var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{
...@@ -8415,7 +8661,7 @@ fn addStringsToMap(...@@ -8415,7 +8661,7 @@ fn addStringsToMap(
8415 map_index: MapIndex,8661 map_index: MapIndex,
8416 strings: []const NullTerminatedString,8662 strings: []const NullTerminatedString,
8417) void {8663) void {
8418 const map = &ip.maps.items[@intFromEnum(map_index)];8664 const map = map_index.get(ip);
8419 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };8665 const adapter: NullTerminatedString.Adapter = .{ .strings = strings };
8420 for (strings) |string| {8666 for (strings) |string| {
8421 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);8667 const gop = map.getOrPutAssumeCapacityAdapted(string, adapter);
...@@ -8428,7 +8674,7 @@ fn addIndexesToMap(...@@ -8428,7 +8674,7 @@ fn addIndexesToMap(
8428 map_index: MapIndex,8674 map_index: MapIndex,
8429 indexes: []const Index,8675 indexes: []const Index,
8430) void {8676) void {
8431 const map = &ip.maps.items[@intFromEnum(map_index)];8677 const map = map_index.get(ip);
8432 const adapter: Index.Adapter = .{ .indexes = indexes };8678 const adapter: Index.Adapter = .{ .indexes = indexes };
8433 for (indexes) |index| {8679 for (indexes) |index| {
8434 const gop = map.getOrPutAssumeCapacityAdapted(index, adapter);8680 const gop = map.getOrPutAssumeCapacityAdapted(index, adapter);
...@@ -8436,12 +8682,14 @@ fn addIndexesToMap(...@@ -8436,12 +8682,14 @@ fn addIndexesToMap(
8436 }8682 }
8437}8683}
84388684
8439fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex {8685fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Allocator.Error!MapIndex {
8440 const ptr = try ip.maps.addOne(gpa);8686 const maps = ip.getLocal(tid).getMutableMaps(gpa);
8441 errdefer _ = ip.maps.pop();8687 const unwrapped: MapIndex.Unwrapped = .{ .tid = tid, .index = maps.mutate.len };
8442 ptr.* = .{};8688 const ptr = try maps.addOne();
8443 try ptr.ensureTotalCapacity(gpa, cap);8689 errdefer maps.mutate.len = unwrapped.index;
8444 return @enumFromInt(ip.maps.items.len - 1);8690 ptr[0].* = .{};
8691 try ptr[0].ensureTotalCapacity(gpa, cap);
8692 return unwrapped.wrap(ip);
8445}8693}
84468694
8447/// This operation only happens under compile error conditions.8695/// This operation only happens under compile error conditions.
...@@ -9167,10 +9415,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {...@@ -9167,10 +9415,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index {
9167/// The is only legal because the initializer is not part of the hash.9415/// The is only legal because the initializer is not part of the hash.
9168pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {9416pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void {
9169 const unwrapped_index = index.unwrap(ip);9417 const unwrapped_index = index.unwrap(ip);
9170 const extra_list = unwrapped_index.getExtra(ip);9418 const local = ip.getLocal(unwrapped_index.tid);
9419 local.mutate.extra.mutex.lock();
9420 defer local.mutate.extra.mutex.unlock();
9421 const extra_items = local.shared.extra.view().items(.@"0");
9171 const item = unwrapped_index.getItem(ip);9422 const item = unwrapped_index.getItem(ip);
9172 assert(item.tag == .variable);9423 assert(item.tag == .variable);
9173 @atomicStore(u32, &extra_list.view().items(.@"0")[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);9424 @atomicStore(u32, &extra_items[item.data + std.meta.fieldIndex(Tag.Variable, "init").?], @intFromEnum(init_index), .release);
9174}9425}
91759426
9176pub fn dump(ip: *const InternPool) void {9427pub fn dump(ip: *const InternPool) void {
...@@ -9185,14 +9436,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {...@@ -9185,14 +9436,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void {
9185 var decls_len: usize = 0;9436 var decls_len: usize = 0;
9186 for (ip.locals) |*local| {9437 for (ip.locals) |*local| {
9187 items_len += local.mutate.items.len;9438 items_len += local.mutate.items.len;
9188 extra_len += local.mutate.extra.len;9439 extra_len += local.mutate.extra.list.len;
9189 limbs_len += local.mutate.limbs.len;9440 limbs_len += local.mutate.limbs.len;
9190 decls_len += local.mutate.decls.buckets_list.len;9441 decls_len += local.mutate.decls.buckets_list.len;
9191 }9442 }
9192 const items_size = (1 + 4) * items_len;9443 const items_size = (1 + 4) * items_len;
9193 const extra_size = 4 * extra_len;9444 const extra_size = 4 * extra_len;
9194 const limbs_size = 8 * limbs_len;9445 const limbs_size = 8 * limbs_len;
9195 const decls_size = @sizeOf(Module.Decl) * decls_len;9446 const decls_size = @sizeOf(Zcu.Decl) * decls_len;
91969447
9197 // TODO: map overhead size is not taken into account9448 // TODO: map overhead size is not taken into account
9198 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;9449 const total_size = @sizeOf(InternPool) + items_size + extra_size + limbs_size + decls_size;
...@@ -9619,29 +9870,22 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)...@@ -9619,29 +9870,22 @@ pub fn dumpGenericInstancesFallible(ip: *const InternPool, allocator: Allocator)
9619 try bw.flush();9870 try bw.flush();
9620}9871}
96219872
9622pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Module.Decl {9873pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl {
9623 return @constCast(ip.declPtrConst(decl_index));9874 return @constCast(ip.declPtrConst(decl_index));
9624}9875}
96259876
9626pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Module.Decl {9877pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl {
9627 const unwrapped_decl_index = decl_index.unwrap(ip);9878 const unwrapped_decl_index = decl_index.unwrap(ip);
9628 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();9879 const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire();
9629 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];9880 const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index];
9630 return &decls_bucket[unwrapped_decl_index.index];9881 return &decls_bucket[unwrapped_decl_index.index];
9631}9882}
96329883
9633pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Module.Namespace {
9634 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9635 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9636 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9637 return &namespaces_bucket[unwrapped_namespace_index.index];
9638}
9639
9640pub fn createDecl(9884pub fn createDecl(
9641 ip: *InternPool,9885 ip: *InternPool,
9642 gpa: Allocator,9886 gpa: Allocator,
9643 tid: Zcu.PerThread.Id,9887 tid: Zcu.PerThread.Id,
9644 initialization: Module.Decl,9888 initialization: Zcu.Decl,
9645) Allocator.Error!DeclIndex {9889) Allocator.Error!DeclIndex {
9646 const local = ip.getLocal(tid);9890 const local = ip.getLocal(tid);
9647 const free_list_next = local.mutate.decls.free_list;9891 const free_list_next = local.mutate.decls.free_list;
...@@ -9658,7 +9902,7 @@ pub fn createDecl(...@@ -9658,7 +9902,7 @@ pub fn createDecl(
9658 var arena = decls.arena.promote(decls.gpa);9902 var arena = decls.arena.promote(decls.gpa);
9659 defer decls.arena.* = arena.state;9903 defer decls.arena.* = arena.state;
9660 decls.appendAssumeCapacity(.{try arena.allocator().create(9904 decls.appendAssumeCapacity(.{try arena.allocator().create(
9661 [1 << Local.decls_bucket_width]Module.Decl,9905 [1 << Local.decls_bucket_width]Zcu.Decl,
9662 )});9906 )});
9663 }9907 }
9664 const unwrapped_decl_index: DeclIndex.Unwrapped = .{9908 const unwrapped_decl_index: DeclIndex.Unwrapped = .{
...@@ -9681,11 +9925,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex...@@ -9681,11 +9925,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex
9681 local.mutate.decls.free_list = @intFromEnum(decl_index);9925 local.mutate.decls.free_list = @intFromEnum(decl_index);
9682}9926}
96839927
9928pub fn namespacePtr(ip: *InternPool, namespace_index: NamespaceIndex) *Zcu.Namespace {
9929 const unwrapped_namespace_index = namespace_index.unwrap(ip);
9930 const namespaces = ip.getLocalShared(unwrapped_namespace_index.tid).namespaces.acquire();
9931 const namespaces_bucket = namespaces.view().items(.@"0")[unwrapped_namespace_index.bucket_index];
9932 return &namespaces_bucket[unwrapped_namespace_index.index];
9933}
9934
9684pub fn createNamespace(9935pub fn createNamespace(
9685 ip: *InternPool,9936 ip: *InternPool,
9686 gpa: Allocator,9937 gpa: Allocator,
9687 tid: Zcu.PerThread.Id,9938 tid: Zcu.PerThread.Id,
9688 initialization: Module.Namespace,9939 initialization: Zcu.Namespace,
9689) Allocator.Error!NamespaceIndex {9940) Allocator.Error!NamespaceIndex {
9690 const local = ip.getLocal(tid);9941 const local = ip.getLocal(tid);
9691 const free_list_next = local.mutate.namespaces.free_list;9942 const free_list_next = local.mutate.namespaces.free_list;
...@@ -9703,7 +9954,7 @@ pub fn createNamespace(...@@ -9703,7 +9954,7 @@ pub fn createNamespace(
9703 var arena = namespaces.arena.promote(namespaces.gpa);9954 var arena = namespaces.arena.promote(namespaces.gpa);
9704 defer namespaces.arena.* = arena.state;9955 defer namespaces.arena.* = arena.state;
9705 namespaces.appendAssumeCapacity(.{try arena.allocator().create(9956 namespaces.appendAssumeCapacity(.{try arena.allocator().create(
9706 [1 << Local.namespaces_bucket_width]Module.Namespace,9957 [1 << Local.namespaces_bucket_width]Zcu.Namespace,
9707 )});9958 )});
9708 }9959 }
9709 const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{9960 const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{
...@@ -9735,6 +9986,27 @@ pub fn destroyNamespace(...@@ -9735,6 +9986,27 @@ pub fn destroyNamespace(
9735 local.mutate.namespaces.free_list = @intFromEnum(namespace_index);9986 local.mutate.namespaces.free_list = @intFromEnum(namespace_index);
9736}9987}
97379988
9989pub fn filePtr(ip: *InternPool, file_index: FileIndex) *Zcu.File {
9990 const file_index_unwrapped = file_index.unwrap(ip);
9991 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
9992 return files.view().items(.file)[file_index_unwrapped.index];
9993}
9994
9995pub fn createFile(
9996 ip: *InternPool,
9997 gpa: Allocator,
9998 tid: Zcu.PerThread.Id,
9999 file: File,
10000) Allocator.Error!FileIndex {
10001 const files = ip.getLocal(tid).getMutableFiles(gpa);
10002 const file_index_unwrapped: FileIndex.Unwrapped = .{
10003 .tid = tid,
10004 .index = files.mutate.len,
10005 };
10006 try files.append(file);
10007 return file_index_unwrapped.wrap(ip);
10008}
10009
9738const EmbeddedNulls = enum {10010const EmbeddedNulls = enum {
9739 no_embedded_nulls,10011 no_embedded_nulls,
9740 maybe_embedded_nulls,10012 maybe_embedded_nulls,
...@@ -9813,7 +10085,7 @@ pub fn getOrPutTrailingString(...@@ -9813,7 +10085,7 @@ pub fn getOrPutTrailingString(
9813 }10085 }
9814 const key: []const u8 = strings.view().items(.@"0")[start..];10086 const key: []const u8 = strings.view().items(.@"0")[start..];
9815 const value: embedded_nulls.StringType() =10087 const value: embedded_nulls.StringType() =
9816 @enumFromInt(@as(u32, @intFromEnum(tid)) << ip.tid_shift_32 | start);10088 @enumFromInt(@intFromEnum((String.Unwrapped{ .tid = tid, .index = start }).wrap(ip)));
9817 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;10089 const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null;
9818 switch (embedded_nulls) {10090 switch (embedded_nulls) {
9819 .no_embedded_nulls => assert(!has_embedded_null),10091 .no_embedded_nulls => assert(!has_embedded_null),
...@@ -9859,10 +10131,10 @@ pub fn getOrPutTrailingString(...@@ -9859,10 +10131,10 @@ pub fn getOrPutTrailingString(
9859 defer shard.mutate.string_map.len += 1;10131 defer shard.mutate.string_map.len += 1;
9860 const map_header = map.header().*;10132 const map_header = map.header().*;
9861 if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) {10133 if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) {
10134 strings.appendAssumeCapacity(.{0});
9862 const entry = &map.entries[map_index];10135 const entry = &map.entries[map_index];
9863 entry.hash = hash;10136 entry.hash = hash;
9864 entry.release(@enumFromInt(@intFromEnum(value)));10137 entry.release(@enumFromInt(@intFromEnum(value)));
9865 strings.appendAssumeCapacity(.{0});
9866 return value;10138 return value;
9867 }10139 }
9868 const arena_state = &ip.getLocal(tid).mutate.arena;10140 const arena_state = &ip.getLocal(tid).mutate.arena;
...@@ -9901,12 +10173,12 @@ pub fn getOrPutTrailingString(...@@ -9901,12 +10173,12 @@ pub fn getOrPutTrailingString(
9901 map_index &= new_map_mask;10173 map_index &= new_map_mask;
9902 if (map.entries[map_index].value == .none) break;10174 if (map.entries[map_index].value == .none) break;
9903 }10175 }
10176 strings.appendAssumeCapacity(.{0});
9904 map.entries[map_index] = .{10177 map.entries[map_index] = .{
9905 .value = @enumFromInt(@intFromEnum(value)),10178 .value = @enumFromInt(@intFromEnum(value)),
9906 .hash = hash,10179 .hash = hash,
9907 };10180 };
9908 shard.shared.string_map.release(new_map);10181 shard.shared.string_map.release(new_map);
9909 strings.appendAssumeCapacity(.{0});
9910 return value;10182 return value;
9911}10183}
991210184
...@@ -10654,7 +10926,7 @@ pub fn addFieldName(...@@ -10654,7 +10926,7 @@ pub fn addFieldName(
10654 name: NullTerminatedString,10926 name: NullTerminatedString,
10655) ?u32 {10927) ?u32 {
10656 const extra_items = extra.view().items(.@"0");10928 const extra_items = extra.view().items(.@"0");
10657 const map = &ip.maps.items[@intFromEnum(names_map)];10929 const map = names_map.get(ip);
10658 const field_index = map.count();10930 const field_index = map.count();
10659 const strings = extra_items[names_start..][0..field_index];10931 const strings = extra_items[names_start..][0..field_index];
10660 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };10932 const adapter: NullTerminatedString.Adapter = .{ .strings = @ptrCast(strings) };
...@@ -10672,3 +10944,160 @@ fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty...@@ -10672,3 +10944,160 @@ fn ptrsHaveSameAlignment(ip: *InternPool, a_ty: Index, a_info: Key.PtrType, b_ty
10672 return a_info.flags.alignment == b_info.flags.alignment and10944 return a_info.flags.alignment == b_info.flags.alignment and
10673 (a_info.child == b_info.child or a_info.flags.alignment != .none);10945 (a_info.child == b_info.child or a_info.flags.alignment != .none);
10674}10946}
10947
10948const GlobalErrorSet = struct {
10949 shared: struct {
10950 names: Names,
10951 map: Shard.Map(GlobalErrorSet.Index),
10952 } align(std.atomic.cache_line),
10953 mutate: Local.MutexListMutate align(std.atomic.cache_line),
10954
10955 const Names = Local.List(struct { NullTerminatedString });
10956
10957 const empty: GlobalErrorSet = .{
10958 .shared = .{
10959 .names = Names.empty,
10960 .map = Shard.Map(GlobalErrorSet.Index).empty,
10961 },
10962 .mutate = Local.MutexListMutate.empty,
10963 };
10964
10965 const Index = enum(Zcu.ErrorInt) {
10966 none = 0,
10967 _,
10968 };
10969
10970 /// Not thread-safe, may only be called from the main thread.
10971 pub fn getNamesFromMainThread(ges: *const GlobalErrorSet) []const NullTerminatedString {
10972 const len = ges.mutate.list.len;
10973 return if (len > 0) ges.shared.names.view().items(.@"0")[0..len] else &.{};
10974 }
10975
10976 fn getErrorValue(
10977 ges: *GlobalErrorSet,
10978 gpa: Allocator,
10979 arena_state: *std.heap.ArenaAllocator.State,
10980 name: NullTerminatedString,
10981 ) Allocator.Error!GlobalErrorSet.Index {
10982 if (name == .empty) return .none;
10983 const hash = std.hash.uint32(@intFromEnum(name));
10984 var map = ges.shared.map.acquire();
10985 const Map = @TypeOf(map);
10986 var map_mask = map.header().mask();
10987 const names = ges.shared.names.acquire();
10988 var map_index = hash;
10989 while (true) : (map_index += 1) {
10990 map_index &= map_mask;
10991 const entry = &map.entries[map_index];
10992 const index = entry.acquire();
10993 if (index == .none) break;
10994 if (entry.hash != hash) continue;
10995 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;
10996 }
10997 ges.mutate.mutex.lock();
10998 defer ges.mutate.mutex.unlock();
10999 if (map.entries != ges.shared.map.entries) {
11000 map = ges.shared.map;
11001 map_mask = map.header().mask();
11002 map_index = hash;
11003 }
11004 while (true) : (map_index += 1) {
11005 map_index &= map_mask;
11006 const entry = &map.entries[map_index];
11007 const index = entry.value;
11008 if (index == .none) break;
11009 if (entry.hash != hash) continue;
11010 if (names.view().items(.@"0")[@intFromEnum(index) - 1] == name) return index;
11011 }
11012 const mutable_names: Names.Mutable = .{
11013 .gpa = gpa,
11014 .arena = arena_state,
11015 .mutate = &ges.mutate.list,
11016 .list = &ges.shared.names,
11017 };
11018 try mutable_names.ensureUnusedCapacity(1);
11019 const map_header = map.header().*;
11020 if (ges.mutate.list.len < map_header.capacity * 3 / 5) {
11021 mutable_names.appendAssumeCapacity(.{name});
11022 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);
11023 const entry = &map.entries[map_index];
11024 entry.hash = hash;
11025 entry.release(index);
11026 return index;
11027 }
11028 var arena = arena_state.promote(gpa);
11029 defer arena_state.* = arena.state;
11030 const new_map_capacity = map_header.capacity * 2;
11031 const new_map_buf = try arena.allocator().alignedAlloc(
11032 u8,
11033 Map.alignment,
11034 Map.entries_offset + new_map_capacity * @sizeOf(Map.Entry),
11035 );
11036 const new_map: Map = .{ .entries = @ptrCast(new_map_buf[Map.entries_offset..].ptr) };
11037 new_map.header().* = .{ .capacity = new_map_capacity };
11038 @memset(new_map.entries[0..new_map_capacity], .{ .value = .none, .hash = undefined });
11039 const new_map_mask = new_map.header().mask();
11040 map_index = 0;
11041 while (map_index < map_header.capacity) : (map_index += 1) {
11042 const entry = &map.entries[map_index];
11043 const index = entry.value;
11044 if (index == .none) continue;
11045 const item_hash = entry.hash;
11046 var new_map_index = item_hash;
11047 while (true) : (new_map_index += 1) {
11048 new_map_index &= new_map_mask;
11049 const new_entry = &new_map.entries[new_map_index];
11050 if (new_entry.value != .none) continue;
11051 new_entry.* = .{
11052 .value = index,
11053 .hash = item_hash,
11054 };
11055 break;
11056 }
11057 }
11058 map = new_map;
11059 map_index = hash;
11060 while (true) : (map_index += 1) {
11061 map_index &= new_map_mask;
11062 if (map.entries[map_index].value == .none) break;
11063 }
11064 mutable_names.appendAssumeCapacity(.{name});
11065 const index: GlobalErrorSet.Index = @enumFromInt(mutable_names.mutate.len);
11066 map.entries[map_index] = .{ .value = index, .hash = hash };
11067 ges.shared.map.release(new_map);
11068 return index;
11069 }
11070
11071 fn getErrorValueIfExists(
11072 ges: *const GlobalErrorSet,
11073 name: NullTerminatedString,
11074 ) ?GlobalErrorSet.Index {
11075 if (name == .empty) return .none;
11076 const hash = std.hash.uint32(@intFromEnum(name));
11077 const map = ges.shared.map.acquire();
11078 const map_mask = map.header().mask();
11079 const names_items = ges.shared.names.acquire().view().items(.@"0");
11080 var map_index = hash;
11081 while (true) : (map_index += 1) {
11082 map_index &= map_mask;
11083 const entry = &map.entries[map_index];
11084 const index = entry.acquire();
11085 if (index == .none) return null;
11086 if (entry.hash != hash) continue;
11087 if (names_items[@intFromEnum(index) - 1] == name) return index;
11088 }
11089 }
11090};
11091
11092pub fn getErrorValue(
11093 ip: *InternPool,
11094 gpa: Allocator,
11095 tid: Zcu.PerThread.Id,
11096 name: NullTerminatedString,
11097) Allocator.Error!Zcu.ErrorInt {
11098 return @intFromEnum(try ip.global_error_set.getErrorValue(gpa, &ip.getLocal(tid).mutate.arena, name));
11099}
11100
11101pub fn getErrorValueIfExists(ip: *const InternPool, name: NullTerminatedString) ?Zcu.ErrorInt {
11102 return @intFromEnum(ip.global_error_set.getErrorValueIfExists(name) orelse return null);
11103}
src/Sema.zig+59-54
...@@ -835,12 +835,11 @@ pub const Block = struct {...@@ -835,12 +835,11 @@ pub const Block = struct {
835 }835 }
836836
837 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {837 fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index {
838 const sema = block.sema;838 const pt = block.sema.pt;
839 const gpa = sema.gpa;839 return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{
840 const zcu = sema.pt.zcu;840 .file = block.getFileScopeIndex(pt.zcu),
841 const ip = &zcu.intern_pool;841 .inst = inst,
842 const file_index = block.getFileScopeIndex(zcu);842 });
843 return ip.trackZir(gpa, file_index, inst);
844 }843 }
845};844};
846845
...@@ -2878,7 +2877,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2878,7 +2877,7 @@ fn createAnonymousDeclTypeNamed(
2878 switch (name_strategy) {2877 switch (name_strategy) {
2879 .anon => {}, // handled after switch2878 .anon => {}, // handled after switch
2880 .parent => {2879 .parent => {
2881 try zcu.initNewAnonDecl(new_decl_index, val, block.type_name_ctx);2880 try pt.initNewAnonDecl(new_decl_index, val, block.type_name_ctx, .none);
2882 return new_decl_index;2881 return new_decl_index;
2883 },2882 },
2884 .func => func_strat: {2883 .func => func_strat: {
...@@ -2923,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2923,7 +2922,7 @@ fn createAnonymousDeclTypeNamed(
29232922
2924 try writer.writeByte(')');2923 try writer.writeByte(')');
2925 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);2924 const name = try ip.getOrPutString(gpa, pt.tid, buf.items, .no_embedded_nulls);
2926 try zcu.initNewAnonDecl(new_decl_index, val, name);2925 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2927 return new_decl_index;2926 return new_decl_index;
2928 },2927 },
2929 .dbg_var => {2928 .dbg_var => {
...@@ -2937,7 +2936,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2937,7 +2936,7 @@ fn createAnonymousDeclTypeNamed(
2937 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{2936 const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{
2938 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),2937 block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code),
2939 }, .no_embedded_nulls);2938 }, .no_embedded_nulls);
2940 try zcu.initNewAnonDecl(new_decl_index, val, name);2939 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2941 return new_decl_index;2940 return new_decl_index;
2942 },2941 },
2943 else => {},2942 else => {},
...@@ -2958,7 +2957,7 @@ fn createAnonymousDeclTypeNamed(...@@ -2958,7 +2957,7 @@ fn createAnonymousDeclTypeNamed(
2958 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{2957 const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{
2959 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),2958 block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index),
2960 }, .no_embedded_nulls) catch unreachable;2959 }, .no_embedded_nulls) catch unreachable;
2961 try zcu.initNewAnonDecl(new_decl_index, val, name);2960 try pt.initNewAnonDecl(new_decl_index, val, name, .none);
2962 return new_decl_index;2961 return new_decl_index;
2963}2962}
29642963
...@@ -3474,7 +3473,7 @@ fn zirErrorSetDecl(...@@ -3474,7 +3473,7 @@ fn zirErrorSetDecl(
3474 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);3473 const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]);
3475 const name = sema.code.nullTerminatedString(name_index);3474 const name = sema.code.nullTerminatedString(name_index);
3476 const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);3475 const name_ip = try mod.intern_pool.getOrPutString(gpa, pt.tid, name, .no_embedded_nulls);
3477 _ = try mod.getErrorValue(name_ip);3476 _ = try pt.getErrorValue(name_ip);
3478 const result = names.getOrPutAssumeCapacity(name_ip);3477 const result = names.getOrPutAssumeCapacity(name_ip);
3479 assert(!result.found_existing); // verified in AstGen3478 assert(!result.found_existing); // verified in AstGen
3480 }3479 }
...@@ -5527,13 +5526,12 @@ fn failWithBadStructFieldAccess(...@@ -5527,13 +5526,12 @@ fn failWithBadStructFieldAccess(
5527 const zcu = pt.zcu;5526 const zcu = pt.zcu;
5528 const ip = &zcu.intern_pool;5527 const ip = &zcu.intern_pool;
5529 const decl = zcu.declPtr(struct_type.decl.unwrap().?);5528 const decl = zcu.declPtr(struct_type.decl.unwrap().?);
5530 const fqn = try decl.fullyQualifiedName(pt);
55315529
5532 const msg = msg: {5530 const msg = msg: {
5533 const msg = try sema.errMsg(5531 const msg = try sema.errMsg(
5534 field_src,5532 field_src,
5535 "no field named '{}' in struct '{}'",5533 "no field named '{}' in struct '{}'",
5536 .{ field_name.fmt(ip), fqn.fmt(ip) },5534 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5537 );5535 );
5538 errdefer msg.destroy(sema.gpa);5536 errdefer msg.destroy(sema.gpa);
5539 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});5537 try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{});
...@@ -5554,15 +5552,13 @@ fn failWithBadUnionFieldAccess(...@@ -5554,15 +5552,13 @@ fn failWithBadUnionFieldAccess(
5554 const zcu = pt.zcu;5552 const zcu = pt.zcu;
5555 const ip = &zcu.intern_pool;5553 const ip = &zcu.intern_pool;
5556 const gpa = sema.gpa;5554 const gpa = sema.gpa;
5557
5558 const decl = zcu.declPtr(union_obj.decl);5555 const decl = zcu.declPtr(union_obj.decl);
5559 const fqn = try decl.fullyQualifiedName(pt);
55605556
5561 const msg = msg: {5557 const msg = msg: {
5562 const msg = try sema.errMsg(5558 const msg = try sema.errMsg(
5563 field_src,5559 field_src,
5564 "no field named '{}' in union '{}'",5560 "no field named '{}' in union '{}'",
5565 .{ field_name.fmt(ip), fqn.fmt(ip) },5561 .{ field_name.fmt(ip), decl.fqn.fmt(ip) },
5566 );5562 );
5567 errdefer msg.destroy(gpa);5563 errdefer msg.destroy(gpa);
5568 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});5564 try sema.errNote(union_ty.srcLoc(zcu), msg, "union declared here", .{});
...@@ -6059,7 +6055,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr...@@ -6059,7 +6055,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
6059 else => |e| return e,6055 else => |e| return e,
6060 };6056 };
60616057
6062 const result = zcu.importPkg(c_import_mod) catch |err|6058 const result = pt.importPkg(c_import_mod) catch |err|
6063 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});6059 return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)});
60646060
6065 const path_digest = zcu.filePathDigest(result.file_index);6061 const path_digest = zcu.filePathDigest(result.file_index);
...@@ -6721,13 +6717,7 @@ fn addDbgVar(...@@ -6721,13 +6717,7 @@ fn addDbgVar(
6721 if (block.need_debug_scope) |ptr| ptr.* = true;6717 if (block.need_debug_scope) |ptr| ptr.* = true;
67226718
6723 // Add the name to the AIR.6719 // Add the name to the AIR.
6724 const name_extra_index: u32 = @intCast(sema.air_extra.items.len);6720 const name_extra_index = try sema.appendAirString(name);
6725 const elements_used = name.len / 4 + 1;
6726 try sema.air_extra.ensureUnusedCapacity(sema.gpa, elements_used);
6727 const buffer = mem.sliceAsBytes(sema.air_extra.unusedCapacitySlice());
6728 @memcpy(buffer[0..name.len], name);
6729 buffer[name.len] = 0;
6730 sema.air_extra.items.len += elements_used;
67316721
6732 _ = try block.addInst(.{6722 _ = try block.addInst(.{
6733 .tag = air_tag,6723 .tag = air_tag,
...@@ -6738,6 +6728,16 @@ fn addDbgVar(...@@ -6738,6 +6728,16 @@ fn addDbgVar(
6738 });6728 });
6739}6729}
67406730
6731pub fn appendAirString(sema: *Sema, str: []const u8) Allocator.Error!u32 {
6732 const str_extra_index: u32 = @intCast(sema.air_extra.items.len);
6733 const elements_used = str.len / 4 + 1;
6734 const elements = try sema.air_extra.addManyAsSlice(sema.gpa, elements_used);
6735 const buffer = mem.sliceAsBytes(elements);
6736 @memcpy(buffer[0..str.len], str);
6737 buffer[str.len] = 0;
6738 return str_extra_index;
6739}
6740
6741fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {6741fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
6742 const pt = sema.pt;6742 const pt = sema.pt;
6743 const mod = pt.zcu;6743 const mod = pt.zcu;
...@@ -8357,13 +8357,6 @@ fn instantiateGenericCall(...@@ -8357,13 +8357,6 @@ fn instantiateGenericCall(
8357 }8357 }
8358 } else {8358 } else {
8359 // The parameter is runtime-known.8359 // The parameter is runtime-known.
8360 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
8361 .tag = .arg,
8362 .data = .{ .arg = .{
8363 .ty = Air.internedToRef(arg_ty.toIntern()),
8364 .src_index = @intCast(arg_index),
8365 } },
8366 }));
8367 const param_name: Zir.NullTerminatedString = switch (param_tag) {8360 const param_name: Zir.NullTerminatedString = switch (param_tag) {
8368 .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,8361 .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start,
8369 .param => name: {8362 .param => name: {
...@@ -8373,6 +8366,16 @@ fn instantiateGenericCall(...@@ -8373,6 +8366,16 @@ fn instantiateGenericCall(
8373 },8366 },
8374 else => unreachable,8367 else => unreachable,
8375 };8368 };
8369 child_sema.inst_map.putAssumeCapacityNoClobber(param_inst, try child_block.addInst(.{
8370 .tag = .arg,
8371 .data = .{ .arg = .{
8372 .ty = Air.internedToRef(arg_ty.toIntern()),
8373 .name = if (child_block.ownerModule().strip)
8374 .none
8375 else
8376 @enumFromInt(try sema.appendAirString(fn_zir.nullTerminatedString(param_name))),
8377 } },
8378 }));
8376 try child_block.params.append(sema.arena, .{8379 try child_block.params.append(sema.arena, .{
8377 .ty = arg_ty.toIntern(), // This is the type after coercion8380 .ty = arg_ty.toIntern(), // This is the type after coercion
8378 .is_comptime = false, // We're adding only runtime args to the instantiation8381 .is_comptime = false, // We're adding only runtime args to the instantiation
...@@ -8702,7 +8705,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!...@@ -8702,7 +8705,7 @@ fn zirErrorValue(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!
8702 inst_data.get(sema.code),8705 inst_data.get(sema.code),
8703 .no_embedded_nulls,8706 .no_embedded_nulls,
8704 );8707 );
8705 _ = try pt.zcu.getErrorValue(name);8708 _ = try pt.getErrorValue(name);
8706 // Create an error set type with only this error value, and return the value.8709 // Create an error set type with only this error value, and return the value.
8707 const error_set_type = try pt.singleErrorSetType(name);8710 const error_set_type = try pt.singleErrorSetType(name);
8708 return Air.internedToRef((try pt.intern(.{ .err = .{8711 return Air.internedToRef((try pt.intern(.{ .err = .{
...@@ -8732,7 +8735,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8732,7 +8735,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8732 const err_name = ip.indexToKey(val.toIntern()).err.name;8735 const err_name = ip.indexToKey(val.toIntern()).err.name;
8733 return Air.internedToRef((try pt.intValue(8736 return Air.internedToRef((try pt.intValue(
8734 err_int_ty,8737 err_int_ty,
8735 try mod.getErrorValue(err_name),8738 try pt.getErrorValue(err_name),
8736 )).toIntern());8739 )).toIntern());
8737 }8740 }
87388741
...@@ -8743,10 +8746,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8743,10 +8746,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
8743 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;8746 const names = ip.indexToKey(err_set_ty_index).error_set_type.names;
8744 switch (names.len) {8747 switch (names.len) {
8745 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),8748 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()),
8746 1 => {8749 1 => return pt.intRef(err_int_ty, ip.getErrorValueIfExists(names.get(ip)[0]).?),
8747 const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?);
8748 return pt.intRef(err_int_ty, int);
8749 },
8750 else => {},8750 else => {},
8751 }8751 }
8752 },8752 },
...@@ -8762,6 +8762,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8762,6 +8762,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87628762
8763 const pt = sema.pt;8763 const pt = sema.pt;
8764 const mod = pt.zcu;8764 const mod = pt.zcu;
8765 const ip = &mod.intern_pool;
8765 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;8766 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
8766 const src = block.nodeOffset(extra.node);8767 const src = block.nodeOffset(extra.node);
8767 const operand_src = block.builtinCallArgSrc(extra.node, 0);8768 const operand_src = block.builtinCallArgSrc(extra.node, 0);
...@@ -8771,11 +8772,16 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD...@@ -8771,11 +8772,16 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
87718772
8772 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {8773 if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| {
8773 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));8774 const int = try sema.usizeCast(block, operand_src, try value.toUnsignedIntSema(pt));
8774 if (int > mod.global_error_set.count() or int == 0)8775 if (int > len: {
8776 const mutate = &ip.global_error_set.mutate;
8777 mutate.mutex.lock();
8778 defer mutate.mutex.unlock();
8779 break :len mutate.list.len;
8780 } or int == 0)
8775 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});8781 return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int});
8776 return Air.internedToRef((try pt.intern(.{ .err = .{8782 return Air.internedToRef((try pt.intern(.{ .err = .{
8777 .ty = .anyerror_type,8783 .ty = .anyerror_type,
8778 .name = mod.global_error_set.keys()[int],8784 .name = ip.global_error_set.shared.names.acquire().view().items(.@"0")[int - 1],
8779 } })));8785 } })));
8780 }8786 }
8781 try sema.requireRuntimeBlock(block, src, operand_src);8787 try sema.requireRuntimeBlock(block, src, operand_src);
...@@ -13943,7 +13949,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air....@@ -13943,7 +13949,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
13943 const operand_src = block.tokenOffset(inst_data.src_tok);13949 const operand_src = block.tokenOffset(inst_data.src_tok);
13944 const operand = inst_data.get(sema.code);13950 const operand = inst_data.get(sema.code);
1394513951
13946 const result = zcu.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {13952 const result = pt.importFile(block.getFileScope(zcu), operand) catch |err| switch (err) {
13947 error.ImportOutsideModulePath => {13953 error.ImportOutsideModulePath => {
13948 return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});13954 return sema.fail(block, operand_src, "import of file outside module path: '{s}'", .{operand});
13949 },13955 },
...@@ -14002,7 +14008,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R...@@ -14002,7 +14008,7 @@ fn zirRetErrValueCode(sema: *Sema, inst: Zir.Inst.Index) CompileError!Air.Inst.R
14002 inst_data.get(sema.code),14008 inst_data.get(sema.code),
14003 .no_embedded_nulls,14009 .no_embedded_nulls,
14004 );14010 );
14005 _ = try mod.getErrorValue(name);14011 _ = try pt.getErrorValue(name);
14006 const error_set_type = try pt.singleErrorSetType(name);14012 const error_set_type = try pt.singleErrorSetType(name);
14007 return Air.internedToRef((try pt.intern(.{ .err = .{14013 return Air.internedToRef((try pt.intern(.{ .err = .{
14008 .ty = error_set_type.toIntern(),14014 .ty = error_set_type.toIntern(),
...@@ -19561,7 +19567,7 @@ fn zirRetErrValue(...@@ -19561,7 +19567,7 @@ fn zirRetErrValue(
19561 inst_data.get(sema.code),19567 inst_data.get(sema.code),
19562 .no_embedded_nulls,19568 .no_embedded_nulls,
19563 );19569 );
19564 _ = try mod.getErrorValue(err_name);19570 _ = try pt.getErrorValue(err_name);
19565 // Return the error code from the function.19571 // Return the error code from the function.
19566 const error_set_type = try pt.singleErrorSetType(err_name);19572 const error_set_type = try pt.singleErrorSetType(err_name);
19567 const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{19573 const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{
...@@ -21604,7 +21610,7 @@ fn zirReify(...@@ -21604,7 +21610,7 @@ fn zirReify(
21604 const name = try sema.sliceToIpString(block, src, name_val, .{21610 const name = try sema.sliceToIpString(block, src, name_val, .{
21605 .needed_comptime_reason = "error set contents must be comptime-known",21611 .needed_comptime_reason = "error set contents must be comptime-known",
21606 });21612 });
21607 _ = try mod.getErrorValue(name);21613 _ = try pt.getErrorValue(name);
21608 const gop = names.getOrPutAssumeCapacity(name);21614 const gop = names.getOrPutAssumeCapacity(name);
21609 if (gop.found_existing) {21615 if (gop.found_existing) {
21610 return sema.fail(block, src, "duplicate error '{}'", .{21616 return sema.fail(block, src, "duplicate error '{}'", .{
...@@ -26500,7 +26506,7 @@ fn zirBuiltinExtern(...@@ -26500,7 +26506,7 @@ fn zirBuiltinExtern(
26500 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);26506 const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace);
26501 errdefer pt.destroyDecl(new_decl_index);26507 errdefer pt.destroyDecl(new_decl_index);
26502 const new_decl = mod.declPtr(new_decl_index);26508 const new_decl = mod.declPtr(new_decl_index);
26503 try mod.initNewAnonDecl(26509 try pt.initNewAnonDecl(
26504 new_decl_index,26510 new_decl_index,
26505 Value.fromInterned(26511 Value.fromInterned(
26506 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)26512 if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn)
...@@ -26522,6 +26528,7 @@ fn zirBuiltinExtern(...@@ -26522,6 +26528,7 @@ fn zirBuiltinExtern(
26522 } }),26528 } }),
26523 ),26529 ),
26524 options.name,26530 options.name,
26531 .none,
26525 );26532 );
26526 new_decl.owns_tv = true;26533 new_decl.owns_tv = true;
26527 // Note that this will queue the anon decl for codegen, so that the backend can26534 // Note that this will queue the anon decl for codegen, so that the backend can
...@@ -27481,7 +27488,7 @@ fn fieldVal(...@@ -27481,7 +27488,7 @@ fn fieldVal(
27481 },27488 },
27482 .simple_type => |t| {27489 .simple_type => |t| {
27483 assert(t == .anyerror);27490 assert(t == .anyerror);
27484 _ = try mod.getErrorValue(field_name);27491 _ = try pt.getErrorValue(field_name);
27485 },27492 },
27486 else => unreachable,27493 else => unreachable,
27487 }27494 }
...@@ -27721,7 +27728,7 @@ fn fieldPtr(...@@ -27721,7 +27728,7 @@ fn fieldPtr(
27721 },27728 },
27722 .simple_type => |t| {27729 .simple_type => |t| {
27723 assert(t == .anyerror);27730 assert(t == .anyerror);
27724 _ = try mod.getErrorValue(field_name);27731 _ = try pt.getErrorValue(field_name);
27725 },27732 },
27726 else => unreachable,27733 else => unreachable,
27727 }27734 }
...@@ -36735,24 +36742,23 @@ fn generateUnionTagTypeNumbered(...@@ -36735,24 +36742,23 @@ fn generateUnionTagTypeNumbered(
3673536742
36736 const new_decl_index = try pt.allocateNewDecl(block.namespace);36743 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36737 errdefer pt.destroyDecl(new_decl_index);36744 errdefer pt.destroyDecl(new_decl_index);
36738 const fqn = try union_owner_decl.fullyQualifiedName(pt);
36739 const name = try ip.getOrPutStringFmt(36745 const name = try ip.getOrPutStringFmt(
36740 gpa,36746 gpa,
36741 pt.tid,36747 pt.tid,
36742 "@typeInfo({}).Union.tag_type.?",36748 "@typeInfo({}).Union.tag_type.?",
36743 .{fqn.fmt(ip)},36749 .{union_owner_decl.fqn.fmt(ip)},
36744 .no_embedded_nulls,36750 .no_embedded_nulls,
36745 );36751 );
36746 try mod.initNewAnonDecl(36752 try pt.initNewAnonDecl(
36747 new_decl_index,36753 new_decl_index,
36748 Value.@"unreachable",36754 Value.@"unreachable",
36749 name,36755 name,
36756 name.toOptional(),
36750 );36757 );
36751 errdefer pt.abortAnonDecl(new_decl_index);36758 errdefer pt.abortAnonDecl(new_decl_index);
3675236759
36753 const new_decl = mod.declPtr(new_decl_index);36760 const new_decl = mod.declPtr(new_decl_index);
36754 new_decl.owns_tv = true;36761 new_decl.owns_tv = true;
36755 new_decl.name_fully_qualified = true;
3675636762
36757 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{36763 const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{
36758 .decl = new_decl_index,36764 .decl = new_decl_index,
...@@ -36784,22 +36790,21 @@ fn generateUnionTagTypeSimple(...@@ -36784,22 +36790,21 @@ fn generateUnionTagTypeSimple(
36784 const gpa = sema.gpa;36790 const gpa = sema.gpa;
3678536791
36786 const new_decl_index = new_decl_index: {36792 const new_decl_index = new_decl_index: {
36787 const fqn = try union_owner_decl.fullyQualifiedName(pt);
36788 const new_decl_index = try pt.allocateNewDecl(block.namespace);36793 const new_decl_index = try pt.allocateNewDecl(block.namespace);
36789 errdefer pt.destroyDecl(new_decl_index);36794 errdefer pt.destroyDecl(new_decl_index);
36790 const name = try ip.getOrPutStringFmt(36795 const name = try ip.getOrPutStringFmt(
36791 gpa,36796 gpa,
36792 pt.tid,36797 pt.tid,
36793 "@typeInfo({}).Union.tag_type.?",36798 "@typeInfo({}).Union.tag_type.?",
36794 .{fqn.fmt(ip)},36799 .{union_owner_decl.fqn.fmt(ip)},
36795 .no_embedded_nulls,36800 .no_embedded_nulls,
36796 );36801 );
36797 try mod.initNewAnonDecl(36802 try pt.initNewAnonDecl(
36798 new_decl_index,36803 new_decl_index,
36799 Value.@"unreachable",36804 Value.@"unreachable",
36800 name,36805 name,
36806 name.toOptional(),
36801 );36807 );
36802 mod.declPtr(new_decl_index).name_fully_qualified = true;
36803 break :new_decl_index new_decl_index;36808 break :new_decl_index new_decl_index;
36804 };36809 };
36805 errdefer pt.abortAnonDecl(new_decl_index);36810 errdefer pt.abortAnonDecl(new_decl_index);
src/Type.zig+9-9
...@@ -268,10 +268,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -268,10 +268,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
268 return;268 return;
269 },269 },
270 .inferred_error_set_type => |func_index| {270 .inferred_error_set_type => |func_index| {
271 try writer.writeAll("@typeInfo(@typeInfo(@TypeOf(");
272 const owner_decl = mod.funcOwnerDeclPtr(func_index);271 const owner_decl = mod.funcOwnerDeclPtr(func_index);
273 try owner_decl.renderFullyQualifiedName(mod, writer);272 try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{
274 try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set");273 owner_decl.fqn.fmt(ip),
274 });
275 },275 },
276 .error_set_type => |error_set_type| {276 .error_set_type => |error_set_type| {
277 const names = error_set_type.names;277 const names = error_set_type.names;
...@@ -334,10 +334,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -334,10 +334,10 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
334 const struct_type = ip.loadStructType(ty.toIntern());334 const struct_type = ip.loadStructType(ty.toIntern());
335 if (struct_type.decl.unwrap()) |decl_index| {335 if (struct_type.decl.unwrap()) |decl_index| {
336 const decl = mod.declPtr(decl_index);336 const decl = mod.declPtr(decl_index);
337 try decl.renderFullyQualifiedName(mod, writer);337 try writer.print("{}", .{decl.fqn.fmt(ip)});
338 } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {338 } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| {
339 const namespace = mod.namespacePtr(namespace_index);339 const namespace = mod.namespacePtr(namespace_index);
340 try namespace.renderFullyQualifiedName(mod, .empty, writer);340 try namespace.renderFullyQualifiedName(ip, .empty, writer);
341 } else {341 } else {
342 try writer.writeAll("@TypeOf(.{})");342 try writer.writeAll("@TypeOf(.{})");
343 }343 }
...@@ -367,15 +367,15 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error...@@ -367,15 +367,15 @@ pub fn print(ty: Type, writer: anytype, pt: Zcu.PerThread) @TypeOf(writer).Error
367367
368 .union_type => {368 .union_type => {
369 const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);369 const decl = mod.declPtr(ip.loadUnionType(ty.toIntern()).decl);
370 try decl.renderFullyQualifiedName(mod, writer);370 try writer.print("{}", .{decl.fqn.fmt(ip)});
371 },371 },
372 .opaque_type => {372 .opaque_type => {
373 const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);373 const decl = mod.declPtr(ip.loadOpaqueType(ty.toIntern()).decl);
374 try decl.renderFullyQualifiedName(mod, writer);374 try writer.print("{}", .{decl.fqn.fmt(ip)});
375 },375 },
376 .enum_type => {376 .enum_type => {
377 const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);377 const decl = mod.declPtr(ip.loadEnumType(ty.toIntern()).decl);
378 try decl.renderFullyQualifiedName(mod, writer);378 try writer.print("{}", .{decl.fqn.fmt(ip)});
379 },379 },
380 .func_type => |fn_info| {380 .func_type => |fn_info| {
381 if (fn_info.is_noinline) {381 if (fn_info.is_noinline) {
...@@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {...@@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index {
3451 };3451 };
3452}3452}
34533453
3454pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 {3454pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
3455 const ip = &zcu.intern_pool;3455 const ip = &zcu.intern_pool;
3456 const tracked = switch (ip.indexToKey(ty.toIntern())) {3456 const tracked = switch (ip.indexToKey(ty.toIntern())) {
3457 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {3457 .struct_type, .union_type, .opaque_type, .enum_type => |info| switch (info) {
src/Value.zig+5-5
...@@ -417,7 +417,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -417,7 +417,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
417 var bigint_buffer: BigIntSpace = undefined;417 var bigint_buffer: BigIntSpace = undefined;
418 const bigint = BigIntMutable.init(418 const bigint = BigIntMutable.init(
419 &bigint_buffer.limbs,419 &bigint_buffer.limbs,
420 mod.global_error_set.getIndex(name).?,420 ip.getErrorValueIfExists(name).?,
421 ).toConst();421 ).toConst();
422 bigint.writeTwosComplement(buffer[0..byte_count], endian);422 bigint.writeTwosComplement(buffer[0..byte_count], endian);
423 },423 },
...@@ -427,7 +427,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro...@@ -427,7 +427,7 @@ pub fn writeToMemory(val: Value, ty: Type, pt: Zcu.PerThread, buffer: []u8) erro
427 if (val.unionTag(mod)) |union_tag| {427 if (val.unionTag(mod)) |union_tag| {
428 const union_obj = mod.typeToUnion(ty).?;428 const union_obj = mod.typeToUnion(ty).?;
429 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;429 const field_index = mod.unionTagFieldIndex(union_obj, union_tag).?;
430 const field_type = Type.fromInterned(union_obj.field_types.get(&mod.intern_pool)[field_index]);430 const field_type = Type.fromInterned(union_obj.field_types.get(ip)[field_index]);
431 const field_val = try val.fieldValue(pt, field_index);431 const field_val = try val.fieldValue(pt, field_index);
432 const byte_count: usize = @intCast(field_type.abiSize(pt));432 const byte_count: usize = @intCast(field_type.abiSize(pt));
433 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);433 return writeToMemory(field_val, field_type, pt, buffer[0..byte_count]);
...@@ -1455,9 +1455,9 @@ pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTermi...@@ -1455,9 +1455,9 @@ pub fn getErrorName(val: Value, mod: *const Module) InternPool.OptionalNullTermi
1455 };1455 };
1456}1456}
14571457
1458pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt {1458pub fn getErrorInt(val: Value, zcu: *Zcu) Module.ErrorInt {
1459 return if (getErrorName(val, mod).unwrap()) |err_name|1459 return if (getErrorName(val, zcu).unwrap()) |err_name|
1460 @intCast(mod.global_error_set.getIndex(err_name).?)1460 zcu.intern_pool.getErrorValueIfExists(err_name).?
1461 else1461 else
1462 0;1462 0;
1463}1463}
src/Zcu.zig+61-312
...@@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {...@@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct {
102/// `Compilation.update` of the process for a given `Compilation`.102/// `Compilation.update` of the process for a given `Compilation`.
103///103///
104/// Indexes correspond 1:1 to `files`.104/// Indexes correspond 1:1 to `files`.
105import_table: std.StringArrayHashMapUnmanaged(*File) = .{},105import_table: std.StringArrayHashMapUnmanaged(File.Index) = .{},
106106
107/// The set of all the files which have been loaded with `@embedFile` in the Module.107/// The set of all the files which have been loaded with `@embedFile` in the Module.
108/// We keep track of this in order to iterate over it and check which files have been108/// We keep track of this in order to iterate over it and check which files have been
...@@ -141,9 +141,6 @@ failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .{},...@@ -141,9 +141,6 @@ failed_exports: std.AutoArrayHashMapUnmanaged(u32, *ErrorMsg) = .{},
141/// are stored here.141/// are stored here.
142cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .{},142cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .{},
143143
144/// Key is the error name, index is the error tag value. Index 0 has a length-0 string.
145global_error_set: GlobalErrorSet = .{},
146
147/// Maximum amount of distinct error values, set by --error-limit144/// Maximum amount of distinct error values, set by --error-limit
148error_limit: ErrorInt,145error_limit: ErrorInt,
149146
...@@ -326,7 +323,10 @@ pub const Reference = struct {...@@ -326,7 +323,10 @@ pub const Reference = struct {
326};323};
327324
328pub const Decl = struct {325pub const Decl = struct {
326 /// Equal to `fqn` if already fully qualified.
329 name: InternPool.NullTerminatedString,327 name: InternPool.NullTerminatedString,
328 /// Fully qualified name.
329 fqn: InternPool.NullTerminatedString,
330 /// The most recent Value of the Decl after a successful semantic analysis.330 /// The most recent Value of the Decl after a successful semantic analysis.
331 /// Populated when `has_tv`.331 /// Populated when `has_tv`.
332 val: Value,332 val: Value,
...@@ -384,8 +384,6 @@ pub const Decl = struct {...@@ -384,8 +384,6 @@ pub const Decl = struct {
384 is_pub: bool,384 is_pub: bool,
385 /// Whether the corresponding AST decl has a `export` keyword.385 /// Whether the corresponding AST decl has a `export` keyword.
386 is_exported: bool,386 is_exported: bool,
387 /// If true `name` is already fully qualified.
388 name_fully_qualified: bool = false,
389 /// What kind of a declaration is this.387 /// What kind of a declaration is this.
390 kind: Kind,388 kind: Kind,
391389
...@@ -408,25 +406,6 @@ pub const Decl = struct {...@@ -408,25 +406,6 @@ pub const Decl = struct {
408 return extra.data.getBodies(@intCast(extra.end), zir);406 return extra.data.getBodies(@intCast(extra.end), zir);
409 }407 }
410408
411 pub fn renderFullyQualifiedName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
412 if (decl.name_fully_qualified) {
413 try writer.print("{}", .{decl.name.fmt(&zcu.intern_pool)});
414 } else {
415 try zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedName(zcu, decl.name, writer);
416 }
417 }
418
419 pub fn renderFullyQualifiedDebugName(decl: Decl, zcu: *Zcu, writer: anytype) !void {
420 return zcu.namespacePtr(decl.src_namespace).renderFullyQualifiedDebugName(zcu, decl.name, writer);
421 }
422
423 pub fn fullyQualifiedName(decl: Decl, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
424 return if (decl.name_fully_qualified)
425 decl.name
426 else
427 pt.zcu.namespacePtr(decl.src_namespace).fullyQualifiedName(pt, decl.name);
428 }
429
430 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {409 pub fn typeOf(decl: Decl, zcu: *const Zcu) Type {
431 assert(decl.has_tv);410 assert(decl.has_tv);
432 return decl.val.typeOf(zcu);411 return decl.val.typeOf(zcu);
...@@ -646,23 +625,27 @@ pub const Namespace = struct {...@@ -646,23 +625,27 @@ pub const Namespace = struct {
646 return zcu.fileByIndex(ns.file_scope);625 return zcu.fileByIndex(ns.file_scope);
647 }626 }
648627
628 pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File {
629 return ip.filePtr(ns.file_scope);
630 }
631
649 // This renders e.g. "std.fs.Dir.OpenOptions"632 // This renders e.g. "std.fs.Dir.OpenOptions"
650 pub fn renderFullyQualifiedName(633 pub fn renderFullyQualifiedName(
651 ns: Namespace,634 ns: Namespace,
652 zcu: *Zcu,635 ip: *InternPool,
653 name: InternPool.NullTerminatedString,636 name: InternPool.NullTerminatedString,
654 writer: anytype,637 writer: anytype,
655 ) @TypeOf(writer).Error!void {638 ) @TypeOf(writer).Error!void {
656 if (ns.parent.unwrap()) |parent| {639 if (ns.parent.unwrap()) |parent| {
657 try zcu.namespacePtr(parent).renderFullyQualifiedName(640 try ip.namespacePtr(parent).renderFullyQualifiedName(
658 zcu,641 ip,
659 zcu.declPtr(ns.decl_index).name,642 ip.declPtr(ns.decl_index).name,
660 writer,643 writer,
661 );644 );
662 } else {645 } else {
663 try ns.fileScope(zcu).renderFullyQualifiedName(writer);646 try ns.fileScopeIp(ip).renderFullyQualifiedName(writer);
664 }647 }
665 if (name != .empty) try writer.print(".{}", .{name.fmt(&zcu.intern_pool)});648 if (name != .empty) try writer.print(".{}", .{name.fmt(ip)});
666 }649 }
667650
668 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"651 /// This renders e.g. "std/fs.zig:Dir.OpenOptions"
...@@ -686,46 +669,45 @@ pub const Namespace = struct {...@@ -686,46 +669,45 @@ pub const Namespace = struct {
686 if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });669 if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) });
687 }670 }
688671
689 pub fn fullyQualifiedName(672 pub fn internFullyQualifiedName(
690 ns: Namespace,673 ns: Namespace,
691 pt: Zcu.PerThread,674 ip: *InternPool,
675 gpa: Allocator,
676 tid: Zcu.PerThread.Id,
692 name: InternPool.NullTerminatedString,677 name: InternPool.NullTerminatedString,
693 ) !InternPool.NullTerminatedString {678 ) !InternPool.NullTerminatedString {
694 const zcu = pt.zcu;679 const strings = ip.getLocal(tid).getMutableStrings(gpa);
695 const ip = &zcu.intern_pool;
696
697 const gpa = zcu.gpa;
698 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
699 // Protects reads of interned strings from being reallocated during the call to680 // Protects reads of interned strings from being reallocated during the call to
700 // renderFullyQualifiedName.681 // renderFullyQualifiedName.
701 const slice = try strings.addManyAsSlice(count: {682 const slice = try strings.addManyAsSlice(count: {
702 var count: usize = name.length(ip) + 1;683 var count: usize = name.length(ip) + 1;
703 var cur_ns = &ns;684 var cur_ns = &ns;
704 while (true) {685 while (true) {
705 const decl = zcu.declPtr(cur_ns.decl_index);686 const decl = ip.declPtr(cur_ns.decl_index);
706 cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse {687 cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse {
707 count += ns.fileScope(zcu).fullyQualifiedNameLen();688 count += ns.fileScopeIp(ip).fullyQualifiedNameLen();
708 break :count count;689 break :count count;
709 });690 });
710 count += decl.name.length(ip) + 1;691 count += decl.name.length(ip) + 1;
711 }692 }
712 });693 });
713 var fbs = std.io.fixedBufferStream(slice[0]);694 var fbs = std.io.fixedBufferStream(slice[0]);
714 ns.renderFullyQualifiedName(zcu, name, fbs.writer()) catch unreachable;695 ns.renderFullyQualifiedName(ip, name, fbs.writer()) catch unreachable;
715 assert(fbs.pos == slice[0].len);696 assert(fbs.pos == slice[0].len);
716697
717 // Sanitize the name for nvptx which is more restrictive.698 // Sanitize the name for nvptx which is more restrictive.
718 // TODO This should be handled by the backend, not the frontend. Have a699 // TODO This should be handled by the backend, not the frontend. Have a
719 // look at how the C backend does it for inspiration.700 // look at how the C backend does it for inspiration.
720 const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;701 // FIXME This has bitrotted and is no longer able to be implemented here.
721 if (cpu_arch.isNvptx()) {702 //const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch;
722 for (slice[0]) |*byte| switch (byte.*) {703 //if (cpu_arch.isNvptx()) {
723 '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',704 // for (slice[0]) |*byte| switch (byte.*) {
724 else => {},705 // '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_',
725 };706 // else => {},
726 }707 // };
708 //}
727709
728 return ip.getOrPutTrailingString(gpa, pt.tid, @intCast(slice[0].len), .no_embedded_nulls);710 return ip.getOrPutTrailingString(gpa, tid, @intCast(slice[0].len), .no_embedded_nulls);
729 }711 }
730712
731 pub fn getType(ns: Namespace, zcu: *Zcu) Type {713 pub fn getType(ns: Namespace, zcu: *Zcu) Type {
...@@ -882,7 +864,7 @@ pub const File = struct {...@@ -882,7 +864,7 @@ pub const File = struct {
882 };864 };
883 }865 }
884866
885 pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {867 pub fn internFullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString {
886 const gpa = pt.zcu.gpa;868 const gpa = pt.zcu.gpa;
887 const ip = &pt.zcu.intern_pool;869 const ip = &pt.zcu.intern_pool;
888 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);870 const strings = ip.getLocal(pt.tid).getMutableStrings(gpa);
...@@ -910,7 +892,7 @@ pub const File = struct {...@@ -910,7 +892,7 @@ pub const File = struct {
910 }892 }
911893
912 /// Add a reference to this file during AstGen.894 /// Add a reference to this file during AstGen.
913 pub fn addReference(file: *File, zcu: Zcu, ref: File.Reference) !void {895 pub fn addReference(file: *File, zcu: *Zcu, ref: File.Reference) !void {
914 // Don't add the same module root twice. Note that since we always add module roots at the896 // Don't add the same module root twice. Note that since we always add module roots at the
915 // front of the references array (see below), this loop is actually O(1) on valid code.897 // front of the references array (see below), this loop is actually O(1) on valid code.
916 if (ref == .root) {898 if (ref == .root) {
...@@ -942,7 +924,7 @@ pub const File = struct {...@@ -942,7 +924,7 @@ pub const File = struct {
942924
943 /// Mark this file and every file referenced by it as multi_pkg and report an925 /// Mark this file and every file referenced by it as multi_pkg and report an
944 /// astgen_failure error for them. AstGen must have completed in its entirety.926 /// astgen_failure error for them. AstGen must have completed in its entirety.
945 pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void {927 pub fn recursiveMarkMultiPkg(file: *File, pt: Zcu.PerThread) void {
946 file.multi_pkg = true;928 file.multi_pkg = true;
947 file.status = .astgen_failure;929 file.status = .astgen_failure;
948930
...@@ -962,9 +944,9 @@ pub const File = struct {...@@ -962,9 +944,9 @@ pub const File = struct {
962 const import_path = file.zir.nullTerminatedString(item.data.name);944 const import_path = file.zir.nullTerminatedString(item.data.name);
963 if (mem.eql(u8, import_path, "builtin")) continue;945 if (mem.eql(u8, import_path, "builtin")) continue;
964946
965 const res = mod.importFile(file, import_path) catch continue;947 const res = pt.importFile(file, import_path) catch continue;
966 if (!res.is_pkg and !res.file.multi_pkg) {948 if (!res.is_pkg and !res.file.multi_pkg) {
967 res.file.recursiveMarkMultiPkg(mod);949 res.file.recursiveMarkMultiPkg(pt);
968 }950 }
969 }951 }
970 }952 }
...@@ -1033,6 +1015,14 @@ pub const ErrorMsg = struct {...@@ -1033,6 +1015,14 @@ pub const ErrorMsg = struct {
1033 }1015 }
1034};1016};
10351017
1018pub const AstGenSrc = union(enum) {
1019 root,
1020 import: struct {
1021 importing_file: Zcu.File.Index,
1022 import_tok: std.zig.Ast.TokenIndex,
1023 },
1024};
1025
1036/// Canonical reference to a position within a source file.1026/// Canonical reference to a position within a source file.
1037pub const SrcLoc = struct {1027pub const SrcLoc = struct {
1038 file_scope: *File,1028 file_scope: *File,
...@@ -2406,7 +2396,6 @@ pub const CompileError = error{...@@ -2406,7 +2396,6 @@ pub const CompileError = error{
2406pub fn init(mod: *Module, thread_count: usize) !void {2396pub fn init(mod: *Module, thread_count: usize) !void {
2407 const gpa = mod.gpa;2397 const gpa = mod.gpa;
2408 try mod.intern_pool.init(gpa, thread_count);2398 try mod.intern_pool.init(gpa, thread_count);
2409 try mod.global_error_set.put(gpa, .empty, {});
2410}2399}
24112400
2412pub fn deinit(zcu: *Zcu) void {2401pub fn deinit(zcu: *Zcu) void {
...@@ -2421,8 +2410,7 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2421,8 +2410,7 @@ pub fn deinit(zcu: *Zcu) void {
2421 for (zcu.import_table.keys()) |key| {2410 for (zcu.import_table.keys()) |key| {
2422 gpa.free(key);2411 gpa.free(key);
2423 }2412 }
2424 for (0..zcu.import_table.entries.len) |file_index_usize| {2413 for (zcu.import_table.values()) |file_index| {
2425 const file_index: File.Index = @enumFromInt(file_index_usize);
2426 pt.destroyFile(file_index);2414 pt.destroyFile(file_index);
2427 }2415 }
2428 zcu.import_table.deinit(gpa);2416 zcu.import_table.deinit(gpa);
...@@ -2479,8 +2467,6 @@ pub fn deinit(zcu: *Zcu) void {...@@ -2479,8 +2467,6 @@ pub fn deinit(zcu: *Zcu) void {
2479 zcu.single_exports.deinit(gpa);2467 zcu.single_exports.deinit(gpa);
2480 zcu.multi_exports.deinit(gpa);2468 zcu.multi_exports.deinit(gpa);
24812469
2482 zcu.global_error_set.deinit(gpa);
2483
2484 zcu.potentially_outdated.deinit(gpa);2470 zcu.potentially_outdated.deinit(gpa);
2485 zcu.outdated.deinit(gpa);2471 zcu.outdated.deinit(gpa);
2486 zcu.outdated_ready.deinit(gpa);2472 zcu.outdated_ready.deinit(gpa);
...@@ -3020,183 +3006,7 @@ pub const ImportFileResult = struct {...@@ -3020,183 +3006,7 @@ pub const ImportFileResult = struct {
3020 is_pkg: bool,3006 is_pkg: bool,
3021};3007};
30223008
3023pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {3009pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
3024 const gpa = zcu.gpa;
3025
3026 // The resolved path is used as the key in the import table, to detect if
3027 // an import refers to the same as another, despite different relative paths
3028 // or differently mapped package names.
3029 const resolved_path = try std.fs.path.resolve(gpa, &.{
3030 mod.root.root_dir.path orelse ".",
3031 mod.root.sub_path,
3032 mod.root_src_path,
3033 });
3034 var keep_resolved_path = false;
3035 defer if (!keep_resolved_path) gpa.free(resolved_path);
3036
3037 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3038 errdefer _ = zcu.import_table.pop();
3039 if (gop.found_existing) {
3040 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
3041 return .{
3042 .file = gop.value_ptr.*,
3043 .file_index = @enumFromInt(gop.index),
3044 .is_new = false,
3045 .is_pkg = true,
3046 };
3047 }
3048
3049 const ip = &zcu.intern_pool;
3050
3051 try ip.files.ensureUnusedCapacity(gpa, 1);
3052
3053 if (mod.builtin_file) |builtin_file| {
3054 keep_resolved_path = true; // It's now owned by import_table.
3055 gop.value_ptr.* = builtin_file;
3056 try builtin_file.addReference(zcu.*, .{ .root = mod });
3057 const path_digest = computePathDigest(zcu, mod, builtin_file.sub_file_path);
3058 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3059 return .{
3060 .file = builtin_file,
3061 .file_index = @enumFromInt(ip.files.entries.len - 1),
3062 .is_new = false,
3063 .is_pkg = true,
3064 };
3065 }
3066
3067 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
3068 errdefer gpa.free(sub_file_path);
3069
3070 const new_file = try gpa.create(File);
3071 errdefer gpa.destroy(new_file);
3072
3073 keep_resolved_path = true; // It's now owned by import_table.
3074 gop.value_ptr.* = new_file;
3075 new_file.* = .{
3076 .sub_file_path = sub_file_path,
3077 .source = undefined,
3078 .source_loaded = false,
3079 .tree_loaded = false,
3080 .zir_loaded = false,
3081 .stat = undefined,
3082 .tree = undefined,
3083 .zir = undefined,
3084 .status = .never_loaded,
3085 .mod = mod,
3086 };
3087
3088 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3089
3090 try new_file.addReference(zcu.*, .{ .root = mod });
3091 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3092 return .{
3093 .file = new_file,
3094 .file_index = @enumFromInt(ip.files.entries.len - 1),
3095 .is_new = true,
3096 .is_pkg = true,
3097 };
3098}
3099
3100/// Called from a worker thread during AstGen.
3101/// Also called from Sema during semantic analysis.
3102pub fn importFile(
3103 zcu: *Zcu,
3104 cur_file: *File,
3105 import_string: []const u8,
3106) !ImportFileResult {
3107 const mod = cur_file.mod;
3108
3109 if (std.mem.eql(u8, import_string, "std")) {
3110 return zcu.importPkg(zcu.std_mod);
3111 }
3112 if (std.mem.eql(u8, import_string, "root")) {
3113 return zcu.importPkg(zcu.root_mod);
3114 }
3115 if (mod.deps.get(import_string)) |pkg| {
3116 return zcu.importPkg(pkg);
3117 }
3118 if (!mem.endsWith(u8, import_string, ".zig")) {
3119 return error.ModuleNotFound;
3120 }
3121 const gpa = zcu.gpa;
3122
3123 // The resolved path is used as the key in the import table, to detect if
3124 // an import refers to the same as another, despite different relative paths
3125 // or differently mapped package names.
3126 const resolved_path = try std.fs.path.resolve(gpa, &.{
3127 mod.root.root_dir.path orelse ".",
3128 mod.root.sub_path,
3129 cur_file.sub_file_path,
3130 "..",
3131 import_string,
3132 });
3133
3134 var keep_resolved_path = false;
3135 defer if (!keep_resolved_path) gpa.free(resolved_path);
3136
3137 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3138 errdefer _ = zcu.import_table.pop();
3139 if (gop.found_existing) return .{
3140 .file = gop.value_ptr.*,
3141 .file_index = @enumFromInt(gop.index),
3142 .is_new = false,
3143 .is_pkg = false,
3144 };
3145
3146 const ip = &zcu.intern_pool;
3147
3148 try ip.files.ensureUnusedCapacity(gpa, 1);
3149
3150 const new_file = try gpa.create(File);
3151 errdefer gpa.destroy(new_file);
3152
3153 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
3154 mod.root.root_dir.path orelse ".",
3155 mod.root.sub_path,
3156 });
3157 defer gpa.free(resolved_root_path);
3158
3159 const sub_file_path = p: {
3160 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
3161 errdefer gpa.free(relative);
3162
3163 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
3164 break :p relative;
3165 }
3166 return error.ImportOutsideModulePath;
3167 };
3168 errdefer gpa.free(sub_file_path);
3169
3170 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
3171 resolved_root_path, resolved_path, sub_file_path, import_string,
3172 });
3173
3174 keep_resolved_path = true; // It's now owned by import_table.
3175 gop.value_ptr.* = new_file;
3176 new_file.* = .{
3177 .sub_file_path = sub_file_path,
3178 .source = undefined,
3179 .source_loaded = false,
3180 .tree_loaded = false,
3181 .zir_loaded = false,
3182 .stat = undefined,
3183 .tree = undefined,
3184 .zir = undefined,
3185 .status = .never_loaded,
3186 .mod = mod,
3187 };
3188
3189 const path_digest = computePathDigest(zcu, mod, sub_file_path);
3190 ip.files.putAssumeCapacityNoClobber(path_digest, .none);
3191 return .{
3192 .file = new_file,
3193 .file_index = @enumFromInt(ip.files.entries.len - 1),
3194 .is_new = true,
3195 .is_pkg = false,
3196 };
3197}
3198
3199fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest {
3200 const want_local_cache = mod == zcu.main_mod;3010 const want_local_cache = mod == zcu.main_mod;
3201 var path_hash: Cache.HashHelper = .{};3011 var path_hash: Cache.HashHelper = .{};
3202 path_hash.addBytes(build_options.version);3012 path_hash.addBytes(build_options.version);
...@@ -3292,43 +3102,11 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit...@@ -3292,43 +3102,11 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit
3292 gop.value_ptr.* = @intCast(ref_idx);3102 gop.value_ptr.* = @intCast(ref_idx);
3293}3103}
32943104
3295pub fn getErrorValue(
3296 mod: *Module,
3297 name: InternPool.NullTerminatedString,
3298) Allocator.Error!ErrorInt {
3299 const gop = try mod.global_error_set.getOrPut(mod.gpa, name);
3300 return @as(ErrorInt, @intCast(gop.index));
3301}
3302
3303pub fn getErrorValueFromSlice(
3304 mod: *Module,
3305 name: []const u8,
3306) Allocator.Error!ErrorInt {
3307 const interned_name = try mod.intern_pool.getOrPutString(mod.gpa, name);
3308 return getErrorValue(mod, interned_name);
3309}
3310
3311pub fn errorSetBits(mod: *Module) u16 {3105pub fn errorSetBits(mod: *Module) u16 {
3312 if (mod.error_limit == 0) return 0;3106 if (mod.error_limit == 0) return 0;
3313 return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error3107 return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error
3314}3108}
33153109
3316pub fn initNewAnonDecl(
3317 mod: *Module,
3318 new_decl_index: Decl.Index,
3319 val: Value,
3320 name: InternPool.NullTerminatedString,
3321) Allocator.Error!void {
3322 const new_decl = mod.declPtr(new_decl_index);
3323
3324 new_decl.name = name;
3325 new_decl.val = val;
3326 new_decl.alignment = .none;
3327 new_decl.@"linksection" = .none;
3328 new_decl.has_tv = true;
3329 new_decl.analysis = .complete;
3330}
3331
3332pub fn errNote(3110pub fn errNote(
3333 mod: *Module,3111 mod: *Module,
3334 src_loc: LazySrcLoc,3112 src_loc: LazySrcLoc,
...@@ -3394,41 +3172,6 @@ pub fn handleUpdateExports(...@@ -3394,41 +3172,6 @@ pub fn handleUpdateExports(
3394 };3172 };
3395}3173}
33963174
3397pub fn reportRetryableFileError(
3398 zcu: *Zcu,
3399 file_index: File.Index,
3400 comptime format: []const u8,
3401 args: anytype,
3402) error{OutOfMemory}!void {
3403 const gpa = zcu.gpa;
3404 const ip = &zcu.intern_pool;
3405
3406 const file = zcu.fileByIndex(file_index);
3407 file.status = .retryable_failure;
3408
3409 const err_msg = try ErrorMsg.create(
3410 gpa,
3411 .{
3412 .base_node_inst = try ip.trackZir(gpa, file_index, .main_struct_inst),
3413 .offset = .entire_file,
3414 },
3415 format,
3416 args,
3417 );
3418 errdefer err_msg.destroy(gpa);
3419
3420 zcu.comp.mutex.lock();
3421 defer zcu.comp.mutex.unlock();
3422
3423 const gop = try zcu.failed_files.getOrPut(gpa, file);
3424 if (gop.found_existing) {
3425 if (gop.value_ptr.*) |old_err_msg| {
3426 old_err_msg.destroy(gpa);
3427 }
3428 }
3429 gop.value_ptr.* = err_msg;
3430}
3431
3432pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {3175pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void {
3433 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);3176 const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index);
3434 if (gop.found_existing) {3177 if (gop.found_existing) {
...@@ -3744,22 +3487,28 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved...@@ -3744,22 +3487,28 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved
3744 return result;3487 return result;
3745}3488}
37463489
3747pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File {3490pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File {
3748 return zcu.import_table.values()[@intFromEnum(i)];3491 return zcu.intern_pool.filePtr(file_index);
3749}3492}
37503493
3751/// Returns the `Decl` of the struct that represents this `File`.3494/// Returns the `Decl` of the struct that represents this `File`.
3752pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex {3495pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex {
3753 const ip = &zcu.intern_pool;3496 const ip = &zcu.intern_pool;
3754 return ip.files.values()[@intFromEnum(i)];3497 const file_index_unwrapped = file_index.unwrap(ip);
3498 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3499 return files.view().items(.root_decl)[file_index_unwrapped.index];
3755}3500}
37563501
3757pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void {3502pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void {
3758 const ip = &zcu.intern_pool;3503 const ip = &zcu.intern_pool;
3759 ip.files.values()[@intFromEnum(i)] = root_decl;3504 const file_index_unwrapped = file_index.unwrap(ip);
3505 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3506 files.view().items(.root_decl)[file_index_unwrapped.index] = root_decl;
3760}3507}
37613508
3762pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest {3509pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest {
3763 const ip = &zcu.intern_pool;3510 const ip = &zcu.intern_pool;
3764 return ip.files.keys()[@intFromEnum(i)];3511 const file_index_unwrapped = file_index.unwrap(ip);
3512 const files = ip.getLocalShared(file_index_unwrapped.tid).files.acquire();
3513 return files.view().items(.bin_digest)[file_index_unwrapped.index];
3765}3514}
src/Zcu/PerThread.zig+458-137
...@@ -342,6 +342,7 @@ pub fn astGenFile(...@@ -342,6 +342,7 @@ pub fn astGenFile(
342/// the Compilation mutex when acting on shared state.342/// the Compilation mutex when acting on shared state.
343fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {343fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void {
344 const zcu = pt.zcu;344 const zcu = pt.zcu;
345 const ip = &zcu.intern_pool;
345 const gpa = zcu.gpa;346 const gpa = zcu.gpa;
346 const new_zir = file.zir;347 const new_zir = file.zir;
347348
...@@ -355,109 +356,117 @@ fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index,...@@ -355,109 +356,117 @@ fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index,
355356
356 // TODO: this should be done after all AstGen workers complete, to avoid357 // TODO: this should be done after all AstGen workers complete, to avoid
357 // iterating over this full set for every updated file.358 // iterating over this full set for every updated file.
358 for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| {359 for (ip.locals, 0..) |*local, tid| {
359 const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw);360 local.mutate.tracked_insts.mutex.lock();
360 if (ti.file != file_index) continue;361 defer local.mutate.tracked_insts.mutex.unlock();
361 const old_inst = ti.inst;362 const tracked_insts_list = local.getMutableTrackedInsts(gpa);
362 ti.inst = inst_map.get(ti.inst) orelse {363 for (tracked_insts_list.view().items(.@"0"), 0..) |*tracked_inst, tracked_inst_unwrapped_index| {
363 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.364 if (tracked_inst.file != file_index) continue;
364 zcu.comp.mutex.lock();365 const old_inst = tracked_inst.inst;
365 defer zcu.comp.mutex.unlock();366 const tracked_inst_index = (InternPool.TrackedInst.Index.Unwrapped{
366 log.debug("tracking failed for %{d}", .{old_inst});367 .tid = @enumFromInt(tid),
367 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });368 .index = @intCast(tracked_inst_unwrapped_index),
368 continue;369 }).wrap(ip);
369 };370 tracked_inst.inst = inst_map.get(old_inst) orelse {
371 // Tracking failed for this instruction. Invalidate associated `src_hash` deps.
372 zcu.comp.mutex.lock();
373 defer zcu.comp.mutex.unlock();
374 log.debug("tracking failed for %{d}", .{old_inst});
375 try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
376 continue;
377 };
370378
371 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {379 if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: {
372 if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| {380 if (new_zir.getAssociatedSrcHash(tracked_inst.inst)) |new_hash| {
373 if (std.zig.srcHashEql(old_hash, new_hash)) {381 if (std.zig.srcHashEql(old_hash, new_hash)) {
374 break :hash_changed;382 break :hash_changed;
383 }
384 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{
385 old_inst,
386 tracked_inst.inst,
387 std.fmt.fmtSliceHexLower(&old_hash),
388 std.fmt.fmtSliceHexLower(&new_hash),
389 });
375 }390 }
376 log.debug("hash for (%{d} -> %{d}) changed: {} -> {}", .{391 // The source hash associated with this instruction changed - invalidate relevant dependencies.
377 old_inst,392 zcu.comp.mutex.lock();
378 ti.inst,393 defer zcu.comp.mutex.unlock();
379 std.fmt.fmtSliceHexLower(&old_hash),394 try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index });
380 std.fmt.fmtSliceHexLower(&new_hash),
381 });
382 }395 }
383 // The source hash associated with this instruction changed - invalidate relevant dependencies.
384 zcu.comp.mutex.lock();
385 defer zcu.comp.mutex.unlock();
386 try zcu.markDependeeOutdated(.{ .src_hash = ti_idx });
387 }
388396
389 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.397 // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies.
390 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {398 const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) {
391 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {399 .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) {
392 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,400 .struct_decl, .union_decl, .opaque_decl, .enum_decl => true,
401 else => false,
402 },
393 else => false,403 else => false,
394 },404 };
395 else => false,405 if (!has_namespace) continue;
396 };406
397 if (!has_namespace) continue;407 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};
398408 defer old_names.deinit(zcu.gpa);
399 var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{};409 {
400 defer old_names.deinit(zcu.gpa);410 var it = old_zir.declIterator(old_inst);
401 {411 while (it.next()) |decl_inst| {
402 var it = old_zir.declIterator(old_inst);412 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
403 while (it.next()) |decl_inst| {413 switch (decl_name) {
404 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;414 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
405 switch (decl_name) {415 _ => if (decl_name.isNamedTest(old_zir)) continue,
406 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,416 }
407 _ => if (decl_name.isNamedTest(old_zir)) continue,417 const name_zir = decl_name.toString(old_zir).?;
418 const name_ip = try zcu.intern_pool.getOrPutString(
419 zcu.gpa,
420 pt.tid,
421 old_zir.nullTerminatedString(name_zir),
422 .no_embedded_nulls,
423 );
424 try old_names.put(zcu.gpa, name_ip, {});
408 }425 }
409 const name_zir = decl_name.toString(old_zir).?;
410 const name_ip = try zcu.intern_pool.getOrPutString(
411 zcu.gpa,
412 pt.tid,
413 old_zir.nullTerminatedString(name_zir),
414 .no_embedded_nulls,
415 );
416 try old_names.put(zcu.gpa, name_ip, {});
417 }426 }
418 }427 var any_change = false;
419 var any_change = false;428 {
420 {429 var it = new_zir.declIterator(tracked_inst.inst);
421 var it = new_zir.declIterator(ti.inst);430 while (it.next()) |decl_inst| {
422 while (it.next()) |decl_inst| {431 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;
423 const decl_name = old_zir.getDeclaration(decl_inst)[0].name;432 switch (decl_name) {
424 switch (decl_name) {433 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,
425 .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue,434 _ => if (decl_name.isNamedTest(old_zir)) continue,
426 _ => if (decl_name.isNamedTest(old_zir)) continue,435 }
436 const name_zir = decl_name.toString(old_zir).?;
437 const name_ip = try zcu.intern_pool.getOrPutString(
438 zcu.gpa,
439 pt.tid,
440 old_zir.nullTerminatedString(name_zir),
441 .no_embedded_nulls,
442 );
443 if (!old_names.swapRemove(name_ip)) continue;
444 // Name added
445 any_change = true;
446 zcu.comp.mutex.lock();
447 defer zcu.comp.mutex.unlock();
448 try zcu.markDependeeOutdated(.{ .namespace_name = .{
449 .namespace = tracked_inst_index,
450 .name = name_ip,
451 } });
427 }452 }
428 const name_zir = decl_name.toString(old_zir).?;453 }
429 const name_ip = try zcu.intern_pool.getOrPutString(454 // The only elements remaining in `old_names` now are any names which were removed.
430 zcu.gpa,455 for (old_names.keys()) |name_ip| {
431 pt.tid,
432 old_zir.nullTerminatedString(name_zir),
433 .no_embedded_nulls,
434 );
435 if (!old_names.swapRemove(name_ip)) continue;
436 // Name added
437 any_change = true;456 any_change = true;
438 zcu.comp.mutex.lock();457 zcu.comp.mutex.lock();
439 defer zcu.comp.mutex.unlock();458 defer zcu.comp.mutex.unlock();
440 try zcu.markDependeeOutdated(.{ .namespace_name = .{459 try zcu.markDependeeOutdated(.{ .namespace_name = .{
441 .namespace = ti_idx,460 .namespace = tracked_inst_index,
442 .name = name_ip,461 .name = name_ip,
443 } });462 } });
444 }463 }
445 }
446 // The only elements remaining in `old_names` now are any names which were removed.
447 for (old_names.keys()) |name_ip| {
448 any_change = true;
449 zcu.comp.mutex.lock();
450 defer zcu.comp.mutex.unlock();
451 try zcu.markDependeeOutdated(.{ .namespace_name = .{
452 .namespace = ti_idx,
453 .name = name_ip,
454 } });
455 }
456464
457 if (any_change) {465 if (any_change) {
458 zcu.comp.mutex.lock();466 zcu.comp.mutex.lock();
459 defer zcu.comp.mutex.unlock();467 defer zcu.comp.mutex.unlock();
460 try zcu.markDependeeOutdated(.{ .namespace = ti_idx });468 try zcu.markDependeeOutdated(.{ .namespace = tracked_inst_index });
469 }
461 }470 }
462 }471 }
463}472}
...@@ -548,7 +557,7 @@ pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.Sem...@@ -548,7 +557,7 @@ pub fn ensureDeclAnalyzed(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Zcu.Sem
548 };557 };
549 }558 }
550559
551 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);560 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
552 defer decl_prog_node.end();561 defer decl_prog_node.end();
553562
554 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {563 break :blk pt.semaDecl(decl_index) catch |err| switch (err) {
...@@ -747,10 +756,9 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -747,10 +756,9 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
747 defer liveness.deinit(gpa);756 defer liveness.deinit(gpa);
748757
749 if (build_options.enable_debug_extensions and comp.verbose_air) {758 if (build_options.enable_debug_extensions and comp.verbose_air) {
750 const fqn = try decl.fullyQualifiedName(pt);759 std.debug.print("# Begin Function AIR: {}:\n", .{decl.fqn.fmt(ip)});
751 std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)});
752 @import("../print_air.zig").dump(pt, air, liveness);760 @import("../print_air.zig").dump(pt, air, liveness);
753 std.debug.print("# End Function AIR: {}\n\n", .{fqn.fmt(ip)});761 std.debug.print("# End Function AIR: {}\n\n", .{decl.fqn.fmt(ip)});
754 }762 }
755763
756 if (std.debug.runtime_safety) {764 if (std.debug.runtime_safety) {
...@@ -781,7 +789,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -781,7 +789,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
781 };789 };
782 }790 }
783791
784 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);792 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(ip), 0);
785 defer codegen_prog_node.end();793 defer codegen_prog_node.end();
786794
787 if (!air.typesFullyResolved(zcu)) {795 if (!air.typesFullyResolved(zcu)) {
...@@ -818,7 +826,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai...@@ -818,7 +826,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai
818826
819/// https://github.com/ziglang/zig/issues/14307827/// https://github.com/ziglang/zig/issues/14307
820pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {828pub fn semaPkg(pt: Zcu.PerThread, pkg: *Module) !void {
821 const import_file_result = try pt.zcu.importPkg(pkg);829 const import_file_result = try pt.importPkg(pkg);
822 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);830 const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index);
823 if (root_decl_index == .none) {831 if (root_decl_index == .none) {
824 return pt.semaFile(import_file_result.file_index);832 return pt.semaFile(import_file_result.file_index);
...@@ -855,7 +863,10 @@ fn getFileRootStruct(...@@ -855,7 +863,10 @@ fn getFileRootStruct(
855 const decls = file.zir.bodySlice(extra_index, decls_len);863 const decls = file.zir.bodySlice(extra_index, decls_len);
856 extra_index += decls_len;864 extra_index += decls_len;
857865
858 const tracked_inst = try ip.trackZir(gpa, file_index, .main_struct_inst);866 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
867 .file = file_index,
868 .inst = .main_struct_inst,
869 });
859 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{870 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
860 .layout = .auto,871 .layout = .auto,
861 .fields_len = fields_len,872 .fields_len = fields_len,
...@@ -996,8 +1007,8 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -996,8 +1007,8 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
996 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());1007 zcu.setFileRootDecl(file_index, new_decl_index.toOptional());
997 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;1008 zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index;
9981009
999 new_decl.name = try file.fullyQualifiedName(pt);1010 new_decl.fqn = try file.internFullyQualifiedName(pt);
1000 new_decl.name_fully_qualified = true;1011 new_decl.name = new_decl.fqn;
1001 new_decl.is_pub = true;1012 new_decl.is_pub = true;
1002 new_decl.is_exported = false;1013 new_decl.is_exported = false;
1003 new_decl.alignment = .none;1014 new_decl.alignment = .none;
...@@ -1016,7 +1027,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1016,7 +1027,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1016 switch (zcu.comp.cache_use) {1027 switch (zcu.comp.cache_use) {
1017 .whole => |whole| if (whole.cache_manifest) |man| {1028 .whole => |whole| if (whole.cache_manifest) |man| {
1018 const source = file.getSource(gpa) catch |err| {1029 const source = file.getSource(gpa) catch |err| {
1019 try Zcu.reportRetryableFileError(zcu, file_index, "unable to load source: {s}", .{@errorName(err)});1030 try pt.reportRetryableFileError(file_index, "unable to load source: {s}", .{@errorName(err)});
1020 return error.AnalysisFail;1031 return error.AnalysisFail;
1021 };1032 };
10221033
...@@ -1025,7 +1036,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {...@@ -1025,7 +1036,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void {
1025 file.mod.root.sub_path,1036 file.mod.root.sub_path,
1026 file.sub_file_path,1037 file.sub_file_path,
1027 }) catch |err| {1038 }) catch |err| {
1028 try Zcu.reportRetryableFileError(zcu, file_index, "unable to resolve path: {s}", .{@errorName(err)});1039 try pt.reportRetryableFileError(file_index, "unable to resolve path: {s}", .{@errorName(err)});
1029 return error.AnalysisFail;1040 return error.AnalysisFail;
1030 };1041 };
1031 errdefer gpa.free(resolved_path);1042 errdefer gpa.free(resolved_path);
...@@ -1058,10 +1069,8 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1058,10 +1069,8 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1058 }1069 }
10591070
1060 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});1071 log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)});
1061 log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});1072 log.debug("decl name '{}'", .{decl.fqn.fmt(ip)});
1062 defer blk: {1073 defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)});
1063 log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1064 }
10651074
1066 const old_has_tv = decl.has_tv;1075 const old_has_tv = decl.has_tv;
1067 // The following values are ignored if `!old_has_tv`1076 // The following values are ignored if `!old_has_tv`
...@@ -1084,7 +1093,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1084,7 +1093,7 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1084 const std_mod = zcu.std_mod;1093 const std_mod = zcu.std_mod;
1085 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;1094 if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none;
1086 // We're in the std module.1095 // We're in the std module.
1087 const std_file_imported = try zcu.importPkg(std_mod);1096 const std_file_imported = try pt.importPkg(std_mod);
1088 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);1097 const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index);
1089 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);1098 const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?);
1090 const std_namespace = std_decl.getInnerNamespace(zcu).?;1099 const std_namespace = std_decl.getInnerNamespace(zcu).?;
...@@ -1151,11 +1160,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {...@@ -1151,11 +1160,10 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult {
1151 defer sema.deinit();1160 defer sema.deinit();
11521161
1153 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.1162 // Every Decl (other than file root Decls, which do not have a ZIR index) has a dependency on its own source.
1154 try sema.declareDependency(.{ .src_hash = try ip.trackZir(1163 try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{
1155 gpa,1164 .file = decl.getFileScopeIndex(zcu),
1156 decl.getFileScopeIndex(zcu),1165 .inst = decl_inst,
1157 decl_inst,1166 }) });
1158 ) });
11591167
1160 var block_scope: Sema.Block = .{1168 var block_scope: Sema.Block = .{
1161 .parent = null,1169 .parent = null,
...@@ -1359,6 +1367,195 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem...@@ -1359,6 +1367,195 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem
1359 };1367 };
1360}1368}
13611369
1370pub fn importPkg(pt: Zcu.PerThread, mod: *Module) !Zcu.ImportFileResult {
1371 const zcu = pt.zcu;
1372 const gpa = zcu.gpa;
1373
1374 // The resolved path is used as the key in the import table, to detect if
1375 // an import refers to the same as another, despite different relative paths
1376 // or differently mapped package names.
1377 const resolved_path = try std.fs.path.resolve(gpa, &.{
1378 mod.root.root_dir.path orelse ".",
1379 mod.root.sub_path,
1380 mod.root_src_path,
1381 });
1382 var keep_resolved_path = false;
1383 defer if (!keep_resolved_path) gpa.free(resolved_path);
1384
1385 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1386 errdefer _ = zcu.import_table.pop();
1387 if (gop.found_existing) {
1388 const file_index = gop.value_ptr.*;
1389 const file = zcu.fileByIndex(file_index);
1390 try file.addReference(zcu, .{ .root = mod });
1391 return .{
1392 .file = file,
1393 .file_index = file_index,
1394 .is_new = false,
1395 .is_pkg = true,
1396 };
1397 }
1398
1399 const ip = &zcu.intern_pool;
1400 if (mod.builtin_file) |builtin_file| {
1401 const path_digest = Zcu.computePathDigest(zcu, mod, builtin_file.sub_file_path);
1402 const file_index = try ip.createFile(gpa, pt.tid, .{
1403 .bin_digest = path_digest,
1404 .file = builtin_file,
1405 .root_decl = .none,
1406 });
1407 keep_resolved_path = true; // It's now owned by import_table.
1408 gop.value_ptr.* = file_index;
1409 try builtin_file.addReference(zcu, .{ .root = mod });
1410 return .{
1411 .file = builtin_file,
1412 .file_index = file_index,
1413 .is_new = false,
1414 .is_pkg = true,
1415 };
1416 }
1417
1418 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
1419 errdefer gpa.free(sub_file_path);
1420
1421 const new_file = try gpa.create(Zcu.File);
1422 errdefer gpa.destroy(new_file);
1423
1424 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1425 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1426 .bin_digest = path_digest,
1427 .file = new_file,
1428 .root_decl = .none,
1429 });
1430 keep_resolved_path = true; // It's now owned by import_table.
1431 gop.value_ptr.* = new_file_index;
1432 new_file.* = .{
1433 .sub_file_path = sub_file_path,
1434 .source = undefined,
1435 .source_loaded = false,
1436 .tree_loaded = false,
1437 .zir_loaded = false,
1438 .stat = undefined,
1439 .tree = undefined,
1440 .zir = undefined,
1441 .status = .never_loaded,
1442 .mod = mod,
1443 };
1444
1445 try new_file.addReference(zcu, .{ .root = mod });
1446 return .{
1447 .file = new_file,
1448 .file_index = new_file_index,
1449 .is_new = true,
1450 .is_pkg = true,
1451 };
1452}
1453
1454/// Called from a worker thread during AstGen.
1455/// Also called from Sema during semantic analysis.
1456pub fn importFile(
1457 pt: Zcu.PerThread,
1458 cur_file: *Zcu.File,
1459 import_string: []const u8,
1460) !Zcu.ImportFileResult {
1461 const zcu = pt.zcu;
1462 const mod = cur_file.mod;
1463
1464 if (std.mem.eql(u8, import_string, "std")) {
1465 return pt.importPkg(zcu.std_mod);
1466 }
1467 if (std.mem.eql(u8, import_string, "root")) {
1468 return pt.importPkg(zcu.root_mod);
1469 }
1470 if (mod.deps.get(import_string)) |pkg| {
1471 return pt.importPkg(pkg);
1472 }
1473 if (!std.mem.endsWith(u8, import_string, ".zig")) {
1474 return error.ModuleNotFound;
1475 }
1476 const gpa = zcu.gpa;
1477
1478 // The resolved path is used as the key in the import table, to detect if
1479 // an import refers to the same as another, despite different relative paths
1480 // or differently mapped package names.
1481 const resolved_path = try std.fs.path.resolve(gpa, &.{
1482 mod.root.root_dir.path orelse ".",
1483 mod.root.sub_path,
1484 cur_file.sub_file_path,
1485 "..",
1486 import_string,
1487 });
1488
1489 var keep_resolved_path = false;
1490 defer if (!keep_resolved_path) gpa.free(resolved_path);
1491
1492 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
1493 errdefer _ = zcu.import_table.pop();
1494 if (gop.found_existing) {
1495 const file_index = gop.value_ptr.*;
1496 return .{
1497 .file = zcu.fileByIndex(file_index),
1498 .file_index = file_index,
1499 .is_new = false,
1500 .is_pkg = false,
1501 };
1502 }
1503
1504 const ip = &zcu.intern_pool;
1505
1506 const new_file = try gpa.create(Zcu.File);
1507 errdefer gpa.destroy(new_file);
1508
1509 const resolved_root_path = try std.fs.path.resolve(gpa, &.{
1510 mod.root.root_dir.path orelse ".",
1511 mod.root.sub_path,
1512 });
1513 defer gpa.free(resolved_root_path);
1514
1515 const sub_file_path = p: {
1516 const relative = try std.fs.path.relative(gpa, resolved_root_path, resolved_path);
1517 errdefer gpa.free(relative);
1518
1519 if (!isUpDir(relative) and !std.fs.path.isAbsolute(relative)) {
1520 break :p relative;
1521 }
1522 return error.ImportOutsideModulePath;
1523 };
1524 errdefer gpa.free(sub_file_path);
1525
1526 log.debug("new importFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, import_string={s}", .{
1527 resolved_root_path, resolved_path, sub_file_path, import_string,
1528 });
1529
1530 const path_digest = zcu.computePathDigest(mod, sub_file_path);
1531 const new_file_index = try ip.createFile(gpa, pt.tid, .{
1532 .bin_digest = path_digest,
1533 .file = new_file,
1534 .root_decl = .none,
1535 });
1536 keep_resolved_path = true; // It's now owned by import_table.
1537 gop.value_ptr.* = new_file_index;
1538 new_file.* = .{
1539 .sub_file_path = sub_file_path,
1540 .source = undefined,
1541 .source_loaded = false,
1542 .tree_loaded = false,
1543 .zir_loaded = false,
1544 .stat = undefined,
1545 .tree = undefined,
1546 .zir = undefined,
1547 .status = .never_loaded,
1548 .mod = mod,
1549 };
1550
1551 return .{
1552 .file = new_file,
1553 .file_index = new_file_index,
1554 .is_new = true,
1555 .is_pkg = false,
1556 };
1557}
1558
1362pub fn embedFile(1559pub fn embedFile(
1363 pt: Zcu.PerThread,1560 pt: Zcu.PerThread,
1364 cur_file: *Zcu.File,1561 cur_file: *Zcu.File,
...@@ -1432,20 +1629,6 @@ pub fn embedFile(...@@ -1432,20 +1629,6 @@ pub fn embedFile(
1432 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);1629 return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc);
1433}1630}
14341631
1435/// Cancel the creation of an anon decl and delete any references to it.
1436/// If other decls depend on this decl, they must be aborted first.
1437pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1438 assert(!pt.zcu.declIsRoot(decl_index));
1439 pt.destroyDecl(decl_index);
1440}
1441
1442/// Finalize the creation of an anon decl.
1443pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1444 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1445 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1446 }
1447}
1448
1449/// https://github.com/ziglang/zig/issues/143071632/// https://github.com/ziglang/zig/issues/14307
1450fn newEmbedFile(1633fn newEmbedFile(
1451 pt: Zcu.PerThread,1634 pt: Zcu.PerThread,
...@@ -1718,7 +1901,10 @@ const ScanDeclIter = struct {...@@ -1718,7 +1901,10 @@ const ScanDeclIter = struct {
1718 }1901 }
17191902
1720 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);1903 const parent_file_scope_index = iter.parent_decl.getFileScopeIndex(zcu);
1721 const tracked_inst = try ip.trackZir(gpa, parent_file_scope_index, decl_inst);1904 const tracked_inst = try ip.trackZir(gpa, pt.tid, .{
1905 .file = parent_file_scope_index,
1906 .inst = decl_inst,
1907 });
17221908
1723 // We create a Decl for it regardless of analysis status.1909 // We create a Decl for it regardless of analysis status.
17241910
...@@ -1728,6 +1914,7 @@ const ScanDeclIter = struct {...@@ -1728,6 +1914,7 @@ const ScanDeclIter = struct {
1728 const was_exported = decl.is_exported;1914 const was_exported = decl.is_exported;
1729 assert(decl.kind == kind); // ZIR tracking should preserve this1915 assert(decl.kind == kind); // ZIR tracking should preserve this
1730 decl.name = decl_name;1916 decl.name = decl_name;
1917 decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
1731 decl.is_pub = declaration.flags.is_pub;1918 decl.is_pub = declaration.flags.is_pub;
1732 decl.is_exported = declaration.flags.is_export;1919 decl.is_exported = declaration.flags.is_export;
1733 break :decl_index .{ was_exported, decl_index };1920 break :decl_index .{ was_exported, decl_index };
...@@ -1737,6 +1924,7 @@ const ScanDeclIter = struct {...@@ -1737,6 +1924,7 @@ const ScanDeclIter = struct {
1737 const new_decl = zcu.declPtr(new_decl_index);1924 const new_decl = zcu.declPtr(new_decl_index);
1738 new_decl.kind = kind;1925 new_decl.kind = kind;
1739 new_decl.name = decl_name;1926 new_decl.name = decl_name;
1927 new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name);
1740 new_decl.is_pub = declaration.flags.is_pub;1928 new_decl.is_pub = declaration.flags.is_pub;
1741 new_decl.is_exported = declaration.flags.is_export;1929 new_decl.is_exported = declaration.flags.is_export;
1742 new_decl.zir_decl_index = tracked_inst.toOptional();1930 new_decl.zir_decl_index = tracked_inst.toOptional();
...@@ -1761,10 +1949,9 @@ const ScanDeclIter = struct {...@@ -1761,10 +1949,9 @@ const ScanDeclIter = struct {
1761 if (!comp.config.is_test) break :a false;1949 if (!comp.config.is_test) break :a false;
1762 if (decl_mod != zcu.main_mod) break :a false;1950 if (decl_mod != zcu.main_mod) break :a false;
1763 if (is_named_test and comp.test_filters.len > 0) {1951 if (is_named_test and comp.test_filters.len > 0) {
1764 const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name);1952 const decl_fqn = decl.fqn.toSlice(ip);
1765 const decl_fqn_slice = decl_fqn.toSlice(ip);
1766 for (comp.test_filters) |test_filter| {1953 for (comp.test_filters) |test_filter| {
1767 if (std.mem.indexOf(u8, decl_fqn_slice, test_filter)) |_| break;1954 if (std.mem.indexOf(u8, decl_fqn, test_filter)) |_| break;
1768 } else break :a false;1955 } else break :a false;
1769 }1956 }
1770 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update1957 zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update
...@@ -1794,6 +1981,20 @@ const ScanDeclIter = struct {...@@ -1794,6 +1981,20 @@ const ScanDeclIter = struct {
1794 }1981 }
1795};1982};
17961983
1984/// Cancel the creation of an anon decl and delete any references to it.
1985/// If other decls depend on this decl, they must be aborted first.
1986pub fn abortAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) void {
1987 assert(!pt.zcu.declIsRoot(decl_index));
1988 pt.destroyDecl(decl_index);
1989}
1990
1991/// Finalize the creation of an anon decl.
1992pub fn finalizeAnonDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) Allocator.Error!void {
1993 if (pt.zcu.declPtr(decl_index).typeOf(pt.zcu).isFnOrHasRuntimeBits(pt)) {
1994 try pt.zcu.comp.work_queue.writeItem(.{ .codegen_decl = decl_index });
1995 }
1996}
1997
1797pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {1998pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air {
1798 const tracy = trace(@src());1999 const tracy = trace(@src());
1799 defer tracy.end();2000 defer tracy.end();
...@@ -1805,12 +2006,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -1805,12 +2006,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
1805 const decl_index = func.owner_decl;2006 const decl_index = func.owner_decl;
1806 const decl = mod.declPtr(decl_index);2007 const decl = mod.declPtr(decl_index);
18072008
1808 log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)});2009 log.debug("func name '{}'", .{decl.fqn.fmt(ip)});
1809 defer blk: {2010 defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)});
1810 log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)});
1811 }
18122011
1813 const decl_prog_node = mod.sema_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(ip), 0);2012 const decl_prog_node = mod.sema_prog_node.start(decl.fqn.toSlice(ip), 0);
1814 defer decl_prog_node.end();2013 defer decl_prog_node.end();
18152014
1816 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));2015 mod.intern_pool.removeDependenciesForDepender(gpa, InternPool.AnalUnit.wrap(.{ .func = func_index }));
...@@ -1911,10 +2110,17 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -1911,10 +2110,17 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
1911 runtime_params_len;2110 runtime_params_len;
19122111
1913 var runtime_param_index: usize = 0;2112 var runtime_param_index: usize = 0;
1914 for (fn_info.param_body[0..src_params_len], 0..) |inst, src_param_index| {2113 for (fn_info.param_body[0..src_params_len]) |inst| {
1915 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);2114 const gop = sema.inst_map.getOrPutAssumeCapacity(inst);
1916 if (gop.found_existing) continue; // provided above by comptime arg2115 if (gop.found_existing) continue; // provided above by comptime arg
19172116
2117 const inst_info = sema.code.instructions.get(@intFromEnum(inst));
2118 const param_name: Zir.NullTerminatedString = switch (inst_info.tag) {
2119 .param_anytype => inst_info.data.str_tok.start,
2120 .param => sema.code.extraData(Zir.Inst.Param, inst_info.data.pl_tok.payload_index).data.name,
2121 else => unreachable,
2122 };
2123
1918 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];2124 const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index];
1919 runtime_param_index += 1;2125 runtime_param_index += 1;
19202126
...@@ -1935,7 +2141,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All...@@ -1935,7 +2141,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All
1935 .tag = .arg,2141 .tag = .arg,
1936 .data = .{ .arg = .{2142 .data = .{ .arg = .{
1937 .ty = Air.internedToRef(param_ty),2143 .ty = Air.internedToRef(param_ty),
1938 .src_index = @intCast(src_param_index),2144 .name = if (inner_block.ownerModule().strip)
2145 .none
2146 else
2147 @enumFromInt(try sema.appendAirString(sema.code.nullTerminatedString(param_name))),
1939 } },2148 } },
1940 });2149 });
1941 }2150 }
...@@ -2053,6 +2262,7 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D...@@ -2053,6 +2262,7 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
2053 const gpa = zcu.gpa;2262 const gpa = zcu.gpa;
2054 const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{2263 const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{
2055 .name = undefined,2264 .name = undefined,
2265 .fqn = undefined,
2056 .src_namespace = namespace,2266 .src_namespace = namespace,
2057 .has_tv = false,2267 .has_tv = false,
2058 .owns_tv = false,2268 .owns_tv = false,
...@@ -2077,6 +2287,36 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D...@@ -2077,6 +2287,36 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D
2077 return decl_index;2287 return decl_index;
2078}2288}
20792289
2290pub fn getErrorValue(
2291 pt: Zcu.PerThread,
2292 name: InternPool.NullTerminatedString,
2293) Allocator.Error!Zcu.ErrorInt {
2294 return pt.zcu.intern_pool.getErrorValue(pt.zcu.gpa, pt.tid, name);
2295}
2296
2297pub fn getErrorValueFromSlice(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Zcu.ErrorInt {
2298 return pt.getErrorValue(try pt.zcu.intern_pool.getOrPutString(pt.zcu.gpa, name));
2299}
2300
2301pub fn initNewAnonDecl(
2302 pt: Zcu.PerThread,
2303 new_decl_index: Zcu.Decl.Index,
2304 val: Value,
2305 name: InternPool.NullTerminatedString,
2306 fqn: InternPool.OptionalNullTerminatedString,
2307) Allocator.Error!void {
2308 const new_decl = pt.zcu.declPtr(new_decl_index);
2309
2310 new_decl.name = name;
2311 new_decl.fqn = fqn.unwrap() orelse try pt.zcu.namespacePtr(new_decl.src_namespace)
2312 .internFullyQualifiedName(&pt.zcu.intern_pool, pt.zcu.gpa, pt.tid, name);
2313 new_decl.val = val;
2314 new_decl.alignment = .none;
2315 new_decl.@"linksection" = .none;
2316 new_decl.has_tv = true;
2317 new_decl.analysis = .complete;
2318}
2319
2080fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {2320fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void {
2081 switch (file.status) {2321 switch (file.status) {
2082 .success_zir, .retryable_failure => {},2322 .success_zir, .retryable_failure => {},
...@@ -2229,7 +2469,7 @@ pub fn populateTestFunctions(...@@ -2229,7 +2469,7 @@ pub fn populateTestFunctions(
2229 const gpa = zcu.gpa;2469 const gpa = zcu.gpa;
2230 const ip = &zcu.intern_pool;2470 const ip = &zcu.intern_pool;
2231 const builtin_mod = zcu.root_mod.getBuiltinDependency();2471 const builtin_mod = zcu.root_mod.getBuiltinDependency();
2232 const builtin_file_index = (zcu.importPkg(builtin_mod) catch unreachable).file_index;2472 const builtin_file_index = (pt.importPkg(builtin_mod) catch unreachable).file_index;
2233 const root_decl_index = zcu.fileRootDecl(builtin_file_index);2473 const root_decl_index = zcu.fileRootDecl(builtin_file_index);
2234 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);2474 const root_decl = zcu.declPtr(root_decl_index.unwrap().?);
2235 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);2475 const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace);
...@@ -2260,7 +2500,7 @@ pub fn populateTestFunctions(...@@ -2260,7 +2500,7 @@ pub fn populateTestFunctions(
22602500
2261 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {2501 for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| {
2262 const test_decl = zcu.declPtr(test_decl_index);2502 const test_decl = zcu.declPtr(test_decl_index);
2263 const test_decl_name = try test_decl.fullyQualifiedName(pt);2503 const test_decl_name = test_decl.fqn;
2264 const test_decl_name_len = test_decl_name.length(ip);2504 const test_decl_name_len = test_decl_name.length(ip);
2265 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {2505 const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: {
2266 const test_name_ty = try pt.arrayType(.{2506 const test_name_ty = try pt.arrayType(.{
...@@ -2366,7 +2606,7 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {...@@ -2366,7 +2606,7 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
23662606
2367 const decl = zcu.declPtr(decl_index);2607 const decl = zcu.declPtr(decl_index);
23682608
2369 const codegen_prog_node = zcu.codegen_prog_node.start((try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool), 0);2609 const codegen_prog_node = zcu.codegen_prog_node.start(decl.fqn.toSlice(&zcu.intern_pool), 0);
2370 defer codegen_prog_node.end();2610 defer codegen_prog_node.end();
23712611
2372 if (comp.bin_file) |lf| {2612 if (comp.bin_file) |lf| {
...@@ -2396,6 +2636,87 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {...@@ -2396,6 +2636,87 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void {
2396 }2636 }
2397}2637}
23982638
2639pub fn reportRetryableAstGenError(
2640 pt: Zcu.PerThread,
2641 src: Zcu.AstGenSrc,
2642 file_index: Zcu.File.Index,
2643 err: anyerror,
2644) error{OutOfMemory}!void {
2645 const zcu = pt.zcu;
2646 const gpa = zcu.gpa;
2647 const ip = &zcu.intern_pool;
2648
2649 const file = zcu.fileByIndex(file_index);
2650 file.status = .retryable_failure;
2651
2652 const src_loc: Zcu.LazySrcLoc = switch (src) {
2653 .root => .{
2654 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2655 .file = file_index,
2656 .inst = .main_struct_inst,
2657 }),
2658 .offset = .entire_file,
2659 },
2660 .import => |info| .{
2661 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2662 .file = info.importing_file,
2663 .inst = .main_struct_inst,
2664 }),
2665 .offset = .{ .token_abs = info.import_tok },
2666 },
2667 };
2668
2669 const err_msg = try Zcu.ErrorMsg.create(gpa, src_loc, "unable to load '{}{s}': {s}", .{
2670 file.mod.root, file.sub_file_path, @errorName(err),
2671 });
2672 errdefer err_msg.destroy(gpa);
2673
2674 {
2675 zcu.comp.mutex.lock();
2676 defer zcu.comp.mutex.unlock();
2677 try zcu.failed_files.putNoClobber(gpa, file, err_msg);
2678 }
2679}
2680
2681pub fn reportRetryableFileError(
2682 pt: Zcu.PerThread,
2683 file_index: Zcu.File.Index,
2684 comptime format: []const u8,
2685 args: anytype,
2686) error{OutOfMemory}!void {
2687 const zcu = pt.zcu;
2688 const gpa = zcu.gpa;
2689 const ip = &zcu.intern_pool;
2690
2691 const file = zcu.fileByIndex(file_index);
2692 file.status = .retryable_failure;
2693
2694 const err_msg = try Zcu.ErrorMsg.create(
2695 gpa,
2696 .{
2697 .base_node_inst = try ip.trackZir(gpa, pt.tid, .{
2698 .file = file_index,
2699 .inst = .main_struct_inst,
2700 }),
2701 .offset = .entire_file,
2702 },
2703 format,
2704 args,
2705 );
2706 errdefer err_msg.destroy(gpa);
2707
2708 zcu.comp.mutex.lock();
2709 defer zcu.comp.mutex.unlock();
2710
2711 const gop = try zcu.failed_files.getOrPut(gpa, file);
2712 if (gop.found_existing) {
2713 if (gop.value_ptr.*) |old_err_msg| {
2714 old_err_msg.destroy(gpa);
2715 }
2716 }
2717 gop.value_ptr.* = err_msg;
2718}
2719
2399/// Shortcut for calling `intern_pool.get`.2720/// Shortcut for calling `intern_pool.get`.
2400pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {2721pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index {
2401 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);2722 return pt.zcu.intern_pool.get(pt.zcu.gpa, pt.tid, key);
...@@ -2897,7 +3218,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter...@@ -2897,7 +3218,7 @@ pub fn getBuiltinDecl(pt: Zcu.PerThread, name: []const u8) Allocator.Error!Inter
2897 const zcu = pt.zcu;3218 const zcu = pt.zcu;
2898 const gpa = zcu.gpa;3219 const gpa = zcu.gpa;
2899 const ip = &zcu.intern_pool;3220 const ip = &zcu.intern_pool;
2900 const std_file_imported = zcu.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");3221 const std_file_imported = pt.importPkg(zcu.std_mod) catch @panic("failed to import lib/std.zig");
2901 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;3222 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?;
2902 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;3223 const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?;
2903 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);3224 const builtin_str = try ip.getOrPutString(gpa, pt.tid, "builtin", .no_embedded_nulls);
src/arch/aarch64/CodeGen.zig+10-10
...@@ -4231,19 +4231,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4231,19 +4231,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4231 while (self.args[arg_index] == .none) arg_index += 1;4231 while (self.args[arg_index] == .none) arg_index += 1;
4232 self.arg_index = arg_index + 1;4232 self.arg_index = arg_index + 1;
42334233
4234 const pt = self.pt;
4235 const mod = pt.zcu;
4236 const ty = self.typeOfIndex(inst);4234 const ty = self.typeOfIndex(inst);
4237 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4235 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4238 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
4239 const name = mod.getParamName(self.func_index, src_index);
42404236
4241 try self.dbg_info_relocs.append(self.gpa, .{4237 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4242 .tag = tag,4238 if (name_nts != .none) {
4243 .ty = ty,4239 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4244 .name = name,4240 try self.dbg_info_relocs.append(self.gpa, .{
4245 .mcv = self.args[arg_index],4241 .tag = tag,
4246 });4242 .ty = ty,
4243 .name = name,
4244 .mcv = self.args[arg_index],
4245 });
4246 }
42474247
4248 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4248 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4249 return self.finishAir(inst, result, .{ .none, .none, .none });4249 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/arm/CodeGen.zig+10-10
...@@ -4206,19 +4206,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -4206,19 +4206,19 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
4206 while (self.args[arg_index] == .none) arg_index += 1;4206 while (self.args[arg_index] == .none) arg_index += 1;
4207 self.arg_index = arg_index + 1;4207 self.arg_index = arg_index + 1;
42084208
4209 const pt = self.pt;
4210 const mod = pt.zcu;
4211 const ty = self.typeOfIndex(inst);4209 const ty = self.typeOfIndex(inst);
4212 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];4210 const tag = self.air.instructions.items(.tag)[@intFromEnum(inst)];
4213 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;
4214 const name = mod.getParamName(self.func_index, src_index);
42154211
4216 try self.dbg_info_relocs.append(self.gpa, .{4212 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
4217 .tag = tag,4213 if (name_nts != .none) {
4218 .ty = ty,4214 const name = self.air.nullTerminatedString(@intFromEnum(name_nts));
4219 .name = name,4215 try self.dbg_info_relocs.append(self.gpa, .{
4220 .mcv = self.args[arg_index],4216 .tag = tag,
4221 });4217 .ty = ty,
4218 .name = name,
4219 .mcv = self.args[arg_index],
4220 });
4221 }
42224222
4223 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];4223 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index];
4224 return self.finishAir(inst, result, .{ .none, .none, .none });4224 return self.finishAir(inst, result, .{ .none, .none, .none });
src/arch/riscv64/CodeGen.zig+3-2
...@@ -933,7 +933,7 @@ fn formatDecl(...@@ -933,7 +933,7 @@ fn formatDecl(
933 _: std.fmt.FormatOptions,933 _: std.fmt.FormatOptions,
934 writer: anytype,934 writer: anytype,
935) @TypeOf(writer).Error!void {935) @TypeOf(writer).Error!void {
936 try data.mod.declPtr(data.decl_index).renderFullyQualifiedName(data.mod, writer);936 try writer.print("{}", .{data.mod.declPtr(data.decl_index).fqn.fmt(&data.mod.intern_pool)});
937}937}
938fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {938fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
939 return .{ .data = .{939 return .{ .data = .{
...@@ -4051,7 +4051,8 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -4051,7 +4051,8 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void {
4051 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;4051 const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg;
4052 const ty = arg.ty.toType();4052 const ty = arg.ty.toType();
4053 const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);4053 const owner_decl = zcu.funcOwnerDeclIndex(func.func_index);
4054 const name = zcu.getParamName(func.func_index, arg.src_index);4054 if (arg.name == .none) return;
4055 const name = func.air.nullTerminatedString(@intFromEnum(arg.name));
40554056
4056 switch (func.debug_output) {4057 switch (func.debug_output) {
4057 .dwarf => |dw| switch (mcv) {4058 .dwarf => |dw| switch (mcv) {
src/arch/sparc64/CodeGen.zig+2-1
...@@ -3614,7 +3614,8 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {...@@ -3614,7 +3614,8 @@ fn genArgDbgInfo(self: Self, inst: Air.Inst.Index, mcv: MCValue) !void {
3614 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;3614 const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg;
3615 const ty = arg.ty.toType();3615 const ty = arg.ty.toType();
3616 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);3616 const owner_decl = mod.funcOwnerDeclIndex(self.func_index);
3617 const name = mod.getParamName(self.func_index, arg.src_index);3617 if (arg.name == .none) return;
3618 const name = self.air.nullTerminatedString(@intFromEnum(arg.name));
36183619
3619 switch (self.debug_output) {3620 switch (self.debug_output) {
3620 .dwarf => |dw| switch (mcv) {3621 .dwarf => |dw| switch (mcv) {
src/arch/wasm/CodeGen.zig+18-21
...@@ -2585,11 +2585,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -2585,11 +2585,13 @@ fn airArg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
25852585
2586 switch (func.debug_output) {2586 switch (func.debug_output) {
2587 .dwarf => |dwarf| {2587 .dwarf => |dwarf| {
2588 const src_index = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;2588 const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
2589 const name = mod.getParamName(func.func_index, src_index);2589 if (name_nts != .none) {
2590 try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{2590 const name = func.air.nullTerminatedString(@intFromEnum(name_nts));
2591 .wasm_local = arg.local.value,2591 try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{
2592 });2592 .wasm_local = arg.local.value,
2593 });
2594 }
2593 },2595 },
2594 else => {},2596 else => {},
2595 }2597 }
...@@ -3302,7 +3304,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {...@@ -3302,7 +3304,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue {
3302 }3304 }
3303 },3305 },
3304 .err => |err| {3306 .err => |err| {
3305 const int = try mod.getErrorValue(err.name);3307 const int = try pt.getErrorValue(err.name);
3306 return WValue{ .imm32 = int };3308 return WValue{ .imm32 = int };
3307 },3309 },
3308 .error_union => |error_union| {3310 .error_union => |error_union| {
...@@ -3450,30 +3452,25 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {...@@ -3450,30 +3452,25 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue {
3450/// Returns a `Value` as a signed 32 bit value.3452/// Returns a `Value` as a signed 32 bit value.
3451/// It's illegal to provide a value with a type that cannot be represented3453/// It's illegal to provide a value with a type that cannot be represented
3452/// as an integer value.3454/// as an integer value.
3453fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 {3455fn valueAsI32(func: *const CodeGen, val: Value) i32 {
3454 const pt = func.pt;3456 const pt = func.pt;
3455 const mod = pt.zcu;3457 const mod = pt.zcu;
3458 const ip = &mod.intern_pool;
34563459
3457 switch (val.ip_index) {3460 switch (val.toIntern()) {
3458 .none => {},
3459 .bool_true => return 1,3461 .bool_true => return 1,
3460 .bool_false => return 0,3462 .bool_false => return 0,
3461 else => return switch (mod.intern_pool.indexToKey(val.ip_index)) {3463 else => return switch (ip.indexToKey(val.ip_index)) {
3462 .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt),3464 .enum_tag => |enum_tag| intIndexAsI32(ip, enum_tag.int, pt),
3463 .int => |int| intStorageAsI32(int.storage, pt),3465 .int => |int| intStorageAsI32(int.storage, pt),
3464 .ptr => |ptr| {3466 .ptr => |ptr| {
3465 assert(ptr.base_addr == .int);3467 assert(ptr.base_addr == .int);
3466 return @intCast(ptr.byte_offset);3468 return @intCast(ptr.byte_offset);
3467 },3469 },
3468 .err => |err| @as(i32, @bitCast(@as(Zcu.ErrorInt, @intCast(mod.global_error_set.getIndex(err.name).?)))),3470 .err => |err| @bitCast(ip.getErrorValueIfExists(err.name).?),
3469 else => unreachable,3471 else => unreachable,
3470 },3472 },
3471 }3473 }
3472
3473 return switch (ty.zigTypeTag(mod)) {
3474 .ErrorSet => @as(i32, @bitCast(val.getErrorInt(mod))),
3475 else => unreachable, // Programmer called this function for an illegal type
3476 };
3477}3474}
34783475
3479fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 {3476fn intIndexAsI32(ip: *const InternPool, int: InternPool.Index, pt: Zcu.PerThread) i32 {
...@@ -4096,7 +4093,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -4096,7 +4093,7 @@ fn airSwitchBr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
40964093
4097 for (items, 0..) |ref, i| {4094 for (items, 0..) |ref, i| {
4098 const item_val = (try func.air.value(ref, pt)).?;4095 const item_val = (try func.air.value(ref, pt)).?;
4099 const int_val = func.valueAsI32(item_val, target_ty);4096 const int_val = func.valueAsI32(item_val);
4100 if (lowest_maybe == null or int_val < lowest_maybe.?) {4097 if (lowest_maybe == null or int_val < lowest_maybe.?) {
4101 lowest_maybe = int_val;4098 lowest_maybe = int_val;
4102 }4099 }
...@@ -7284,8 +7281,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {...@@ -7284,8 +7281,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 {
7284 defer arena_allocator.deinit();7281 defer arena_allocator.deinit();
7285 const arena = arena_allocator.allocator();7282 const arena = arena_allocator.allocator();
72867283
7287 const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(pt);7284 const decl = mod.declPtr(enum_decl_index);
7288 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)});7285 const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)});
72897286
7290 // check if we already generated code for this.7287 // check if we already generated code for this.
7291 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {7288 if (func.bin_file.findGlobalSymbol(func_name)) |loc| {
...@@ -7452,7 +7449,7 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {...@@ -7452,7 +7449,7 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void {
7452 var lowest: ?u32 = null;7449 var lowest: ?u32 = null;
7453 var highest: ?u32 = null;7450 var highest: ?u32 = null;
7454 for (0..names.len) |name_index| {7451 for (0..names.len) |name_index| {
7455 const err_int: Zcu.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[name_index]).?);7452 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
7456 if (lowest) |*l| {7453 if (lowest) |*l| {
7457 if (err_int < l.*) {7454 if (err_int < l.*) {
7458 l.* = err_int;7455 l.* = err_int;
src/arch/x86_64/CodeGen.zig+8-6
...@@ -1077,7 +1077,7 @@ fn formatDecl(...@@ -1077,7 +1077,7 @@ fn formatDecl(
1077 _: std.fmt.FormatOptions,1077 _: std.fmt.FormatOptions,
1078 writer: anytype,1078 writer: anytype,
1079) @TypeOf(writer).Error!void {1079) @TypeOf(writer).Error!void {
1080 try data.zcu.declPtr(data.decl_index).renderFullyQualifiedName(data.zcu, writer);1080 try writer.print("{}", .{data.zcu.declPtr(data.decl_index).fqn.fmt(&data.zcu.intern_pool)});
1081}1081}
1082fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {1082fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) {
1083 return .{ .data = .{1083 return .{ .data = .{
...@@ -11920,9 +11920,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {...@@ -11920,9 +11920,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void {
11920 else => return self.fail("TODO implement arg for {}", .{src_mcv}),11920 else => return self.fail("TODO implement arg for {}", .{src_mcv}),
11921 };11921 };
1192211922
11923 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;11923 const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
11924 const name = mod.getParamName(self.owner.func_index, src_index);11924 switch (name_nts) {
11925 try self.genArgDbgInfo(arg_ty, name, src_mcv);11925 .none => {},
11926 _ => try self.genArgDbgInfo(arg_ty, self.air.nullTerminatedString(@intFromEnum(name_nts)), src_mcv),
11927 }
1192611928
11927 break :result dst_mcv;11929 break :result dst_mcv;
11928 };11930 };
...@@ -16433,7 +16435,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16433,7 +16435,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16433 .size = .dword,16435 .size = .dword,
16434 .index = err_reg.to64(),16436 .index = err_reg.to64(),
16435 .scale = .@"4",16437 .scale = .@"4",
16436 .disp = 4,16438 .disp = (1 - 1) * 4,
16437 } },16439 } },
16438 },16440 },
16439 );16441 );
...@@ -16446,7 +16448,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {...@@ -16446,7 +16448,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void {
16446 .size = .dword,16448 .size = .dword,
16447 .index = err_reg.to64(),16449 .index = err_reg.to64(),
16448 .scale = .@"4",16450 .scale = .@"4",
16449 .disp = 8,16451 .disp = (2 - 1) * 4,
16450 } },16452 } },
16451 },16453 },
16452 );16454 );
src/codegen.zig+5-5
...@@ -137,10 +137,10 @@ pub fn generateLazySymbol(...@@ -137,10 +137,10 @@ pub fn generateLazySymbol(
137137
138 if (lazy_sym.ty.isAnyError(pt.zcu)) {138 if (lazy_sym.ty.isAnyError(pt.zcu)) {
139 alignment.* = .@"4";139 alignment.* = .@"4";
140 const err_names = pt.zcu.global_error_set.keys();140 const err_names = ip.global_error_set.getNamesFromMainThread();
141 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);141 mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian);
142 var offset = code.items.len;142 var offset = code.items.len;
143 try code.resize((1 + err_names.len + 1) * 4);143 try code.resize((err_names.len + 1) * 4);
144 for (err_names) |err_name_nts| {144 for (err_names) |err_name_nts| {
145 const err_name = err_name_nts.toSlice(ip);145 const err_name = err_name_nts.toSlice(ip);
146 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);146 mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian);
...@@ -243,13 +243,13 @@ pub fn generateSymbol(...@@ -243,13 +243,13 @@ pub fn generateSymbol(
243 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);243 int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian);
244 },244 },
245 .err => |err| {245 .err => |err| {
246 const int = try mod.getErrorValue(err.name);246 const int = try pt.getErrorValue(err.name);
247 try code.writer().writeInt(u16, @intCast(int), endian);247 try code.writer().writeInt(u16, @intCast(int), endian);
248 },248 },
249 .error_union => |error_union| {249 .error_union => |error_union| {
250 const payload_ty = ty.errorUnionPayload(mod);250 const payload_ty = ty.errorUnionPayload(mod);
251 const err_val: u16 = switch (error_union.val) {251 const err_val: u16 = switch (error_union.val) {
252 .err_name => |err_name| @intCast(try mod.getErrorValue(err_name)),252 .err_name => |err_name| @intCast(try pt.getErrorValue(err_name)),
253 .payload => 0,253 .payload => 0,
254 };254 };
255255
...@@ -1058,7 +1058,7 @@ pub fn genTypedValue(...@@ -1058,7 +1058,7 @@ pub fn genTypedValue(
1058 },1058 },
1059 .ErrorSet => {1059 .ErrorSet => {
1060 const err_name = ip.indexToKey(val.toIntern()).err.name;1060 const err_name = ip.indexToKey(val.toIntern()).err.name;
1061 const error_index = zcu.global_error_set.getIndex(err_name).?;1061 const error_index = try pt.getErrorValue(err_name);
1062 return GenResult.mcv(.{ .immediate = error_index });1062 return GenResult.mcv(.{ .immediate = error_index });
1063 },1063 },
1064 .ErrorUnion => {1064 .ErrorUnion => {
src/codegen/c.zig+14-21
...@@ -2194,13 +2194,9 @@ pub const DeclGen = struct {...@@ -2194,13 +2194,9 @@ pub const DeclGen = struct {
2194 }) else {2194 }) else {
2195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),2195 // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case),
2196 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.2196 // expand to 3x the length of its input, but let's cut it off at a much shorter limit.
2197 var name: [100]u8 = undefined;2197 const fqn_slice = decl.fqn.toSlice(ip);
2198 var name_stream = std.io.fixedBufferStream(&name);
2199 decl.renderFullyQualifiedName(zcu, name_stream.writer()) catch |err| switch (err) {
2200 error.NoSpaceLeft => {},
2201 };
2202 try writer.print("{}__{d}", .{2198 try writer.print("{}__{d}", .{
2203 fmtIdent(name_stream.getWritten()),2199 fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]),
2204 @intFromEnum(decl_index),2200 @intFromEnum(decl_index),
2205 });2201 });
2206 }2202 }
...@@ -2587,11 +2583,9 @@ pub fn genTypeDecl(...@@ -2587,11 +2583,9 @@ pub fn genTypeDecl(
2587 try writer.writeByte(';');2583 try writer.writeByte(';');
2588 const owner_decl = zcu.declPtr(owner_decl_index);2584 const owner_decl = zcu.declPtr(owner_decl_index);
2589 const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;2585 const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod;
2590 if (!owner_mod.strip) {2586 if (!owner_mod.strip) try writer.print(" /* {} */", .{
2591 try writer.writeAll(" /* ");2587 owner_decl.fqn.fmt(&zcu.intern_pool),
2592 try owner_decl.renderFullyQualifiedName(zcu, writer);2588 });
2593 try writer.writeAll(" */");
2594 }
2595 try writer.writeByte('\n');2589 try writer.writeByte('\n');
2596 },2590 },
2597 },2591 },
...@@ -2628,10 +2622,11 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2628,10 +2622,11 @@ pub fn genErrDecls(o: *Object) !void {
26282622
2629 var max_name_len: usize = 0;2623 var max_name_len: usize = 0;
2630 // do not generate an invalid empty enum when the global error set is empty2624 // do not generate an invalid empty enum when the global error set is empty
2631 if (zcu.global_error_set.keys().len > 1) {2625 const names = ip.global_error_set.getNamesFromMainThread();
2626 if (names.len > 0) {
2632 try writer.writeAll("enum {\n");2627 try writer.writeAll("enum {\n");
2633 o.indent_writer.pushIndent();2628 o.indent_writer.pushIndent();
2634 for (zcu.global_error_set.keys()[1..], 1..) |name_nts, value| {2629 for (names, 1..) |name_nts, value| {
2635 const name = name_nts.toSlice(ip);2630 const name = name_nts.toSlice(ip);
2636 max_name_len = @max(name.len, max_name_len);2631 max_name_len = @max(name.len, max_name_len);
2637 const err_val = try pt.intern(.{ .err = .{2632 const err_val = try pt.intern(.{ .err = .{
...@@ -2650,7 +2645,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2650,7 +2645,7 @@ pub fn genErrDecls(o: *Object) !void {
2650 defer o.dg.gpa.free(name_buf);2645 defer o.dg.gpa.free(name_buf);
26512646
2652 @memcpy(name_buf[0..name_prefix.len], name_prefix);2647 @memcpy(name_buf[0..name_prefix.len], name_prefix);
2653 for (zcu.global_error_set.keys()) |name| {2648 for (names) |name| {
2654 const name_slice = name.toSlice(ip);2649 const name_slice = name.toSlice(ip);
2655 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);2650 @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice);
2656 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];2651 const identifier = name_buf[0 .. name_prefix.len + name_slice.len];
...@@ -2680,7 +2675,7 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2680,7 +2675,7 @@ pub fn genErrDecls(o: *Object) !void {
2680 }2675 }
26812676
2682 const name_array_ty = try pt.arrayType(.{2677 const name_array_ty = try pt.arrayType(.{
2683 .len = zcu.global_error_set.count(),2678 .len = 1 + names.len,
2684 .child = .slice_const_u8_sentinel_0_type,2679 .child = .slice_const_u8_sentinel_0_type,
2685 });2680 });
26862681
...@@ -2694,9 +2689,9 @@ pub fn genErrDecls(o: *Object) !void {...@@ -2694,9 +2689,9 @@ pub fn genErrDecls(o: *Object) !void {
2694 .complete,2689 .complete,
2695 );2690 );
2696 try writer.writeAll(" = {");2691 try writer.writeAll(" = {");
2697 for (zcu.global_error_set.keys(), 0..) |name_nts, value| {2692 for (names, 1..) |name_nts, val| {
2698 const name = name_nts.toSlice(ip);2693 const name = name_nts.toSlice(ip);
2699 if (value != 0) try writer.writeByte(',');2694 if (val > 1) try writer.writeAll(", ");
2700 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{2695 try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{
2701 fmtIdent(name),2696 fmtIdent(name),
2702 try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer),2697 try o.dg.fmtIntLiteral(try pt.intValue(Type.usize, name.len), .StaticInitializer),
...@@ -4563,9 +4558,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -4563,9 +4558,7 @@ fn airDbgInlineBlock(f: *Function, inst: Air.Inst.Index) !CValue {
4563 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);4558 const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload);
4564 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);4559 const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func);
4565 const writer = f.object.writer();4560 const writer = f.object.writer();
4566 try writer.writeAll("/* inline:");4561 try writer.print("/* inline:{} */\n", .{owner_decl.fqn.fmt(&zcu.intern_pool)});
4567 try owner_decl.renderFullyQualifiedName(zcu, writer);
4568 try writer.writeAll(" */\n");
4569 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));4562 return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len]));
4570}4563}
45714564
...@@ -6881,7 +6874,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6881,7 +6874,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue {
68816874
6882 try writer.writeAll(" = zig_errorName[");6875 try writer.writeAll(" = zig_errorName[");
6883 try f.writeCValue(writer, operand, .Other);6876 try f.writeCValue(writer, operand, .Other);
6884 try writer.writeAll("];\n");6877 try writer.writeAll(" - 1];\n");
6885 return local;6878 return local;
6886}6879}
68876880
src/codegen/llvm.zig+34-38
...@@ -1036,20 +1036,21 @@ pub const Object = struct {...@@ -1036,20 +1036,21 @@ pub const Object = struct {
10361036
1037 const pt = o.pt;1037 const pt = o.pt;
1038 const mod = pt.zcu;1038 const mod = pt.zcu;
1039 const ip = &mod.intern_pool;
10391040
1040 const error_name_list = mod.global_error_set.keys();1041 const error_name_list = ip.global_error_set.getNamesFromMainThread();
1041 const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len);1042 const llvm_errors = try mod.gpa.alloc(Builder.Constant, 1 + error_name_list.len);
1042 defer mod.gpa.free(llvm_errors);1043 defer mod.gpa.free(llvm_errors);
10431044
1044 // TODO: Address space1045 // TODO: Address space
1045 const slice_ty = Type.slice_const_u8_sentinel_0;1046 const slice_ty = Type.slice_const_u8_sentinel_0;
1046 const llvm_usize_ty = try o.lowerType(Type.usize);1047 const llvm_usize_ty = try o.lowerType(Type.usize);
1047 const llvm_slice_ty = try o.lowerType(slice_ty);1048 const llvm_slice_ty = try o.lowerType(slice_ty);
1048 const llvm_table_ty = try o.builder.arrayType(error_name_list.len, llvm_slice_ty);1049 const llvm_table_ty = try o.builder.arrayType(1 + error_name_list.len, llvm_slice_ty);
10491050
1050 llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty);1051 llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty);
1051 for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name| {1052 for (llvm_errors[1..], error_name_list) |*llvm_error, name| {
1052 const name_string = try o.builder.stringNull(name.toSlice(&mod.intern_pool));1053 const name_string = try o.builder.stringNull(name.toSlice(ip));
1053 const name_init = try o.builder.stringConst(name_string);1054 const name_init = try o.builder.stringConst(name_string);
1054 const name_variable_index =1055 const name_variable_index =
1055 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);1056 try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default);
...@@ -1085,7 +1086,7 @@ pub const Object = struct {...@@ -1085,7 +1086,7 @@ pub const Object = struct {
1085 // If there is no such function in the module, it means the source code does not need it.1086 // If there is no such function in the module, it means the source code does not need it.
1086 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;1087 const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return;
1087 const llvm_fn = o.builder.getGlobal(name) orelse return;1088 const llvm_fn = o.builder.getGlobal(name) orelse return;
1088 const errors_len = o.pt.zcu.global_error_set.count();1089 const errors_len = o.pt.zcu.intern_pool.global_error_set.mutate.list.len;
10891090
1090 var wip = try Builder.WipFunction.init(&o.builder, .{1091 var wip = try Builder.WipFunction.init(&o.builder, .{
1091 .function = llvm_fn.ptrConst(&o.builder).kind.function,1092 .function = llvm_fn.ptrConst(&o.builder).kind.function,
...@@ -1096,12 +1097,12 @@ pub const Object = struct {...@@ -1096,12 +1097,12 @@ pub const Object = struct {
10961097
1097 // Example source of the following LLVM IR:1098 // Example source of the following LLVM IR:
1098 // fn __zig_lt_errors_len(index: u16) bool {1099 // fn __zig_lt_errors_len(index: u16) bool {
1099 // return index < total_errors_len;1100 // return index <= total_errors_len;
1100 // }1101 // }
11011102
1102 const lhs = wip.arg(0);1103 const lhs = wip.arg(0);
1103 const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);1104 const rhs = try o.builder.intValue(try o.errorIntType(), errors_len);
1104 const is_lt = try wip.icmp(.ult, lhs, rhs, "");1105 const is_lt = try wip.icmp(.ule, lhs, rhs, "");
1105 _ = try wip.ret(is_lt);1106 _ = try wip.ret(is_lt);
1106 try wip.finish();1107 try wip.finish();
1107 }1108 }
...@@ -1744,7 +1745,7 @@ pub const Object = struct {...@@ -1744,7 +1745,7 @@ pub const Object = struct {
1744 if (export_indices.len != 0) {1745 if (export_indices.len != 0) {
1745 return updateExportedGlobal(self, zcu, global_index, export_indices);1746 return updateExportedGlobal(self, zcu, global_index, export_indices);
1746 } else {1747 } else {
1747 const fqn = try self.builder.strtabString((try decl.fullyQualifiedName(pt)).toSlice(ip));1748 const fqn = try self.builder.strtabString(decl.fqn.toSlice(ip));
1748 try global_index.rename(fqn, &self.builder);1749 try global_index.rename(fqn, &self.builder);
1749 global_index.setLinkage(.internal, &self.builder);1750 global_index.setLinkage(.internal, &self.builder);
1750 if (comp.config.dll_export_fns)1751 if (comp.config.dll_export_fns)
...@@ -2811,7 +2812,7 @@ pub const Object = struct {...@@ -2811,7 +2812,7 @@ pub const Object = struct {
2811 const zcu = pt.zcu;2812 const zcu = pt.zcu;
28122813
2813 const std_mod = zcu.std_mod;2814 const std_mod = zcu.std_mod;
2814 const std_file_imported = zcu.importPkg(std_mod) catch unreachable;2815 const std_file_imported = pt.importPkg(std_mod) catch unreachable;
28152816
2816 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);2817 const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls);
2817 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);2818 const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index);
...@@ -2863,10 +2864,7 @@ pub const Object = struct {...@@ -2863,10 +2864,7 @@ pub const Object = struct {
2863 const is_extern = decl.isExtern(zcu);2864 const is_extern = decl.isExtern(zcu);
2864 const function_index = try o.builder.addFunction(2865 const function_index = try o.builder.addFunction(
2865 try o.lowerType(zig_fn_type),2866 try o.lowerType(zig_fn_type),
2866 try o.builder.strtabString((if (is_extern)2867 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
2867 decl.name
2868 else
2869 try decl.fullyQualifiedName(pt)).toSlice(ip)),
2870 toLlvmAddressSpace(decl.@"addrspace", target),2868 toLlvmAddressSpace(decl.@"addrspace", target),
2871 );2869 );
2872 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;2870 gop.value_ptr.* = function_index.ptrConst(&o.builder).global;
...@@ -3077,14 +3075,12 @@ pub const Object = struct {...@@ -3077,14 +3075,12 @@ pub const Object = struct {
30773075
3078 const pt = o.pt;3076 const pt = o.pt;
3079 const zcu = pt.zcu;3077 const zcu = pt.zcu;
3078 const ip = &zcu.intern_pool;
3080 const decl = zcu.declPtr(decl_index);3079 const decl = zcu.declPtr(decl_index);
3081 const is_extern = decl.isExtern(zcu);3080 const is_extern = decl.isExtern(zcu);
30823081
3083 const variable_index = try o.builder.addVariable(3082 const variable_index = try o.builder.addVariable(
3084 try o.builder.strtabString((if (is_extern)3083 try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)),
3085 decl.name
3086 else
3087 try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)),
3088 try o.lowerType(decl.typeOf(zcu)),3084 try o.lowerType(decl.typeOf(zcu)),
3089 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),3085 toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()),
3090 );3086 );
...@@ -3312,7 +3308,7 @@ pub const Object = struct {...@@ -3312,7 +3308,7 @@ pub const Object = struct {
3312 return int_ty;3308 return int_ty;
3313 }3309 }
33143310
3315 const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt);3311 const decl = mod.declPtr(struct_type.decl.unwrap().?);
33163312
3317 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};3313 var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){};
3318 defer llvm_field_types.deinit(o.gpa);3314 defer llvm_field_types.deinit(o.gpa);
...@@ -3377,7 +3373,7 @@ pub const Object = struct {...@@ -3377,7 +3373,7 @@ pub const Object = struct {
3377 );3373 );
3378 }3374 }
33793375
3380 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));3376 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3381 try o.type_map.put(o.gpa, t.toIntern(), ty);3377 try o.type_map.put(o.gpa, t.toIntern(), ty);
33823378
3383 o.builder.namedTypeSetBody(3379 o.builder.namedTypeSetBody(
...@@ -3466,7 +3462,7 @@ pub const Object = struct {...@@ -3466,7 +3462,7 @@ pub const Object = struct {
3466 return enum_tag_ty;3462 return enum_tag_ty;
3467 }3463 }
34683464
3469 const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt);3465 const decl = mod.declPtr(union_obj.decl);
34703466
3471 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);3467 const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]);
3472 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);3468 const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty);
...@@ -3486,7 +3482,7 @@ pub const Object = struct {...@@ -3486,7 +3482,7 @@ pub const Object = struct {
3486 };3482 };
34873483
3488 if (layout.tag_size == 0) {3484 if (layout.tag_size == 0) {
3489 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));3485 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3490 try o.type_map.put(o.gpa, t.toIntern(), ty);3486 try o.type_map.put(o.gpa, t.toIntern(), ty);
34913487
3492 o.builder.namedTypeSetBody(3488 o.builder.namedTypeSetBody(
...@@ -3514,7 +3510,7 @@ pub const Object = struct {...@@ -3514,7 +3510,7 @@ pub const Object = struct {
3514 llvm_fields_len += 1;3510 llvm_fields_len += 1;
3515 }3511 }
35163512
3517 const ty = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));3513 const ty = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3518 try o.type_map.put(o.gpa, t.toIntern(), ty);3514 try o.type_map.put(o.gpa, t.toIntern(), ty);
35193515
3520 o.builder.namedTypeSetBody(3516 o.builder.namedTypeSetBody(
...@@ -3527,8 +3523,7 @@ pub const Object = struct {...@@ -3527,8 +3523,7 @@ pub const Object = struct {
3527 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());3523 const gop = try o.type_map.getOrPut(o.gpa, t.toIntern());
3528 if (!gop.found_existing) {3524 if (!gop.found_existing) {
3529 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);3525 const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl);
3530 const fqn = try decl.fullyQualifiedName(pt);3526 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip)));
3531 gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip)));
3532 }3527 }
3533 return gop.value_ptr.*;3528 return gop.value_ptr.*;
3534 },3529 },
...@@ -3826,7 +3821,7 @@ pub const Object = struct {...@@ -3826,7 +3821,7 @@ pub const Object = struct {
3826 return lowerBigInt(o, ty, bigint);3821 return lowerBigInt(o, ty, bigint);
3827 },3822 },
3828 .err => |err| {3823 .err => |err| {
3829 const int = try mod.getErrorValue(err.name);3824 const int = try pt.getErrorValue(err.name);
3830 const llvm_int = try o.builder.intConst(try o.errorIntType(), int);3825 const llvm_int = try o.builder.intConst(try o.errorIntType(), int);
3831 return llvm_int;3826 return llvm_int;
3832 },3827 },
...@@ -4587,11 +4582,11 @@ pub const Object = struct {...@@ -4587,11 +4582,11 @@ pub const Object = struct {
45874582
4588 const usize_ty = try o.lowerType(Type.usize);4583 const usize_ty = try o.lowerType(Type.usize);
4589 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);4584 const ret_ty = try o.lowerType(Type.slice_const_u8_sentinel_0);
4590 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);4585 const decl = zcu.declPtr(enum_type.decl);
4591 const target = zcu.root_mod.resolved_target.result;4586 const target = zcu.root_mod.resolved_target.result;
4592 const function_index = try o.builder.addFunction(4587 const function_index = try o.builder.addFunction(
4593 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),4588 try o.builder.fnType(ret_ty, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
4594 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{fqn.fmt(ip)}),4589 try o.builder.strtabStringFmt("__zig_tag_name_{}", .{decl.fqn.fmt(ip)}),
4595 toLlvmAddressSpace(.generic, target),4590 toLlvmAddressSpace(.generic, target),
4596 );4591 );
45974592
...@@ -5175,8 +5170,6 @@ pub const FuncGen = struct {...@@ -5175,8 +5170,6 @@ pub const FuncGen = struct {
5175 const line_number = decl.navSrcLine(zcu) + 1;5170 const line_number = decl.navSrcLine(zcu) + 1;
5176 self.inlined = self.wip.debug_location;5171 self.inlined = self.wip.debug_location;
51775172
5178 const fqn = try decl.fullyQualifiedName(pt);
5179
5180 const fn_ty = try pt.funcType(.{5173 const fn_ty = try pt.funcType(.{
5181 .param_types = &.{},5174 .param_types = &.{},
5182 .return_type = .void_type,5175 .return_type = .void_type,
...@@ -5185,7 +5178,7 @@ pub const FuncGen = struct {...@@ -5185,7 +5178,7 @@ pub const FuncGen = struct {
5185 self.scope = try o.builder.debugSubprogram(5178 self.scope = try o.builder.debugSubprogram(
5186 self.file,5179 self.file,
5187 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),5180 try o.builder.metadataString(decl.name.toSlice(&zcu.intern_pool)),
5188 try o.builder.metadataString(fqn.toSlice(&zcu.intern_pool)),5181 try o.builder.metadataString(decl.fqn.toSlice(&zcu.intern_pool)),
5189 line_number,5182 line_number,
5190 line_number + func.lbrace_line,5183 line_number + func.lbrace_line,
5191 try o.lowerDebugType(fn_ty),5184 try o.lowerDebugType(fn_ty),
...@@ -8867,19 +8860,21 @@ pub const FuncGen = struct {...@@ -8867,19 +8860,21 @@ pub const FuncGen = struct {
8867 self.arg_index += 1;8860 self.arg_index += 1;
88688861
8869 // llvm does not support debug info for naked function arguments8862 // llvm does not support debug info for naked function arguments
8870 if (self.wip.strip or self.is_naked) return arg_val;8863 if (self.is_naked) return arg_val;
88718864
8872 const inst_ty = self.typeOfIndex(inst);8865 const inst_ty = self.typeOfIndex(inst);
8873 if (needDbgVarWorkaround(o)) return arg_val;8866 if (needDbgVarWorkaround(o)) return arg_val;
88748867
8875 const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index;8868 const name = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name;
8869 if (name == .none) return arg_val;
8870
8876 const func_index = self.dg.decl.getOwnedFunctionIndex();8871 const func_index = self.dg.decl.getOwnedFunctionIndex();
8877 const func = mod.funcInfo(func_index);8872 const func = mod.funcInfo(func_index);
8878 const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;8873 const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1;
8879 const lbrace_col = func.lbrace_column + 1;8874 const lbrace_col = func.lbrace_column + 1;
88808875
8881 const debug_parameter = try o.builder.debugParameter(8876 const debug_parameter = try o.builder.debugParameter(
8882 try o.builder.metadataString(mod.getParamName(func_index, src_index)),8877 try o.builder.metadataString(self.air.nullTerminatedString(@intFromEnum(name))),
8883 self.file,8878 self.file,
8884 self.scope,8879 self.scope,
8885 lbrace_line,8880 lbrace_line,
...@@ -9664,7 +9659,7 @@ pub const FuncGen = struct {...@@ -9664,7 +9659,7 @@ pub const FuncGen = struct {
9664 defer wip_switch.finish(&self.wip);9659 defer wip_switch.finish(&self.wip);
96659660
9666 for (0..names.len) |name_index| {9661 for (0..names.len) |name_index| {
9667 const err_int = mod.global_error_set.getIndex(names.get(ip)[name_index]).?;9662 const err_int = ip.getErrorValueIfExists(names.get(ip)[name_index]).?;
9668 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);9663 const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int);
9669 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);9664 try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip);
9670 }9665 }
...@@ -9702,18 +9697,19 @@ pub const FuncGen = struct {...@@ -9702,18 +9697,19 @@ pub const FuncGen = struct {
9702 const o = self.dg.object;9697 const o = self.dg.object;
9703 const pt = o.pt;9698 const pt = o.pt;
9704 const zcu = pt.zcu;9699 const zcu = pt.zcu;
9705 const enum_type = zcu.intern_pool.loadEnumType(enum_ty.toIntern());9700 const ip = &zcu.intern_pool;
9701 const enum_type = ip.loadEnumType(enum_ty.toIntern());
97069702
9707 // TODO: detect when the type changes and re-emit this function.9703 // TODO: detect when the type changes and re-emit this function.
9708 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);9704 const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl);
9709 if (gop.found_existing) return gop.value_ptr.*;9705 if (gop.found_existing) return gop.value_ptr.*;
9710 errdefer assert(o.named_enum_map.remove(enum_type.decl));9706 errdefer assert(o.named_enum_map.remove(enum_type.decl));
97119707
9712 const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt);9708 const decl = zcu.declPtr(enum_type.decl);
9713 const target = zcu.root_mod.resolved_target.result;9709 const target = zcu.root_mod.resolved_target.result;
9714 const function_index = try o.builder.addFunction(9710 const function_index = try o.builder.addFunction(
9715 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),9711 try o.builder.fnType(.i1, &.{try o.lowerType(Type.fromInterned(enum_type.tag_ty))}, .normal),
9716 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{fqn.fmt(&zcu.intern_pool)}),9712 try o.builder.strtabStringFmt("__zig_is_named_enum_value_{}", .{decl.fqn.fmt(ip)}),
9717 toLlvmAddressSpace(.generic, target),9713 toLlvmAddressSpace(.generic, target),
9718 );9714 );
97199715
src/codegen/spirv.zig+5-8
...@@ -963,7 +963,7 @@ const DeclGen = struct {...@@ -963,7 +963,7 @@ const DeclGen = struct {
963 break :cache result_id;963 break :cache result_id;
964 },964 },
965 .err => |err| {965 .err => |err| {
966 const value = try mod.getErrorValue(err.name);966 const value = try pt.getErrorValue(err.name);
967 break :cache try self.constInt(ty, value, repr);967 break :cache try self.constInt(ty, value, repr);
968 },968 },
969 .error_union => |error_union| {969 .error_union => |error_union| {
...@@ -3012,12 +3012,11 @@ const DeclGen = struct {...@@ -3012,12 +3012,11 @@ const DeclGen = struct {
3012 // Append the actual code into the functions section.3012 // Append the actual code into the functions section.
3013 try self.spv.addFunction(spv_decl_index, self.func);3013 try self.spv.addFunction(spv_decl_index, self.func);
30143014
3015 const fqn = try decl.fullyQualifiedName(self.pt);3015 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
3016 try self.spv.debugName(result_id, fqn.toSlice(ip));
30173016
3018 // Temporarily generate a test kernel declaration if this is a test function.3017 // Temporarily generate a test kernel declaration if this is a test function.
3019 if (self.pt.zcu.test_functions.contains(self.decl_index)) {3018 if (self.pt.zcu.test_functions.contains(self.decl_index)) {
3020 try self.generateTestEntryPoint(fqn.toSlice(ip), spv_decl_index);3019 try self.generateTestEntryPoint(decl.fqn.toSlice(ip), spv_decl_index);
3021 }3020 }
3022 },3021 },
3023 .global => {3022 .global => {
...@@ -3041,8 +3040,7 @@ const DeclGen = struct {...@@ -3041,8 +3040,7 @@ const DeclGen = struct {
3041 .storage_class = final_storage_class,3040 .storage_class = final_storage_class,
3042 });3041 });
30433042
3044 const fqn = try decl.fullyQualifiedName(self.pt);3043 try self.spv.debugName(result_id, decl.fqn.toSlice(ip));
3045 try self.spv.debugName(result_id, fqn.toSlice(ip));
3046 try self.spv.declareDeclDeps(spv_decl_index, &.{});3044 try self.spv.declareDeclDeps(spv_decl_index, &.{});
3047 },3045 },
3048 .invocation_global => {3046 .invocation_global => {
...@@ -3086,8 +3084,7 @@ const DeclGen = struct {...@@ -3086,8 +3084,7 @@ const DeclGen = struct {
3086 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});3084 try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {});
3087 try self.spv.addFunction(spv_decl_index, self.func);3085 try self.spv.addFunction(spv_decl_index, self.func);
30883086
3089 const fqn = try decl.fullyQualifiedName(self.pt);3087 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{decl.fqn.fmt(ip)});
3090 try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)});
30913088
3092 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{3089 try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{
3093 .id_result_type = ptr_ty_id,3090 .id_result_type = ptr_ty_id,
src/link/Coff.zig+8-9
...@@ -1176,9 +1176,10 @@ pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index:...@@ -1176,9 +1176,10 @@ pub fn lowerUnnamedConst(self: *Coff, pt: Zcu.PerThread, val: Value, decl_index:
1176 gop.value_ptr.* = .{};1176 gop.value_ptr.* = .{};
1177 }1177 }
1178 const unnamed_consts = gop.value_ptr;1178 const unnamed_consts = gop.value_ptr;
1179 const decl_name = try decl.fullyQualifiedName(pt);
1180 const index = unnamed_consts.items.len;1179 const index = unnamed_consts.items.len;
1181 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1180 const sym_name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{
1181 decl.fqn.fmt(&mod.intern_pool), index,
1182 });
1182 defer gpa.free(sym_name);1183 defer gpa.free(sym_name);
1183 const ty = val.typeOf(mod);1184 const ty = val.typeOf(mod);
1184 const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {1185 const atom_index = switch (try self.lowerConst(pt, sym_name, val, ty.abiAlignment(pt), self.rdata_section_index.?, decl.navSrcLoc(mod))) {
...@@ -1427,9 +1428,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1427,9 +1428,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
1427 const mod = pt.zcu;1428 const mod = pt.zcu;
1428 const decl = mod.declPtr(decl_index);1429 const decl = mod.declPtr(decl_index);
14291430
1430 const decl_name = try decl.fullyQualifiedName(pt);1431 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(&mod.intern_pool), decl });
1431
1432 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });
1433 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);1432 const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0);
14341433
1435 const decl_metadata = self.decls.get(decl_index).?;1434 const decl_metadata = self.decls.get(decl_index).?;
...@@ -1441,7 +1440,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1441,7 +1440,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
14411440
1442 if (atom.size != 0) {1441 if (atom.size != 0) {
1443 const sym = atom.getSymbolPtr(self);1442 const sym = atom.getSymbolPtr(self);
1444 try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));1443 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
1445 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));1444 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
1446 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1445 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14471446
...@@ -1449,7 +1448,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1449,7 +1448,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
1449 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);1448 const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment);
1450 if (need_realloc) {1449 if (need_realloc) {
1451 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);1450 const vaddr = try self.growAtom(atom_index, code_len, required_alignment);
1452 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), sym.value, vaddr });1451 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), sym.value, vaddr });
1453 log.debug(" (required alignment 0x{x}", .{required_alignment});1452 log.debug(" (required alignment 0x{x}", .{required_alignment});
14541453
1455 if (vaddr != sym.value) {1454 if (vaddr != sym.value) {
...@@ -1465,13 +1464,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd...@@ -1465,13 +1464,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd
1465 self.getAtomPtr(atom_index).size = code_len;1464 self.getAtomPtr(atom_index).size = code_len;
1466 } else {1465 } else {
1467 const sym = atom.getSymbolPtr(self);1466 const sym = atom.getSymbolPtr(self);
1468 try self.setSymbolName(sym, decl_name.toSlice(&mod.intern_pool));1467 try self.setSymbolName(sym, decl.fqn.toSlice(&mod.intern_pool));
1469 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));1468 sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1));
1470 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };1469 sym.type = .{ .complex_type = complex_type, .base_type = .NULL };
14711470
1472 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);1471 const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment);
1473 errdefer self.freeAtom(atom_index);1472 errdefer self.freeAtom(atom_index);
1474 log.debug("allocated atom for {} at 0x{x}", .{ decl_name.fmt(&mod.intern_pool), vaddr });1473 log.debug("allocated atom for {} at 0x{x}", .{ decl.fqn.fmt(&mod.intern_pool), vaddr });
1475 self.getAtomPtr(atom_index).size = code_len;1474 self.getAtomPtr(atom_index).size = code_len;
1476 sym.value = vaddr;1475 sym.value = vaddr;
14771476
src/link/Dwarf.zig+4-6
...@@ -1082,9 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1082,9 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
1082 defer tracy.end();1082 defer tracy.end();
10831083
1084 const decl = pt.zcu.declPtr(decl_index);1084 const decl = pt.zcu.declPtr(decl_index);
1085 const decl_linkage_name = try decl.fullyQualifiedName(pt);1085 log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
1086
1087 log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl });
10881086
1089 const gpa = self.allocator;1087 const gpa = self.allocator;
1090 var decl_state: DeclState = .{1088 var decl_state: DeclState = .{
...@@ -1157,7 +1155,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec...@@ -1157,7 +1155,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec
11571155
1158 // .debug_info subprogram1156 // .debug_info subprogram
1159 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);1157 const decl_name_slice = decl.name.toSlice(&pt.zcu.intern_pool);
1160 const decl_linkage_name_slice = decl_linkage_name.toSlice(&pt.zcu.intern_pool);1158 const decl_linkage_name_slice = decl.fqn.toSlice(&pt.zcu.intern_pool);
1161 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +1159 try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 +
1162 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));1160 (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1));
11631161
...@@ -2700,7 +2698,7 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {...@@ -2700,7 +2698,7 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void {
2700 try addDbgInfoErrorSetNames(2698 try addDbgInfoErrorSetNames(
2701 pt,2699 pt,
2702 Type.anyerror,2700 Type.anyerror,
2703 pt.zcu.global_error_set.keys(),2701 pt.zcu.intern_pool.global_error_set.getNamesFromMainThread(),
2704 target,2702 target,
2705 &dbg_info_buffer,2703 &dbg_info_buffer,
2706 );2704 );
...@@ -2869,7 +2867,7 @@ fn addDbgInfoErrorSetNames(...@@ -2869,7 +2867,7 @@ fn addDbgInfoErrorSetNames(
2869 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);2867 mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian);
28702868
2871 for (error_names) |error_name| {2869 for (error_names) |error_name| {
2872 const int = try pt.zcu.getErrorValue(error_name);2870 const int = try pt.getErrorValue(error_name);
2873 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);2871 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);
2874 // DW.AT.enumerator2872 // DW.AT.enumerator
2875 try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));2873 try dbg_info_buffer.ensureUnusedCapacity(error_name_slice.len + 2 + @sizeOf(u64));
src/link/Elf/ZigObject.zig+9-11
...@@ -907,10 +907,10 @@ fn updateDeclCode(...@@ -907,10 +907,10 @@ fn updateDeclCode(
907) !void {907) !void {
908 const gpa = elf_file.base.comp.gpa;908 const gpa = elf_file.base.comp.gpa;
909 const mod = pt.zcu;909 const mod = pt.zcu;
910 const ip = &mod.intern_pool;
910 const decl = mod.declPtr(decl_index);911 const decl = mod.declPtr(decl_index);
911 const decl_name = try decl.fullyQualifiedName(pt);
912912
913 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });913 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
914914
915 const required_alignment = decl.getAlignment(pt).max(915 const required_alignment = decl.getAlignment(pt).max(
916 target_util.minFunctionAlignment(mod.getTarget()),916 target_util.minFunctionAlignment(mod.getTarget()),
...@@ -923,7 +923,7 @@ fn updateDeclCode(...@@ -923,7 +923,7 @@ fn updateDeclCode(
923 sym.output_section_index = shdr_index;923 sym.output_section_index = shdr_index;
924 atom_ptr.output_section_index = shdr_index;924 atom_ptr.output_section_index = shdr_index;
925925
926 sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));926 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
927 atom_ptr.flags.alive = true;927 atom_ptr.flags.alive = true;
928 atom_ptr.name_offset = sym.name_offset;928 atom_ptr.name_offset = sym.name_offset;
929 esym.st_name = sym.name_offset;929 esym.st_name = sym.name_offset;
...@@ -940,7 +940,7 @@ fn updateDeclCode(...@@ -940,7 +940,7 @@ fn updateDeclCode(
940 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));940 const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value));
941 if (need_realloc) {941 if (need_realloc) {
942 try atom_ptr.grow(elf_file);942 try atom_ptr.grow(elf_file);
943 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom_ptr.value });943 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom_ptr.value });
944 if (old_vaddr != atom_ptr.value) {944 if (old_vaddr != atom_ptr.value) {
945 sym.value = 0;945 sym.value = 0;
946 esym.st_value = 0;946 esym.st_value = 0;
...@@ -1007,11 +1007,11 @@ fn updateTlv(...@@ -1007,11 +1007,11 @@ fn updateTlv(
1007 code: []const u8,1007 code: []const u8,
1008) !void {1008) !void {
1009 const mod = pt.zcu;1009 const mod = pt.zcu;
1010 const ip = &mod.intern_pool;
1010 const gpa = mod.gpa;1011 const gpa = mod.gpa;
1011 const decl = mod.declPtr(decl_index);1012 const decl = mod.declPtr(decl_index);
1012 const decl_name = try decl.fullyQualifiedName(pt);
10131013
1014 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl });1014 log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(ip), decl });
10151015
1016 const required_alignment = decl.getAlignment(pt);1016 const required_alignment = decl.getAlignment(pt);
10171017
...@@ -1023,7 +1023,7 @@ fn updateTlv(...@@ -1023,7 +1023,7 @@ fn updateTlv(
1023 sym.output_section_index = shndx;1023 sym.output_section_index = shndx;
1024 atom_ptr.output_section_index = shndx;1024 atom_ptr.output_section_index = shndx;
10251025
1026 sym.name_offset = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));1026 sym.name_offset = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
1027 atom_ptr.flags.alive = true;1027 atom_ptr.flags.alive = true;
1028 atom_ptr.name_offset = sym.name_offset;1028 atom_ptr.name_offset = sym.name_offset;
1029 esym.st_value = 0;1029 esym.st_value = 0;
...@@ -1286,9 +1286,8 @@ pub fn lowerUnnamedConst(...@@ -1286,9 +1286,8 @@ pub fn lowerUnnamedConst(
1286 }1286 }
1287 const unnamed_consts = gop.value_ptr;1287 const unnamed_consts = gop.value_ptr;
1288 const decl = mod.declPtr(decl_index);1288 const decl = mod.declPtr(decl_index);
1289 const decl_name = try decl.fullyQualifiedName(pt);
1290 const index = unnamed_consts.items.len;1289 const index = unnamed_consts.items.len;
1291 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1290 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
1292 defer gpa.free(name);1291 defer gpa.free(name);
1293 const ty = val.typeOf(mod);1292 const ty = val.typeOf(mod);
1294 const sym_index = switch (try self.lowerConst(1293 const sym_index = switch (try self.lowerConst(
...@@ -1473,9 +1472,8 @@ pub fn updateDeclLineNumber(...@@ -1473,9 +1472,8 @@ pub fn updateDeclLineNumber(
1473 defer tracy.end();1472 defer tracy.end();
14741473
1475 const decl = pt.zcu.declPtr(decl_index);1474 const decl = pt.zcu.declPtr(decl_index);
1476 const decl_name = try decl.fullyQualifiedName(pt);
14771475
1478 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });1476 log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
14791477
1480 if (self.dwarf) |*dw| {1478 if (self.dwarf) |*dw| {
1481 try dw.updateDeclLineNumber(pt.zcu, decl_index);1479 try dw.updateDeclLineNumber(pt.zcu, decl_index);
src/link/MachO/ZigObject.zig+10-14
...@@ -809,10 +809,10 @@ fn updateDeclCode(...@@ -809,10 +809,10 @@ fn updateDeclCode(
809) !void {809) !void {
810 const gpa = macho_file.base.comp.gpa;810 const gpa = macho_file.base.comp.gpa;
811 const mod = pt.zcu;811 const mod = pt.zcu;
812 const ip = &mod.intern_pool;
812 const decl = mod.declPtr(decl_index);813 const decl = mod.declPtr(decl_index);
813 const decl_name = try decl.fullyQualifiedName(pt);
814814
815 log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl });815 log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl });
816816
817 const required_alignment = decl.getAlignment(pt);817 const required_alignment = decl.getAlignment(pt);
818818
...@@ -824,7 +824,7 @@ fn updateDeclCode(...@@ -824,7 +824,7 @@ fn updateDeclCode(
824 sym.out_n_sect = sect_index;824 sym.out_n_sect = sect_index;
825 atom.out_n_sect = sect_index;825 atom.out_n_sect = sect_index;
826826
827 sym.name = try self.strtab.insert(gpa, decl_name.toSlice(&mod.intern_pool));827 sym.name = try self.strtab.insert(gpa, decl.fqn.toSlice(ip));
828 atom.flags.alive = true;828 atom.flags.alive = true;
829 atom.name = sym.name;829 atom.name = sym.name;
830 nlist.n_strx = sym.name;830 nlist.n_strx = sym.name;
...@@ -843,7 +843,7 @@ fn updateDeclCode(...@@ -843,7 +843,7 @@ fn updateDeclCode(
843843
844 if (need_realloc) {844 if (need_realloc) {
845 try atom.grow(macho_file);845 try atom.grow(macho_file);
846 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl_name.fmt(&mod.intern_pool), old_vaddr, atom.value });846 log.debug("growing {} from 0x{x} to 0x{x}", .{ decl.fqn.fmt(ip), old_vaddr, atom.value });
847 if (old_vaddr != atom.value) {847 if (old_vaddr != atom.value) {
848 sym.value = 0;848 sym.value = 0;
849 nlist.n_value = 0;849 nlist.n_value = 0;
...@@ -893,25 +893,22 @@ fn updateTlv(...@@ -893,25 +893,22 @@ fn updateTlv(
893 sect_index: u8,893 sect_index: u8,
894 code: []const u8,894 code: []const u8,
895) !void {895) !void {
896 const ip = &pt.zcu.intern_pool;
896 const decl = pt.zcu.declPtr(decl_index);897 const decl = pt.zcu.declPtr(decl_index);
897 const decl_name = try decl.fullyQualifiedName(pt);
898898
899 log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });899 log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
900
901 const decl_name_slice = decl_name.toSlice(&pt.zcu.intern_pool);
902 const required_alignment = decl.getAlignment(pt);
903900
904 // 1. Lower TLV initializer901 // 1. Lower TLV initializer
905 const init_sym_index = try self.createTlvInitializer(902 const init_sym_index = try self.createTlvInitializer(
906 macho_file,903 macho_file,
907 decl_name_slice,904 decl.fqn.toSlice(ip),
908 required_alignment,905 decl.getAlignment(pt),
909 sect_index,906 sect_index,
910 code,907 code,
911 );908 );
912909
913 // 2. Create TLV descriptor910 // 2. Create TLV descriptor
914 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl_name_slice);911 try self.createTlvDescriptor(macho_file, sym_index, init_sym_index, decl.fqn.toSlice(ip));
915}912}
916913
917fn createTlvInitializer(914fn createTlvInitializer(
...@@ -1099,9 +1096,8 @@ pub fn lowerUnnamedConst(...@@ -1099,9 +1096,8 @@ pub fn lowerUnnamedConst(
1099 }1096 }
1100 const unnamed_consts = gop.value_ptr;1097 const unnamed_consts = gop.value_ptr;
1101 const decl = mod.declPtr(decl_index);1098 const decl = mod.declPtr(decl_index);
1102 const decl_name = try decl.fullyQualifiedName(pt);
1103 const index = unnamed_consts.items.len;1099 const index = unnamed_consts.items.len;
1104 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });1100 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
1105 defer gpa.free(name);1101 defer gpa.free(name);
1106 const sym_index = switch (try self.lowerConst(1102 const sym_index = switch (try self.lowerConst(
1107 macho_file,1103 macho_file,
src/link/Plan9.zig+1-3
...@@ -483,11 +483,9 @@ pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index...@@ -483,11 +483,9 @@ pub fn lowerUnnamedConst(self: *Plan9, pt: Zcu.PerThread, val: Value, decl_index
483 }483 }
484 const unnamed_consts = gop.value_ptr;484 const unnamed_consts = gop.value_ptr;
485485
486 const decl_name = try decl.fullyQualifiedName(pt);
487
488 const index = unnamed_consts.items.len;486 const index = unnamed_consts.items.len;
489 // name is freed when the unnamed const is freed487 // name is freed when the unnamed const is freed
490 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl_name.fmt(&mod.intern_pool), index });488 const name = try std.fmt.allocPrint(gpa, "__unnamed_{}_{d}", .{ decl.fqn.fmt(&mod.intern_pool), index });
491489
492 const sym_index = try self.allocateSymbolIndex();490 const sym_index = try self.allocateSymbolIndex();
493 const new_atom_idx = try self.createAtom();491 const new_atom_idx = try self.createAtom();
src/link/SpirV.zig+4-4
...@@ -227,9 +227,9 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -227,9 +227,9 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
227 var error_info = std.ArrayList(u8).init(self.object.gpa);227 var error_info = std.ArrayList(u8).init(self.object.gpa);
228 defer error_info.deinit();228 defer error_info.deinit();
229229
230 try error_info.appendSlice("zig_errors");230 try error_info.appendSlice("zig_errors:");
231 const mod = self.base.comp.module.?;231 const ip = &self.base.comp.module.?.intern_pool;
232 for (mod.global_error_set.keys()) |name| {232 for (ip.global_error_set.getNamesFromMainThread()) |name| {
233 // Errors can contain pretty much any character - to encode them in a string we must escape233 // Errors can contain pretty much any character - to encode them in a string we must escape
234 // them somehow. Easiest here is to use some established scheme, one which also preseves the234 // them somehow. Easiest here is to use some established scheme, one which also preseves the
235 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.235 // name if it contains no strange characters is nice for debugging. URI encoding fits the bill.
...@@ -238,7 +238,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n...@@ -238,7 +238,7 @@ pub fn flushModule(self: *SpirV, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
238 try error_info.append(':');238 try error_info.append(':');
239 try std.Uri.Component.percentEncode(239 try std.Uri.Component.percentEncode(
240 error_info.writer(),240 error_info.writer(),
241 name.toSlice(&mod.intern_pool),241 name.toSlice(ip),
242 struct {242 struct {
243 fn isValidChar(c: u8) bool {243 fn isValidChar(c: u8) bool {
244 return switch (c) {244 return switch (c) {
src/link/Wasm/ZigObject.zig+20-16
...@@ -346,8 +346,7 @@ fn finishUpdateDecl(...@@ -346,8 +346,7 @@ fn finishUpdateDecl(
346 const atom_index = decl_info.atom;346 const atom_index = decl_info.atom;
347 const atom = wasm_file.getAtomPtr(atom_index);347 const atom = wasm_file.getAtomPtr(atom_index);
348 const sym = zig_object.symbol(atom.sym_index);348 const sym = zig_object.symbol(atom.sym_index);
349 const full_name = try decl.fullyQualifiedName(pt);349 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(ip));
350 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip));
351 try atom.code.appendSlice(gpa, code);350 try atom.code.appendSlice(gpa, code);
352 atom.size = @intCast(code.len);351 atom.size = @intCast(code.len);
353352
...@@ -387,7 +386,7 @@ fn finishUpdateDecl(...@@ -387,7 +386,7 @@ fn finishUpdateDecl(
387 // Will be freed upon freeing of decl or after cleanup of Wasm binary.386 // Will be freed upon freeing of decl or after cleanup of Wasm binary.
388 const full_segment_name = try std.mem.concat(gpa, u8, &.{387 const full_segment_name = try std.mem.concat(gpa, u8, &.{
389 segment_name,388 segment_name,
390 full_name.toSlice(ip),389 decl.fqn.toSlice(ip),
391 });390 });
392 errdefer gpa.free(full_segment_name);391 errdefer gpa.free(full_segment_name);
393 sym.tag = .data;392 sym.tag = .data;
...@@ -436,9 +435,8 @@ pub fn getOrCreateAtomForDecl(...@@ -436,9 +435,8 @@ pub fn getOrCreateAtomForDecl(
436 const sym_index = try zig_object.allocateSymbol(gpa);435 const sym_index = try zig_object.allocateSymbol(gpa);
437 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };436 gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) };
438 const decl = pt.zcu.declPtr(decl_index);437 const decl = pt.zcu.declPtr(decl_index);
439 const full_name = try decl.fullyQualifiedName(pt);
440 const sym = zig_object.symbol(sym_index);438 const sym = zig_object.symbol(sym_index);
441 sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(&pt.zcu.intern_pool));439 sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(&pt.zcu.intern_pool));
442 }440 }
443 return gop.value_ptr.atom;441 return gop.value_ptr.atom;
444}442}
...@@ -494,9 +492,8 @@ pub fn lowerUnnamedConst(...@@ -494,9 +492,8 @@ pub fn lowerUnnamedConst(
494 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);492 const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index);
495 const parent_atom = wasm_file.getAtom(parent_atom_index);493 const parent_atom = wasm_file.getAtom(parent_atom_index);
496 const local_index = parent_atom.locals.items.len;494 const local_index = parent_atom.locals.items.len;
497 const fqn = try decl.fullyQualifiedName(pt);
498 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{495 const name = try std.fmt.allocPrintZ(gpa, "__unnamed_{}_{d}", .{
499 fqn.fmt(&mod.intern_pool), local_index,496 decl.fqn.fmt(&mod.intern_pool), local_index,
500 });497 });
501 defer gpa.free(name);498 defer gpa.free(name);
502499
...@@ -655,13 +652,22 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per...@@ -655,13 +652,22 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
655 // Addend for each relocation to the table652 // Addend for each relocation to the table
656 var addend: u32 = 0;653 var addend: u32 = 0;
657 const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };654 const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid };
658 for (pt.zcu.global_error_set.keys()) |error_name| {655 const slice_ty = Type.slice_const_u8_sentinel_0;
659 const atom = wasm_file.getAtomPtr(atom_index);656 const atom = wasm_file.getAtomPtr(atom_index);
657 {
658 // TODO: remove this unreachable entry
659 try atom.code.appendNTimes(gpa, 0, 4);
660 try atom.code.writer(gpa).writeInt(u32, 0, .little);
661 atom.size += @intCast(slice_ty.abiSize(pt));
662 addend += 1;
660663
661 const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool);664 try names_atom.code.append(gpa, 0);
665 }
666 const ip = &pt.zcu.intern_pool;
667 for (ip.global_error_set.getNamesFromMainThread()) |error_name| {
668 const error_name_slice = error_name.toSlice(ip);
662 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated669 const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated
663670
664 const slice_ty = Type.slice_const_u8_sentinel_0;
665 const offset = @as(u32, @intCast(atom.code.items.len));671 const offset = @as(u32, @intCast(atom.code.items.len));
666 // first we create the data for the slice of the name672 // first we create the data for the slice of the name
667 try atom.code.appendNTimes(gpa, 0, 4); // ptr to name, will be relocated673 try atom.code.appendNTimes(gpa, 0, 4); // ptr to name, will be relocated
...@@ -680,7 +686,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per...@@ -680,7 +686,7 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per
680 try names_atom.code.ensureUnusedCapacity(gpa, len);686 try names_atom.code.ensureUnusedCapacity(gpa, len);
681 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);687 names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]);
682688
683 log.debug("Populated error name: '{}'", .{error_name.fmt(&pt.zcu.intern_pool)});689 log.debug("Populated error name: '{}'", .{error_name.fmt(ip)});
684 }690 }
685 names_atom.size = addend;691 names_atom.size = addend;
686 zig_object.error_names_atom = names_atom_index;692 zig_object.error_names_atom = names_atom_index;
...@@ -1045,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {...@@ -1045,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void {
1045 const gpa = wasm_file.base.comp.gpa;1051 const gpa = wasm_file.base.comp.gpa;
1046 const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;1052 const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return;
10471053
1048 const errors_len = wasm_file.base.comp.module.?.global_error_set.count();1054 const errors_len = 1 + wasm_file.base.comp.module.?.intern_pool.global_error_set.mutate.list.len;
1049 // overwrite existing atom if it already exists (maybe the error set has increased)1055 // overwrite existing atom if it already exists (maybe the error set has increased)
1050 // if not, allcoate a new atom.1056 // if not, allcoate a new atom.
1051 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {1057 const atom_index = if (wasm_file.symbol_atom.get(.{ .file = zig_object.index, .index = sym_index })) |index| blk: {
...@@ -1127,9 +1133,7 @@ pub fn updateDeclLineNumber(...@@ -1127,9 +1133,7 @@ pub fn updateDeclLineNumber(
1127) !void {1133) !void {
1128 if (zig_object.dwarf) |*dw| {1134 if (zig_object.dwarf) |*dw| {
1129 const decl = pt.zcu.declPtr(decl_index);1135 const decl = pt.zcu.declPtr(decl_index);
1130 const decl_name = try decl.fullyQualifiedName(pt);1136 log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl });
1131
1132 log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl });
1133 try dw.updateDeclLineNumber(pt.zcu, decl_index);1137 try dw.updateDeclLineNumber(pt.zcu, decl_index);
1134 }1138 }
1135}1139}
src/print_air.zig+7-1
...@@ -356,7 +356,13 @@ const Writer = struct {...@@ -356,7 +356,13 @@ const Writer = struct {
356 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {356 fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
357 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;357 const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg;
358 try w.writeType(s, arg.ty.toType());358 try w.writeType(s, arg.ty.toType());
359 try s.print(", {d}", .{arg.src_index});359 switch (arg.name) {
360 .none => {},
361 _ => {
362 const name = w.air.nullTerminatedString(@intFromEnum(arg.name));
363 try s.print(", \"{}\"", .{std.zig.fmtEscapes(name)});
364 },
365 }
360 }366 }
361367
362 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {368 fn writeTyOp(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void {
src/print_value.zig+2-2
...@@ -299,8 +299,8 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve...@@ -299,8 +299,8 @@ fn printPtrDerivation(derivation: Value.PointerDeriveStep, writer: anytype, leve
299 int.ptr_ty.fmt(pt),299 int.ptr_ty.fmt(pt),
300 int.addr,300 int.addr,
301 }),301 }),
302 .decl_ptr => |decl| {302 .decl_ptr => |decl_index| {
303 try zcu.declPtr(decl).renderFullyQualifiedName(zcu, writer);303 try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)});
304 },304 },
305 .anon_decl_ptr => |anon| {305 .anon_decl_ptr => |anon| {
306 const ty = Value.fromInterned(anon.val).typeOf(zcu);306 const ty = Value.fromInterned(anon.val).typeOf(zcu);