| author | |
| committer | |
| log | 80d7e260d78400b841f15e3350473650b87931a5 |
| tree | 3035bae743da24cbe1d5046469fea0a5542a8829 |
| parent | 45be80364659332807b527670514332a4b835f84 |
| parent | 77810f288216ef3e35f3d0df4a04351297560a5e |
| signature |
InternPool: fix more races blocking a separate codegen/linker thread27 files changed, 1472 insertions(+), 1004 deletions(-)
src/Air.zig+6-1| ... | ... | @@ -1034,7 +1034,12 @@ pub const Inst = struct { |
| 1034 | 1034 | ty: Type, |
| 1035 | 1035 | arg: struct { |
| 1036 | 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 | 1044 | ty_op: struct { |
| 1040 | 1045 | ty: Ref, |
src/Compilation.zig+51-78| ... | ... | @@ -1877,6 +1877,7 @@ pub fn destroy(comp: *Compilation) void { |
| 1877 | 1877 | if (comp.module) |zcu| zcu.deinit(); |
| 1878 | 1878 | comp.cache_use.deinit(); |
| 1879 | 1879 | comp.work_queue.deinit(); |
| 1880 | if (!InternPool.single_threaded) comp.codegen_work.queue.deinit(); | |
| 1880 | 1881 | comp.c_object_work_queue.deinit(); |
| 1881 | 1882 | if (!build_options.only_core_functionality) { |
| 1882 | 1883 | comp.win32_resource_work_queue.deinit(); |
| ... | ... | @@ -2119,12 +2120,14 @@ pub fn update(comp: *Compilation, main_progress_node: std.Progress.Node) !void { |
| 2119 | 2120 | } |
| 2120 | 2121 | |
| 2121 | 2122 | if (comp.module) |zcu| { |
| 2123 | const pt: Zcu.PerThread = .{ .zcu = zcu, .tid = .main }; | |
| 2124 | ||
| 2122 | 2125 | zcu.compile_log_text.shrinkAndFree(gpa, 0); |
| 2123 | 2126 | |
| 2124 | 2127 | // Make sure std.zig is inside the import_table. We unconditionally need |
| 2125 | 2128 | // it for start.zig. |
| 2126 | 2129 | const std_mod = zcu.std_mod; |
| 2127 | _ = try zcu.importPkg(std_mod); | |
| 2130 | _ = try pt.importPkg(std_mod); | |
| 2128 | 2131 | |
| 2129 | 2132 | // Normally we rely on importing std to in turn import the root source file |
| 2130 | 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 | 2136 | // Likewise, in the case of `zig test`, the test runner is the root source file, |
| 2134 | 2137 | // and so there is nothing to import the main file. |
| 2135 | 2138 | if (comp.config.is_test) { |
| 2136 | _ = try zcu.importPkg(zcu.main_mod); | |
| 2139 | _ = try pt.importPkg(zcu.main_mod); | |
| 2137 | 2140 | } |
| 2138 | 2141 | |
| 2139 | 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 | } |
| 2142 | 2145 | |
| 2143 | 2146 | // Put a work item in for every known source file to detect if |
| 2144 | 2147 | // it changed, and, if so, re-compute ZIR and then queue the job |
| 2145 | 2148 | // to update it. |
| 2146 | 2149 | try comp.astgen_work_queue.ensureUnusedCapacity(zcu.import_table.count()); |
| 2147 | for (zcu.import_table.values(), 0..) |file, file_index_usize| { | |
| 2148 | const file_index: Zcu.File.Index = @enumFromInt(file_index_usize); | |
| 2149 | if (file.mod.isBuiltin()) continue; | |
| 2150 | for (zcu.import_table.values()) |file_index| { | |
| 2151 | if (zcu.fileByIndex(file_index).mod.isBuiltin()) continue; | |
| 2150 | 2152 | comp.astgen_work_queue.writeItemAssumeCapacity(file_index); |
| 2151 | 2153 | } |
| 2152 | 2154 | |
| ... | ... | @@ -2641,7 +2643,8 @@ fn resolveEmitLoc( |
| 2641 | 2643 | return slice.ptr; |
| 2642 | 2644 | } |
| 2643 | 2645 | |
| 2644 | fn reportMultiModuleErrors(zcu: *Zcu) !void { | |
| 2646 | fn reportMultiModuleErrors(pt: Zcu.PerThread) !void { | |
| 2647 | const zcu = pt.zcu; | |
| 2645 | 2648 | const gpa = zcu.gpa; |
| 2646 | 2649 | const ip = &zcu.intern_pool; |
| 2647 | 2650 | // 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 | 2654 | // Attach the "some omitted" note to the final error message |
| 2652 | 2655 | var last_err: ?*Zcu.ErrorMsg = null; |
| 2653 | 2656 | |
| 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 | 2659 | if (!file.multi_pkg) continue; |
| 2656 | 2660 | |
| 2657 | 2661 | num_errors += 1; |
| 2658 | 2662 | if (num_errors > max_errors) continue; |
| 2659 | 2663 | |
| 2660 | const file_index: Zcu.File.Index = @enumFromInt(file_index_usize); | |
| 2661 | ||
| 2662 | 2664 | const err = err_blk: { |
| 2663 | 2665 | // Like with errors, let's cap the number of notes to prevent a huge error spew. |
| 2664 | 2666 | const max_notes = 5; |
| ... | ... | @@ -2674,7 +2676,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void { |
| 2674 | 2676 | .import => |import| try Zcu.ErrorMsg.init( |
| 2675 | 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 | 2683 | .offset = .{ .token_abs = import.token }, |
| 2679 | 2684 | }, |
| 2680 | 2685 | "imported from module {s}", |
| ... | ... | @@ -2683,7 +2688,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void { |
| 2683 | 2688 | .root => |pkg| try Zcu.ErrorMsg.init( |
| 2684 | 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 | 2695 | .offset = .entire_file, |
| 2688 | 2696 | }, |
| 2689 | 2697 | "root of module {s}", |
| ... | ... | @@ -2697,7 +2705,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void { |
| 2697 | 2705 | notes[num_notes] = try Zcu.ErrorMsg.init( |
| 2698 | 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 | 2712 | .offset = .entire_file, |
| 2702 | 2713 | }, |
| 2703 | 2714 | "{} more references omitted", |
| ... | ... | @@ -2709,7 +2720,10 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void { |
| 2709 | 2720 | const err = try Zcu.ErrorMsg.create( |
| 2710 | 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 | 2727 | .offset = .entire_file, |
| 2714 | 2728 | }, |
| 2715 | 2729 | "file exists in multiple modules", |
| ... | ... | @@ -2749,8 +2763,9 @@ fn reportMultiModuleErrors(zcu: *Zcu) !void { |
| 2749 | 2763 | // to add this flag after reporting the errors however, as otherwise |
| 2750 | 2764 | // we'd get an error for every single downstream file, which wouldn't be |
| 2751 | 2765 | // very useful. |
| 2752 | for (zcu.import_table.values()) |file| { | |
| 2753 | if (file.multi_pkg) file.recursiveMarkMultiPkg(zcu); | |
| 2766 | for (zcu.import_table.values()) |file_index| { | |
| 2767 | const file = zcu.fileByIndex(file_index); | |
| 2768 | if (file.multi_pkg) file.recursiveMarkMultiPkg(pt); | |
| 2754 | 2769 | } |
| 2755 | 2770 | } |
| 2756 | 2771 | |
| ... | ... | @@ -2774,7 +2789,7 @@ const Header = extern struct { |
| 2774 | 2789 | //extra_len: u32, |
| 2775 | 2790 | //limbs_len: u32, |
| 2776 | 2791 | //string_bytes_len: u32, |
| 2777 | tracked_insts_len: u32, | |
| 2792 | //tracked_insts_len: u32, | |
| 2778 | 2793 | src_hash_deps_len: u32, |
| 2779 | 2794 | decl_val_deps_len: u32, |
| 2780 | 2795 | namespace_deps_len: u32, |
| ... | ... | @@ -2782,7 +2797,7 @@ const Header = extern struct { |
| 2782 | 2797 | first_dependency_len: u32, |
| 2783 | 2798 | dep_entries_len: u32, |
| 2784 | 2799 | free_dep_entries_len: u32, |
| 2785 | files_len: u32, | |
| 2800 | //files_len: u32, | |
| 2786 | 2801 | }, |
| 2787 | 2802 | }; |
| 2788 | 2803 | |
| ... | ... | @@ -2803,7 +2818,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 2803 | 2818 | //.extra_len = @intCast(ip.extra.items.len), |
| 2804 | 2819 | //.limbs_len = @intCast(ip.limbs.items.len), |
| 2805 | 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 | 2822 | .src_hash_deps_len = @intCast(ip.src_hash_deps.count()), |
| 2808 | 2823 | .decl_val_deps_len = @intCast(ip.decl_val_deps.count()), |
| 2809 | 2824 | .namespace_deps_len = @intCast(ip.namespace_deps.count()), |
| ... | ... | @@ -2811,7 +2826,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 2811 | 2826 | .first_dependency_len = @intCast(ip.first_dependency.count()), |
| 2812 | 2827 | .dep_entries_len = @intCast(ip.dep_entries.items.len), |
| 2813 | 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 | 2832 | addBuf(&bufs_list, &bufs_len, mem.asBytes(&header)); |
| ... | ... | @@ -2820,7 +2835,7 @@ pub fn saveState(comp: *Compilation) !void { |
| 2820 | 2835 | //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.data))); |
| 2821 | 2836 | //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.items.items(.tag))); |
| 2822 | 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())); | |
| 2824 | 2839 | |
| 2825 | 2840 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.keys())); |
| 2826 | 2841 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.src_hash_deps.values())); |
| ... | ... | @@ -2836,8 +2851,8 @@ pub fn saveState(comp: *Compilation) !void { |
| 2836 | 2851 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.dep_entries.items)); |
| 2837 | 2852 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.free_dep_entries.items)); |
| 2838 | 2853 | |
| 2839 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys())); | |
| 2840 | addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values())); | |
| 2854 | //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.keys())); | |
| 2855 | //addBuf(&bufs_list, &bufs_len, mem.sliceAsBytes(ip.files.values())); | |
| 2841 | 2856 | |
| 2842 | 2857 | // TODO: compilation errors |
| 2843 | 2858 | // TODO: namespaces |
| ... | ... | @@ -2929,7 +2944,7 @@ pub fn totalErrorCount(comp: *Compilation) u32 { |
| 2929 | 2944 | } |
| 2930 | 2945 | } |
| 2931 | 2946 | |
| 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 | 2948 | total += 1; |
| 2934 | 2949 | } |
| 2935 | 2950 | } |
| ... | ... | @@ -3058,7 +3073,7 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle { |
| 3058 | 3073 | try addModuleErrorMsg(zcu, &bundle, value.*, &all_references); |
| 3059 | 3074 | } |
| 3060 | 3075 | |
| 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 | 3077 | if (actual_error_count > zcu.error_limit) { |
| 3063 | 3078 | try bundle.addRootErrorMessage(.{ |
| 3064 | 3079 | .msg = try bundle.printString("ZCU used more errors than possible: used {d}, max {d}", .{ |
| ... | ... | @@ -3443,11 +3458,12 @@ fn performAllTheWorkInner( |
| 3443 | 3458 | } |
| 3444 | 3459 | } |
| 3445 | 3460 | |
| 3446 | if (comp.module) |mod| { | |
| 3447 | try reportMultiModuleErrors(mod); | |
| 3448 | try mod.flushRetryableFailures(); | |
| 3449 | mod.sema_prog_node = main_progress_node.start("Semantic Analysis", 0); | |
| 3450 | mod.codegen_prog_node = main_progress_node.start("Code Generation", 0); | |
| 3461 | if (comp.module) |zcu| { | |
| 3462 | const pt: Zcu.PerThread = .{ .zcu = comp.module.?, .tid = .main }; | |
| 3463 | try reportMultiModuleErrors(pt); | |
| 3464 | try zcu.flushRetryableFailures(); | |
| 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 | } |
| 3452 | 3468 | |
| 3453 | 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 | 4147 | }; |
| 4132 | 4148 | } |
| 4133 | 4149 | |
| 4134 | const AstGenSrc = union(enum) { | |
| 4135 | root, | |
| 4136 | import: struct { | |
| 4137 | importing_file: Zcu.File.Index, | |
| 4138 | import_tok: std.zig.Ast.TokenIndex, | |
| 4139 | }, | |
| 4140 | }; | |
| 4141 | ||
| 4142 | 4150 | fn workerAstGenFile( |
| 4143 | 4151 | tid: usize, |
| 4144 | 4152 | comp: *Compilation, |
| ... | ... | @@ -4148,7 +4156,7 @@ fn workerAstGenFile( |
| 4148 | 4156 | root_decl: Zcu.Decl.OptionalIndex, |
| 4149 | 4157 | prog_node: std.Progress.Node, |
| 4150 | 4158 | wg: *WaitGroup, |
| 4151 | src: AstGenSrc, | |
| 4159 | src: Zcu.AstGenSrc, | |
| 4152 | 4160 | ) void { |
| 4153 | 4161 | const child_prog_node = prog_node.start(file.sub_file_path, 0); |
| 4154 | 4162 | defer child_prog_node.end(); |
| ... | ... | @@ -4158,7 +4166,7 @@ fn workerAstGenFile( |
| 4158 | 4166 | error.AnalysisFail => return, |
| 4159 | 4167 | else => { |
| 4160 | 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 | 4170 | // Swallowing this error is OK because it's implied to be OOM when |
| 4163 | 4171 | // there is a missing `failed_files` error message. |
| 4164 | 4172 | error.OutOfMemory => {}, |
| ... | ... | @@ -4189,9 +4197,9 @@ fn workerAstGenFile( |
| 4189 | 4197 | comp.mutex.lock(); |
| 4190 | 4198 | defer comp.mutex.unlock(); |
| 4191 | 4199 | |
| 4192 | const res = pt.zcu.importFile(file, import_path) catch continue; | |
| 4200 | const res = pt.importFile(file, import_path) catch continue; | |
| 4193 | 4201 | if (!res.is_pkg) { |
| 4194 | res.file.addReference(pt.zcu.*, .{ .import = .{ | |
| 4202 | res.file.addReference(pt.zcu, .{ .import = .{ | |
| 4195 | 4203 | .file = file_index, |
| 4196 | 4204 | .token = item.data.token, |
| 4197 | 4205 | } }) catch continue; |
| ... | ... | @@ -4204,7 +4212,7 @@ fn workerAstGenFile( |
| 4204 | 4212 | log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{ |
| 4205 | 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 | 4216 | .importing_file = file_index, |
| 4209 | 4217 | .import_tok = item.data.token, |
| 4210 | 4218 | } }; |
| ... | ... | @@ -4557,41 +4565,6 @@ fn reportRetryableWin32ResourceError( |
| 4557 | 4565 | } |
| 4558 | 4566 | } |
| 4559 | 4567 | |
| 4560 | fn 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 | ||
| 4595 | 4568 | fn reportRetryableEmbedFileError( |
| 4596 | 4569 | comp: *Compilation, |
| 4597 | 4570 | embed_file: *Zcu.EmbedFile, |
src/InternPool.zig+649-220| ... | ... | @@ -1,12 +1,13 @@ |
| 1 | 1 | //! All interned objects have both a value and a type. |
| 2 | //! This data structure is self-contained, with the following exceptions: | |
| 3 | //! * Module.Namespace has a pointer to Module.File | |
| 2 | //! This data structure is self-contained. | |
| 4 | 3 | |
| 5 | 4 | /// One item per thread, indexed by `tid`, which is dense and unique per thread. |
| 6 | 5 | locals: []Local = &.{}, |
| 7 | 6 | /// Length must be a power of two and represents the number of simultaneous |
| 8 | 7 | /// writers that can mutate any single sharded data structure. |
| 9 | 8 | shards: []Shard = &.{}, |
| 9 | /// Key is the error name, index is the error tag value. Index 0 has a length-0 string. | |
| 10 | global_error_set: GlobalErrorSet = GlobalErrorSet.empty, | |
| 10 | 11 | /// Cached number of active bits in a `tid`. |
| 11 | 12 | tid_width: if (single_threaded) u0 else std.math.Log2Int(u32) = 0, |
| 12 | 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 | 15 | /// Cached shift amount to put a `tid` in the top bits of a 32-bit value. |
| 15 | 16 | tid_shift_32: if (single_threaded) u0 else std.math.Log2Int(u32) = if (single_threaded) 0 else 31, |
| 16 | 17 | |
| 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. | |
| 22 | maps: std.ArrayListUnmanaged(FieldMap) = .{}, | |
| 23 | ||
| 24 | /// An index into `tracked_insts` gives a reference to a single ZIR instruction which | |
| 25 | /// persists across incremental updates. | |
| 26 | tracked_insts: std.AutoArrayHashMapUnmanaged(TrackedInst, void) = .{}, | |
| 27 | ||
| 28 | 18 | /// Dependencies on the source code hash associated with a ZIR instruction. |
| 29 | 19 | /// * For a `declaration`, this is the entire declaration body. |
| 30 | 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 | 50 | /// garbage collection pass. |
| 61 | 51 | free_dep_entries: std.ArrayListUnmanaged(DepEntry.Index) = .{}, |
| 62 | 52 | |
| 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`. | |
| 72 | files: std.AutoArrayHashMapUnmanaged(Cache.BinDigest, OptionalDeclIndex) = .{}, | |
| 73 | ||
| 74 | 53 | /// Whether a multi-threaded intern pool is useful. |
| 75 | 54 | /// Currently `false` until the intern pool is actually accessed |
| 76 | 55 | /// from multiple threads to reduce the cost of this data structure. |
| ... | ... | @@ -79,10 +58,6 @@ const want_multi_threaded = false; |
| 79 | 58 | /// Whether a single-threaded intern pool impl is in use. |
| 80 | 59 | pub const single_threaded = builtin.single_threaded or !want_multi_threaded; |
| 81 | 60 | |
| 82 | pub const FileIndex = enum(u32) { | |
| 83 | _, | |
| 84 | }; | |
| 85 | ||
| 86 | 61 | pub const TrackedInst = extern struct { |
| 87 | 62 | file: FileIndex, |
| 88 | 63 | inst: Zir.Inst.Index, |
| ... | ... | @@ -92,12 +67,15 @@ pub const TrackedInst = extern struct { |
| 92 | 67 | } |
| 93 | 68 | pub const Index = enum(u32) { |
| 94 | 69 | _, |
| 95 | pub fn resolveFull(i: TrackedInst.Index, ip: *const InternPool) TrackedInst { | |
| 96 | return ip.tracked_insts.keys()[@intFromEnum(i)]; | |
| 70 | pub fn resolveFull(tracked_inst_index: TrackedInst.Index, ip: *const InternPool) TrackedInst { | |
| 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 | 75 | pub fn resolve(i: TrackedInst.Index, ip: *const InternPool) Zir.Inst.Index { |
| 99 | 76 | return i.resolveFull(ip).inst; |
| 100 | 77 | } |
| 78 | ||
| 101 | 79 | pub fn toOptional(i: TrackedInst.Index) Optional { |
| 102 | 80 | return @enumFromInt(@intFromEnum(i)); |
| 103 | 81 | } |
| ... | ... | @@ -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 | }; |
| 116 | 112 | |
| 117 | 113 | pub fn trackZir( |
| 118 | 114 | ip: *InternPool, |
| 119 | 115 | gpa: Allocator, |
| 120 | file: FileIndex, | |
| 121 | inst: Zir.Inst.Index, | |
| 116 | tid: Zcu.PerThread.Id, | |
| 117 | key: TrackedInst, | |
| 122 | 118 | ) Allocator.Error!TrackedInst.Index { |
| 123 | const key: TrackedInst = .{ | |
| 124 | .file = file, | |
| 125 | .inst = inst, | |
| 126 | }; | |
| 127 | const gop = try ip.tracked_insts.getOrPut(gpa, key); | |
| 128 | return @enumFromInt(gop.index); | |
| 119 | const full_hash = Hash.hash(0, std.mem.asBytes(&key)); | |
| 120 | const hash: u32 = @truncate(full_hash >> 32); | |
| 121 | const shard = &ip.shards[@intCast(full_hash & (ip.shards.len - 1))]; | |
| 122 | var map = shard.shared.tracked_inst_map.acquire(); | |
| 123 | const Map = @TypeOf(map); | |
| 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 | } |
| 130 | 211 | |
| 131 | 212 | /// Analysis Unit. Represents a single entity which undergoes semantic analysis. |
| ... | ... | @@ -337,9 +418,12 @@ const Local = struct { |
| 337 | 418 | arena: std.heap.ArenaAllocator.State, |
| 338 | 419 | |
| 339 | 420 | items: ListMutate, |
| 340 | extra: ListMutate, | |
| 421 | extra: MutexListMutate, | |
| 341 | 422 | limbs: ListMutate, |
| 342 | 423 | strings: ListMutate, |
| 424 | tracked_insts: MutexListMutate, | |
| 425 | files: ListMutate, | |
| 426 | maps: ListMutate, | |
| 343 | 427 | |
| 344 | 428 | decls: BucketListMutate, |
| 345 | 429 | namespaces: BucketListMutate, |
| ... | ... | @@ -350,6 +434,9 @@ const Local = struct { |
| 350 | 434 | extra: Extra, |
| 351 | 435 | limbs: Limbs, |
| 352 | 436 | strings: Strings, |
| 437 | tracked_insts: TrackedInsts, | |
| 438 | files: List(File), | |
| 439 | maps: Maps, | |
| 353 | 440 | |
| 354 | 441 | decls: Decls, |
| 355 | 442 | namespaces: Namespaces, |
| ... | ... | @@ -370,16 +457,18 @@ const Local = struct { |
| 370 | 457 | else => @compileError("unsupported host"), |
| 371 | 458 | }; |
| 372 | 459 | const Strings = List(struct { u8 }); |
| 460 | const TrackedInsts = List(struct { TrackedInst }); | |
| 461 | const Maps = List(struct { FieldMap }); | |
| 373 | 462 | |
| 374 | 463 | const decls_bucket_width = 8; |
| 375 | 464 | const decls_bucket_mask = (1 << decls_bucket_width) - 1; |
| 376 | 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 }); | |
| 378 | 467 | |
| 379 | 468 | const namespaces_bucket_width = 8; |
| 380 | 469 | const namespaces_bucket_mask = (1 << namespaces_bucket_width) - 1; |
| 381 | 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 }); | |
| 383 | 472 | |
| 384 | 473 | const ListMutate = struct { |
| 385 | 474 | len: u32, |
| ... | ... | @@ -389,6 +478,16 @@ const Local = struct { |
| 389 | 478 | }; |
| 390 | 479 | }; |
| 391 | 480 | |
| 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 | 491 | const BucketListMutate = struct { |
| 393 | 492 | last_bucket_len: u32, |
| 394 | 493 | buckets_list: ListMutate, |
| ... | ... | @@ -410,7 +509,7 @@ const Local = struct { |
| 410 | 509 | |
| 411 | 510 | const ListSelf = @This(); |
| 412 | 511 | const Mutable = struct { |
| 413 | gpa: std.mem.Allocator, | |
| 512 | gpa: Allocator, | |
| 414 | 513 | arena: *std.heap.ArenaAllocator.State, |
| 415 | 514 | mutate: *ListMutate, |
| 416 | 515 | list: *ListSelf, |
| ... | ... | @@ -435,14 +534,17 @@ const Local = struct { |
| 435 | 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 | 541 | const elem_info = @typeInfo(Elem).Struct; |
| 440 | 542 | const elem_fields = elem_info.fields; |
| 441 | 543 | var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined; |
| 442 | 544 | for (&new_fields, elem_fields) |*new_field, elem_field| new_field.* = .{ |
| 443 | 545 | .name = elem_field.name, |
| 444 | 546 | .type = @Type(.{ .Pointer = .{ |
| 445 | .size = .Slice, | |
| 547 | .size = opts.size, | |
| 446 | 548 | .is_const = opts.is_const, |
| 447 | 549 | .is_volatile = false, |
| 448 | 550 | .alignment = 0, |
| ... | ... | @@ -463,6 +565,23 @@ const Local = struct { |
| 463 | 565 | } }); |
| 464 | 566 | } |
| 465 | 567 | |
| 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 | 585 | pub fn append(mutable: Mutable, elem: Elem) Allocator.Error!void { |
| 467 | 586 | try mutable.ensureUnusedCapacity(1); |
| 468 | 587 | mutable.appendAssumeCapacity(elem); |
| ... | ... | @@ -476,14 +595,14 @@ const Local = struct { |
| 476 | 595 | |
| 477 | 596 | pub fn appendSliceAssumeCapacity( |
| 478 | 597 | mutable: Mutable, |
| 479 | slice: SliceElem(.{ .is_const = true }), | |
| 598 | slice: PtrElem(.{ .size = .Slice, .is_const = true }), | |
| 480 | 599 | ) void { |
| 481 | 600 | if (fields.len == 0) return; |
| 482 | 601 | const start = mutable.mutate.len; |
| 483 | 602 | const slice_len = @field(slice, @tagName(fields[0])).len; |
| 484 | 603 | assert(slice_len <= mutable.list.header().capacity - start); |
| 485 | 604 | mutable.mutate.len = @intCast(start + slice_len); |
| 486 | const mutable_view = mutable.view(); | |
| 605 | const mutable_view = mutable.view().slice(); | |
| 487 | 606 | inline for (fields) |field| { |
| 488 | 607 | const field_slice = @field(slice, @tagName(field)); |
| 489 | 608 | assert(field_slice.len == slice_len); |
| ... | ... | @@ -500,7 +619,7 @@ const Local = struct { |
| 500 | 619 | const start = mutable.mutate.len; |
| 501 | 620 | assert(len <= mutable.list.header().capacity - start); |
| 502 | 621 | mutable.mutate.len = @intCast(start + len); |
| 503 | const mutable_view = mutable.view(); | |
| 622 | const mutable_view = mutable.view().slice(); | |
| 504 | 623 | inline for (fields) |field| { |
| 505 | 624 | @memset(mutable_view.items(field)[start..][0..len], @field(elem, @tagName(field))); |
| 506 | 625 | } |
| ... | ... | @@ -515,7 +634,7 @@ const Local = struct { |
| 515 | 634 | const start = mutable.mutate.len; |
| 516 | 635 | assert(len <= mutable.list.header().capacity - start); |
| 517 | 636 | mutable.mutate.len = @intCast(start + len); |
| 518 | const mutable_view = mutable.view(); | |
| 637 | const mutable_view = mutable.view().slice(); | |
| 519 | 638 | var ptr_array: PtrArrayElem(len) = undefined; |
| 520 | 639 | inline for (fields) |field| { |
| 521 | 640 | @field(ptr_array, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| ... | ... | @@ -523,17 +642,17 @@ const Local = struct { |
| 523 | 642 | return ptr_array; |
| 524 | 643 | } |
| 525 | 644 | |
| 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 | 646 | try mutable.ensureUnusedCapacity(len); |
| 528 | 647 | return mutable.addManyAsSliceAssumeCapacity(len); |
| 529 | 648 | } |
| 530 | 649 | |
| 531 | pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) SliceElem(.{}) { | |
| 650 | pub fn addManyAsSliceAssumeCapacity(mutable: Mutable, len: usize) PtrElem(.{ .size = .Slice }) { | |
| 532 | 651 | const start = mutable.mutate.len; |
| 533 | 652 | assert(len <= mutable.list.header().capacity - start); |
| 534 | 653 | mutable.mutate.len = @intCast(start + len); |
| 535 | const mutable_view = mutable.view(); | |
| 536 | var slice: SliceElem(.{}) = undefined; | |
| 654 | const mutable_view = mutable.view().slice(); | |
| 655 | var slice: PtrElem(.{ .size = .Slice }) = undefined; | |
| 537 | 656 | inline for (fields) |field| { |
| 538 | 657 | @field(slice, @tagName(field)) = mutable_view.items(field)[start..][0..len]; |
| 539 | 658 | } |
| ... | ... | @@ -578,7 +697,7 @@ const Local = struct { |
| 578 | 697 | mutable.list.release(new_list); |
| 579 | 698 | } |
| 580 | 699 | |
| 581 | fn view(mutable: Mutable) View { | |
| 700 | pub fn view(mutable: Mutable) View { | |
| 582 | 701 | const capacity = mutable.list.header().capacity; |
| 583 | 702 | assert(capacity > 0); // optimizes `MultiArrayList.Slice.items` |
| 584 | 703 | return .{ |
| ... | ... | @@ -602,7 +721,7 @@ const Local = struct { |
| 602 | 721 | const View = std.MultiArrayList(Elem); |
| 603 | 722 | |
| 604 | 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 | 725 | return .{ .bytes = @atomicLoad([*]align(@alignOf(Elem)) u8, &list.bytes, .acquire) }; |
| 607 | 726 | } |
| 608 | 727 | fn release(list: *ListSelf, new_list: ListSelf) void { |
| ... | ... | @@ -616,7 +735,7 @@ const Local = struct { |
| 616 | 735 | return @ptrFromInt(@intFromPtr(list.bytes) - bytes_offset); |
| 617 | 736 | } |
| 618 | 737 | |
| 619 | fn view(list: ListSelf) View { | |
| 738 | pub fn view(list: ListSelf) View { | |
| 620 | 739 | const capacity = list.header().capacity; |
| 621 | 740 | assert(capacity > 0); // optimizes `MultiArrayList.Slice.items` |
| 622 | 741 | return .{ |
| ... | ... | @@ -628,7 +747,7 @@ const Local = struct { |
| 628 | 747 | }; |
| 629 | 748 | } |
| 630 | 749 | |
| 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 | 751 | return .{ |
| 633 | 752 | .gpa = gpa, |
| 634 | 753 | .arena = &local.mutate.arena, |
| ... | ... | @@ -637,11 +756,11 @@ const Local = struct { |
| 637 | 756 | }; |
| 638 | 757 | } |
| 639 | 758 | |
| 640 | pub fn getMutableExtra(local: *Local, gpa: std.mem.Allocator) Extra.Mutable { | |
| 759 | pub fn getMutableExtra(local: *Local, gpa: Allocator) Extra.Mutable { | |
| 641 | 760 | return .{ |
| 642 | 761 | .gpa = gpa, |
| 643 | 762 | .arena = &local.mutate.arena, |
| 644 | .mutate = &local.mutate.extra, | |
| 763 | .mutate = &local.mutate.extra.list, | |
| 645 | 764 | .list = &local.shared.extra, |
| 646 | 765 | }; |
| 647 | 766 | } |
| ... | ... | @@ -650,7 +769,7 @@ const Local = struct { |
| 650 | 769 | /// On 64-bit systems, this array is used for big integers and associated metadata. |
| 651 | 770 | /// Use the helper methods instead of accessing this directly in order to not |
| 652 | 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 | 773 | return switch (@sizeOf(Limb)) { |
| 655 | 774 | @sizeOf(u32) => local.getMutableExtra(gpa), |
| 656 | 775 | @sizeOf(u64) => .{ |
| ... | ... | @@ -668,7 +787,7 @@ const Local = struct { |
| 668 | 787 | /// is referencing the data here whether they want to store both index and length, |
| 669 | 788 | /// thus allowing null bytes, or store only index, and use null-termination. The |
| 670 | 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 | 791 | return .{ |
| 673 | 792 | .gpa = gpa, |
| 674 | 793 | .arena = &local.mutate.arena, |
| ... | ... | @@ -677,6 +796,49 @@ const Local = struct { |
| 677 | 796 | }; |
| 678 | 797 | } |
| 679 | 798 | |
| 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 | 842 | /// Rather than allocating Decl objects with an Allocator, we instead allocate |
| 681 | 843 | /// them with this BucketList. This provides four advantages: |
| 682 | 844 | /// * Stable memory so that one thread can access a Decl object while another |
| ... | ... | @@ -687,7 +849,7 @@ const Local = struct { |
| 687 | 849 | /// serialization trivial. |
| 688 | 850 | /// * It provides a unique integer to be used for anonymous symbol names, avoiding |
| 689 | 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 | 853 | return .{ |
| 692 | 854 | .gpa = gpa, |
| 693 | 855 | .arena = &local.mutate.arena, |
| ... | ... | @@ -697,7 +859,7 @@ const Local = struct { |
| 697 | 859 | } |
| 698 | 860 | |
| 699 | 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 | 863 | return .{ |
| 702 | 864 | .gpa = gpa, |
| 703 | 865 | .arena = &local.mutate.arena, |
| ... | ... | @@ -719,11 +881,13 @@ const Shard = struct { |
| 719 | 881 | shared: struct { |
| 720 | 882 | map: Map(Index), |
| 721 | 883 | string_map: Map(OptionalNullTerminatedString), |
| 884 | tracked_inst_map: Map(TrackedInst.Index.Optional), | |
| 722 | 885 | } align(std.atomic.cache_line), |
| 723 | 886 | mutate: struct { |
| 724 | 887 | // TODO: measure cost of sharing unrelated mutate state |
| 725 | 888 | map: Mutate align(std.atomic.cache_line), |
| 726 | 889 | string_map: Mutate align(std.atomic.cache_line), |
| 890 | tracked_inst_map: Mutate align(std.atomic.cache_line), | |
| 727 | 891 | }, |
| 728 | 892 | |
| 729 | 893 | const Mutate = struct { |
| ... | ... | @@ -812,8 +976,6 @@ const Hash = std.hash.Wyhash; |
| 812 | 976 | |
| 813 | 977 | const InternPool = @This(); |
| 814 | 978 | const Zcu = @import("Zcu.zig"); |
| 815 | /// Deprecated. | |
| 816 | const Module = Zcu; | |
| 817 | 979 | const Zir = std.zig.Zir; |
| 818 | 980 | |
| 819 | 981 | /// An index into `maps` which might be `none`. |
| ... | ... | @@ -831,9 +993,37 @@ pub const OptionalMapIndex = enum(u32) { |
| 831 | 993 | pub const MapIndex = enum(u32) { |
| 832 | 994 | _, |
| 833 | 995 | |
| 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 | 1006 | pub fn toOptional(i: MapIndex) OptionalMapIndex { |
| 835 | 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 | }; |
| 838 | 1028 | |
| 839 | 1029 | pub const RuntimeIndex = enum(u32) { |
| ... | ... | @@ -938,6 +1128,34 @@ pub const OptionalNamespaceIndex = enum(u32) { |
| 938 | 1128 | } |
| 939 | 1129 | }; |
| 940 | 1130 | |
| 1131 | pub 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 | ||
| 1153 | const File = struct { | |
| 1154 | bin_digest: Cache.BinDigest, | |
| 1155 | file: *Zcu.File, | |
| 1156 | root_decl: OptionalDeclIndex, | |
| 1157 | }; | |
| 1158 | ||
| 941 | 1159 | /// An index into `strings`. |
| 942 | 1160 | pub const String = enum(u32) { |
| 943 | 1161 | /// An empty string. |
| ... | ... | @@ -1240,7 +1458,7 @@ pub const Key = union(enum) { |
| 1240 | 1458 | |
| 1241 | 1459 | /// Look up field index based on field name. |
| 1242 | 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 | 1462 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 1245 | 1463 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 1246 | 1464 | return @intCast(field_index); |
| ... | ... | @@ -2665,7 +2883,7 @@ pub const LoadedStructType = struct { |
| 2665 | 2883 | if (i >= self.field_types.len) return null; |
| 2666 | 2884 | return i; |
| 2667 | 2885 | }; |
| 2668 | const map = &ip.maps.items[@intFromEnum(names_map)]; | |
| 2886 | const map = names_map.getConst(ip); | |
| 2669 | 2887 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.field_names.get(ip) }; |
| 2670 | 2888 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 2671 | 2889 | return @intCast(field_index); |
| ... | ... | @@ -2783,20 +3001,25 @@ pub const LoadedStructType = struct { |
| 2783 | 3001 | } |
| 2784 | 3002 | |
| 2785 | 3003 | pub fn setInitsWip(s: LoadedStructType, ip: *InternPool) bool { |
| 2786 | switch (s.layout) { | |
| 2787 | .@"packed" => { | |
| 2788 | const flag = &s.packedFlagsPtr(ip).field_inits_wip; | |
| 2789 | if (flag.*) return true; | |
| 2790 | flag.* = true; | |
| 2791 | return false; | |
| 2792 | }, | |
| 2793 | .auto, .@"extern" => { | |
| 2794 | const flag = &s.flagsPtr(ip).field_inits_wip; | |
| 2795 | if (flag.*) return true; | |
| 2796 | flag.* = true; | |
| 2797 | return false; | |
| 2798 | }, | |
| 2799 | } | |
| 3004 | const local = ip.getLocal(s.tid); | |
| 3005 | local.mutate.extra.mutex.lock(); | |
| 3006 | defer local.mutate.extra.mutex.unlock(); | |
| 3007 | return switch (s.layout) { | |
| 3008 | .@"packed" => @as(Tag.TypeStructPacked.Flags, @bitCast(@atomicRmw( | |
| 3009 | u32, | |
| 3010 | @as(*u32, @ptrCast(s.packedFlagsPtr(ip))), | |
| 3011 | .Or, | |
| 3012 | @bitCast(Tag.TypeStructPacked.Flags{ .field_inits_wip = true }), | |
| 3013 | .acq_rel, | |
| 3014 | ))).field_inits_wip, | |
| 3015 | .auto, .@"extern" => @as(Tag.TypeStruct.Flags, @bitCast(@atomicRmw( | |
| 3016 | u32, | |
| 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 | } |
| 2801 | 3024 | |
| 2802 | 3025 | pub fn clearInitsWip(s: LoadedStructType, ip: *InternPool) void { |
| ... | ... | @@ -2962,6 +3185,7 @@ pub const LoadedStructType = struct { |
| 2962 | 3185 | pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2963 | 3186 | const unwrapped_index = index.unwrap(ip); |
| 2964 | 3187 | const extra_list = unwrapped_index.getExtra(ip); |
| 3188 | const extra_items = extra_list.view().items(.@"0"); | |
| 2965 | 3189 | const item = unwrapped_index.getItem(ip); |
| 2966 | 3190 | switch (item.tag) { |
| 2967 | 3191 | .type_struct => { |
| ... | ... | @@ -2982,10 +3206,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2982 | 3206 | .names_map = .none, |
| 2983 | 3207 | .captures = CaptureValue.Slice.empty, |
| 2984 | 3208 | }; |
| 2985 | const extra = extraDataTrail(extra_list, Tag.TypeStruct, item.data); | |
| 2986 | const fields_len = extra.data.fields_len; | |
| 2987 | var extra_index = extra.end; | |
| 2988 | const captures_len = if (extra.data.flags.any_captures) c: { | |
| 3209 | const decl: DeclIndex = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "decl").?]); | |
| 3210 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); | |
| 3211 | const fields_len = extra_items[item.data + std.meta.fieldIndex(Tag.TypeStruct, "fields_len").?]; | |
| 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 | 3215 | const len = extra_list.view().items(.@"0")[extra_index]; |
| 2990 | 3216 | extra_index += 1; |
| 2991 | 3217 | break :c len; |
| ... | ... | @@ -2996,7 +3222,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 2996 | 3222 | .len = captures_len, |
| 2997 | 3223 | }; |
| 2998 | 3224 | extra_index += captures_len; |
| 2999 | if (extra.data.flags.is_reified) { | |
| 3225 | if (flags.is_reified) { | |
| 3000 | 3226 | extra_index += 2; // PackedU64 |
| 3001 | 3227 | } |
| 3002 | 3228 | const field_types: Index.Slice = .{ |
| ... | ... | @@ -3005,7 +3231,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3005 | 3231 | .len = fields_len, |
| 3006 | 3232 | }; |
| 3007 | 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 | 3235 | const names_map: OptionalMapIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); |
| 3010 | 3236 | extra_index += 1; |
| 3011 | 3237 | const names: NullTerminatedString.Slice = .{ |
| ... | ... | @@ -3016,7 +3242,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3016 | 3242 | extra_index += fields_len; |
| 3017 | 3243 | break :n .{ names_map, names }; |
| 3018 | 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 | 3246 | const inits: Index.Slice = .{ |
| 3021 | 3247 | .tid = unwrapped_index.tid, |
| 3022 | 3248 | .start = extra_index, |
| ... | ... | @@ -3025,12 +3251,12 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3025 | 3251 | extra_index += fields_len; |
| 3026 | 3252 | break :i inits; |
| 3027 | 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 | 3255 | const n: NamespaceIndex = @enumFromInt(extra_list.view().items(.@"0")[extra_index]); |
| 3030 | 3256 | extra_index += 1; |
| 3031 | 3257 | break :n n.toOptional(); |
| 3032 | 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 | 3260 | const a: Alignment.Slice = .{ |
| 3035 | 3261 | .tid = unwrapped_index.tid, |
| 3036 | 3262 | .start = extra_index, |
| ... | ... | @@ -3039,7 +3265,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3039 | 3265 | extra_index += std.math.divCeil(u32, fields_len, 4) catch unreachable; |
| 3040 | 3266 | break :a a; |
| 3041 | 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 | 3269 | const len = std.math.divCeil(u32, fields_len, 32) catch unreachable; |
| 3044 | 3270 | const c: LoadedStructType.ComptimeBits = .{ |
| 3045 | 3271 | .tid = unwrapped_index.tid, |
| ... | ... | @@ -3049,7 +3275,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3049 | 3275 | extra_index += len; |
| 3050 | 3276 | break :c c; |
| 3051 | 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 | 3279 | const ro: LoadedStructType.RuntimeOrder.Slice = .{ |
| 3054 | 3280 | .tid = unwrapped_index.tid, |
| 3055 | 3281 | .start = extra_index, |
| ... | ... | @@ -3070,10 +3296,10 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3070 | 3296 | return .{ |
| 3071 | 3297 | .tid = unwrapped_index.tid, |
| 3072 | 3298 | .extra_index = item.data, |
| 3073 | .decl = extra.data.decl.toOptional(), | |
| 3299 | .decl = decl.toOptional(), | |
| 3074 | 3300 | .namespace = namespace, |
| 3075 | .zir_index = extra.data.zir_index.toOptional(), | |
| 3076 | .layout = if (extra.data.flags.is_extern) .@"extern" else .auto, | |
| 3301 | .zir_index = zir_index.toOptional(), | |
| 3302 | .layout = if (flags.is_extern) .@"extern" else .auto, | |
| 3077 | 3303 | .field_names = names, |
| 3078 | 3304 | .field_types = field_types, |
| 3079 | 3305 | .field_inits = inits, |
| ... | ... | @@ -3086,11 +3312,15 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3086 | 3312 | }; |
| 3087 | 3313 | }, |
| 3088 | 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 | 3322 | const has_inits = item.tag == .type_struct_packed_inits; |
| 3091 | const fields_len = extra.data.fields_len; | |
| 3092 | var extra_index = extra.end; | |
| 3093 | const captures_len = if (extra.data.flags.any_captures) c: { | |
| 3323 | const captures_len = if (flags.any_captures) c: { | |
| 3094 | 3324 | const len = extra_list.view().items(.@"0")[extra_index]; |
| 3095 | 3325 | extra_index += 1; |
| 3096 | 3326 | break :c len; |
| ... | ... | @@ -3101,7 +3331,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3101 | 3331 | .len = captures_len, |
| 3102 | 3332 | }; |
| 3103 | 3333 | extra_index += captures_len; |
| 3104 | if (extra.data.flags.is_reified) { | |
| 3334 | if (flags.is_reified) { | |
| 3105 | 3335 | extra_index += 2; // PackedU64 |
| 3106 | 3336 | } |
| 3107 | 3337 | const field_types: Index.Slice = .{ |
| ... | ... | @@ -3128,9 +3358,9 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3128 | 3358 | return .{ |
| 3129 | 3359 | .tid = unwrapped_index.tid, |
| 3130 | 3360 | .extra_index = item.data, |
| 3131 | .decl = extra.data.decl.toOptional(), | |
| 3132 | .namespace = extra.data.namespace, | |
| 3133 | .zir_index = extra.data.zir_index.toOptional(), | |
| 3361 | .decl = decl.toOptional(), | |
| 3362 | .namespace = namespace, | |
| 3363 | .zir_index = zir_index.toOptional(), | |
| 3134 | 3364 | .layout = .@"packed", |
| 3135 | 3365 | .field_names = field_names, |
| 3136 | 3366 | .field_types = field_types, |
| ... | ... | @@ -3139,7 +3369,7 @@ pub fn loadStructType(ip: *const InternPool, index: Index) LoadedStructType { |
| 3139 | 3369 | .runtime_order = LoadedStructType.RuntimeOrder.Slice.empty, |
| 3140 | 3370 | .comptime_bits = LoadedStructType.ComptimeBits.empty, |
| 3141 | 3371 | .offsets = LoadedStructType.Offsets.empty, |
| 3142 | .names_map = extra.data.names_map.toOptional(), | |
| 3372 | .names_map = names_map.toOptional(), | |
| 3143 | 3373 | .captures = captures, |
| 3144 | 3374 | }; |
| 3145 | 3375 | }, |
| ... | ... | @@ -3183,7 +3413,7 @@ const LoadedEnumType = struct { |
| 3183 | 3413 | |
| 3184 | 3414 | /// Look up field index based on field name. |
| 3185 | 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 | 3417 | const adapter: NullTerminatedString.Adapter = .{ .strings = self.names.get(ip) }; |
| 3188 | 3418 | const field_index = map.getIndexAdapted(name, adapter) orelse return null; |
| 3189 | 3419 | return @intCast(field_index); |
| ... | ... | @@ -3203,7 +3433,7 @@ const LoadedEnumType = struct { |
| 3203 | 3433 | else => unreachable, |
| 3204 | 3434 | }; |
| 3205 | 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 | 3437 | const adapter: Index.Adapter = .{ .indexes = self.values.get(ip) }; |
| 3208 | 3438 | const field_index = map.getIndexAdapted(int_tag_val, adapter) orelse return null; |
| 3209 | 3439 | return @intCast(field_index); |
| ... | ... | @@ -4476,11 +4706,11 @@ pub const Tag = enum(u8) { |
| 4476 | 4706 | flags: Flags, |
| 4477 | 4707 | |
| 4478 | 4708 | pub const Flags = packed struct(u32) { |
| 4479 | any_captures: bool, | |
| 4709 | any_captures: bool = false, | |
| 4480 | 4710 | /// Dependency loop detection when resolving field inits. |
| 4481 | field_inits_wip: bool, | |
| 4482 | inits_resolved: bool, | |
| 4483 | is_reified: bool, | |
| 4711 | field_inits_wip: bool = false, | |
| 4712 | inits_resolved: bool = false, | |
| 4713 | is_reified: bool = false, | |
| 4484 | 4714 | _: u28 = 0, |
| 4485 | 4715 | }; |
| 4486 | 4716 | }; |
| ... | ... | @@ -4526,36 +4756,36 @@ pub const Tag = enum(u8) { |
| 4526 | 4756 | size: u32, |
| 4527 | 4757 | |
| 4528 | 4758 | pub const Flags = packed struct(u32) { |
| 4529 | any_captures: bool, | |
| 4530 | is_extern: bool, | |
| 4531 | known_non_opv: bool, | |
| 4532 | requires_comptime: RequiresComptime, | |
| 4533 | is_tuple: bool, | |
| 4534 | assumed_runtime_bits: bool, | |
| 4535 | assumed_pointer_aligned: bool, | |
| 4536 | has_namespace: bool, | |
| 4537 | any_comptime_fields: bool, | |
| 4538 | any_default_inits: bool, | |
| 4539 | any_aligned_fields: bool, | |
| 4759 | any_captures: bool = false, | |
| 4760 | is_extern: bool = false, | |
| 4761 | known_non_opv: bool = false, | |
| 4762 | requires_comptime: RequiresComptime = @enumFromInt(0), | |
| 4763 | is_tuple: bool = false, | |
| 4764 | assumed_runtime_bits: bool = false, | |
| 4765 | assumed_pointer_aligned: bool = false, | |
| 4766 | has_namespace: bool = false, | |
| 4767 | any_comptime_fields: bool = false, | |
| 4768 | any_default_inits: bool = false, | |
| 4769 | any_aligned_fields: bool = false, | |
| 4540 | 4770 | /// `.none` until layout_resolved |
| 4541 | alignment: Alignment, | |
| 4771 | alignment: Alignment = @enumFromInt(0), | |
| 4542 | 4772 | /// Dependency loop detection when resolving struct alignment. |
| 4543 | alignment_wip: bool, | |
| 4773 | alignment_wip: bool = false, | |
| 4544 | 4774 | /// Dependency loop detection when resolving field types. |
| 4545 | field_types_wip: bool, | |
| 4775 | field_types_wip: bool = false, | |
| 4546 | 4776 | /// Dependency loop detection when resolving struct layout. |
| 4547 | layout_wip: bool, | |
| 4777 | layout_wip: bool = false, | |
| 4548 | 4778 | /// Indicates whether `size`, `alignment`, runtime field order, and |
| 4549 | 4779 | /// field offets are populated. |
| 4550 | layout_resolved: bool, | |
| 4780 | layout_resolved: bool = false, | |
| 4551 | 4781 | /// Dependency loop detection when resolving field inits. |
| 4552 | field_inits_wip: bool, | |
| 4782 | field_inits_wip: bool = false, | |
| 4553 | 4783 | /// Indicates whether `field_inits` has been resolved. |
| 4554 | inits_resolved: bool, | |
| 4555 | // The types and all its fields have had their layout resolved. Even through pointer, | |
| 4784 | inits_resolved: bool = false, | |
| 4785 | // The types and all its fields have had their layout resolved. Even through pointer = false, | |
| 4556 | 4786 | // which `layout_resolved` does not ensure. |
| 4557 | fully_resolved: bool, | |
| 4558 | is_reified: bool, | |
| 4787 | fully_resolved: bool = false, | |
| 4788 | is_reified: bool = false, | |
| 4559 | 4789 | _: u6 = 0, |
| 4560 | 4790 | }; |
| 4561 | 4791 | }; |
| ... | ... | @@ -4599,12 +4829,12 @@ pub const FuncAnalysis = packed struct(u32) { |
| 4599 | 4829 | /// inline, which means no runtime version of the function will be generated. |
| 4600 | 4830 | inline_only, |
| 4601 | 4831 | in_progress, |
| 4602 | /// There will be a corresponding ErrorMsg in Module.failed_decls | |
| 4832 | /// There will be a corresponding ErrorMsg in Zcu.failed_decls | |
| 4603 | 4833 | sema_failure, |
| 4604 | 4834 | /// This function might be OK but it depends on another Decl which did not |
| 4605 | 4835 | /// successfully complete semantic analysis. |
| 4606 | 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 | 4838 | /// Indicates that semantic analysis succeeded, but code generation for |
| 4609 | 4839 | /// this function failed. |
| 4610 | 4840 | codegen_failure, |
| ... | ... | @@ -5201,6 +5431,9 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5201 | 5431 | .extra = Local.Extra.empty, |
| 5202 | 5432 | .limbs = Local.Limbs.empty, |
| 5203 | 5433 | .strings = Local.Strings.empty, |
| 5434 | .tracked_insts = Local.TrackedInsts.empty, | |
| 5435 | .files = Local.List(File).empty, | |
| 5436 | .maps = Local.Maps.empty, | |
| 5204 | 5437 | |
| 5205 | 5438 | .decls = Local.Decls.empty, |
| 5206 | 5439 | .namespaces = Local.Namespaces.empty, |
| ... | ... | @@ -5209,9 +5442,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5209 | 5442 | .arena = .{}, |
| 5210 | 5443 | |
| 5211 | 5444 | .items = Local.ListMutate.empty, |
| 5212 | .extra = Local.ListMutate.empty, | |
| 5445 | .extra = Local.MutexListMutate.empty, | |
| 5213 | 5446 | .limbs = Local.ListMutate.empty, |
| 5214 | 5447 | .strings = Local.ListMutate.empty, |
| 5448 | .tracked_insts = Local.MutexListMutate.empty, | |
| 5449 | .files = Local.ListMutate.empty, | |
| 5450 | .maps = Local.ListMutate.empty, | |
| 5215 | 5451 | |
| 5216 | 5452 | .decls = Local.BucketListMutate.empty, |
| 5217 | 5453 | .namespaces = Local.BucketListMutate.empty, |
| ... | ... | @@ -5226,10 +5462,12 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5226 | 5462 | .shared = .{ |
| 5227 | 5463 | .map = Shard.Map(Index).empty, |
| 5228 | 5464 | .string_map = Shard.Map(OptionalNullTerminatedString).empty, |
| 5465 | .tracked_inst_map = Shard.Map(TrackedInst.Index.Optional).empty, | |
| 5229 | 5466 | }, |
| 5230 | 5467 | .mutate = .{ |
| 5231 | 5468 | .map = Shard.Mutate.empty, |
| 5232 | 5469 | .string_map = Shard.Mutate.empty, |
| 5470 | .tracked_inst_map = Shard.Mutate.empty, | |
| 5233 | 5471 | }, |
| 5234 | 5472 | }); |
| 5235 | 5473 | |
| ... | ... | @@ -5267,11 +5505,6 @@ pub fn init(ip: *InternPool, gpa: Allocator, available_threads: usize) !void { |
| 5267 | 5505 | } |
| 5268 | 5506 | |
| 5269 | 5507 | pub 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 | 5508 | ip.src_hash_deps.deinit(gpa); |
| 5276 | 5509 | ip.decl_val_deps.deinit(gpa); |
| 5277 | 5510 | ip.func_ies_deps.deinit(gpa); |
| ... | ... | @@ -5283,8 +5516,6 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5283 | 5516 | ip.dep_entries.deinit(gpa); |
| 5284 | 5517 | ip.free_dep_entries.deinit(gpa); |
| 5285 | 5518 | |
| 5286 | ip.files.deinit(gpa); | |
| 5287 | ||
| 5288 | 5519 | gpa.free(ip.shards); |
| 5289 | 5520 | for (ip.locals) |*local| { |
| 5290 | 5521 | const buckets_len = local.mutate.namespaces.buckets_list.len; |
| ... | ... | @@ -5301,6 +5532,8 @@ pub fn deinit(ip: *InternPool, gpa: Allocator) void { |
| 5301 | 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 | 5537 | local.mutate.arena.promote(gpa).deinit(); |
| 5305 | 5538 | } |
| 5306 | 5539 | gpa.free(ip.locals); |
| ... | ... | @@ -5400,40 +5633,46 @@ pub fn indexToKey(ip: *const InternPool, index: Index) Key { |
| 5400 | 5633 | .type_struct => .{ .struct_type = ns: { |
| 5401 | 5634 | if (data == 0) break :ns .empty_struct; |
| 5402 | 5635 | const extra_list = unwrapped_index.getExtra(ip); |
| 5403 | const extra = extraDataTrail(extra_list, Tag.TypeStruct, data); | |
| 5404 | if (extra.data.flags.is_reified) { | |
| 5405 | assert(!extra.data.flags.any_captures); | |
| 5636 | const extra_items = extra_list.view().items(.@"0"); | |
| 5637 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[data + std.meta.fieldIndex(Tag.TypeStruct, "zir_index").?]); | |
| 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 | 5642 | break :ns .{ .reified = .{ |
| 5407 | .zir_index = extra.data.zir_index, | |
| 5408 | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), | |
| 5643 | .zir_index = zir_index, | |
| 5644 | .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(), | |
| 5409 | 5645 | } }; |
| 5410 | 5646 | } |
| 5411 | 5647 | break :ns .{ .declared = .{ |
| 5412 | .zir_index = extra.data.zir_index, | |
| 5413 | .captures = .{ .owned = if (extra.data.flags.any_captures) .{ | |
| 5648 | .zir_index = zir_index, | |
| 5649 | .captures = .{ .owned = if (flags.any_captures) .{ | |
| 5414 | 5650 | .tid = unwrapped_index.tid, |
| 5415 | .start = extra.end + 1, | |
| 5416 | .len = extra_list.view().items(.@"0")[extra.end], | |
| 5651 | .start = end_extra_index + 1, | |
| 5652 | .len = extra_list.view().items(.@"0")[end_extra_index], | |
| 5417 | 5653 | } else CaptureValue.Slice.empty }, |
| 5418 | 5654 | } }; |
| 5419 | 5655 | } }, |
| 5420 | 5656 | |
| 5421 | 5657 | .type_struct_packed, .type_struct_packed_inits => .{ .struct_type = ns: { |
| 5422 | 5658 | const extra_list = unwrapped_index.getExtra(ip); |
| 5423 | const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data); | |
| 5424 | if (extra.data.flags.is_reified) { | |
| 5425 | assert(!extra.data.flags.any_captures); | |
| 5659 | const extra_items = extra_list.view().items(.@"0"); | |
| 5660 | const zir_index: TrackedInst.Index = @enumFromInt(extra_items[item.data + std.meta.fieldIndex(Tag.TypeStructPacked, "zir_index").?]); | |
| 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 | 5665 | break :ns .{ .reified = .{ |
| 5427 | .zir_index = extra.data.zir_index, | |
| 5428 | .type_hash = extraData(extra_list, PackedU64, extra.end).get(), | |
| 5666 | .zir_index = zir_index, | |
| 5667 | .type_hash = extraData(extra_list, PackedU64, end_extra_index).get(), | |
| 5429 | 5668 | } }; |
| 5430 | 5669 | } |
| 5431 | 5670 | break :ns .{ .declared = .{ |
| 5432 | .zir_index = extra.data.zir_index, | |
| 5433 | .captures = .{ .owned = if (extra.data.flags.any_captures) .{ | |
| 5671 | .zir_index = zir_index, | |
| 5672 | .captures = .{ .owned = if (flags.any_captures) .{ | |
| 5434 | 5673 | .tid = unwrapped_index.tid, |
| 5435 | .start = extra.end + 1, | |
| 5436 | .len = extra_list.view().items(.@"0")[extra.end], | |
| 5674 | .start = end_extra_index + 1, | |
| 5675 | .len = extra_items[end_extra_index], | |
| 5437 | 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 | 6153 | } |
| 5915 | 6154 | |
| 5916 | 6155 | fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local.Extra, extra_index: u32) Key.Func { |
| 5917 | const P = Tag.FuncInstance; | |
| 5918 | const fi = extraDataTrail(extra, P, extra_index); | |
| 5919 | const func_decl = ip.funcDeclInfo(fi.data.generic_owner); | |
| 6156 | const extra_items = extra.view().items(.@"0"); | |
| 6157 | const analysis_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "analysis").?; | |
| 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 | 6164 | return .{ |
| 5921 | 6165 | .tid = tid, |
| 5922 | .ty = fi.data.ty, | |
| 5923 | .uncoerced_ty = fi.data.ty, | |
| 5924 | .analysis_extra_index = extra_index + std.meta.fieldIndex(P, "analysis").?, | |
| 6166 | .ty = ty, | |
| 6167 | .uncoerced_ty = ty, | |
| 6168 | .analysis_extra_index = analysis_extra_index, | |
| 5925 | 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, | |
| 5927 | .branch_quota_extra_index = extra_index + std.meta.fieldIndex(P, "branch_quota").?, | |
| 5928 | .owner_decl = fi.data.owner_decl, | |
| 6170 | .resolved_error_set_extra_index = if (analysis.inferred_error_set) end_extra_index else 0, | |
| 6171 | .branch_quota_extra_index = extra_index + std.meta.fieldIndex(Tag.FuncInstance, "branch_quota").?, | |
| 6172 | .owner_decl = owner_decl, | |
| 5929 | 6173 | .zir_body_inst = func_decl.zir_body_inst, |
| 5930 | 6174 | .lbrace_line = func_decl.lbrace_line, |
| 5931 | 6175 | .rbrace_line = func_decl.rbrace_line, |
| 5932 | 6176 | .lbrace_column = func_decl.lbrace_column, |
| 5933 | 6177 | .rbrace_column = func_decl.rbrace_column, |
| 5934 | .generic_owner = fi.data.generic_owner, | |
| 6178 | .generic_owner = generic_owner, | |
| 5935 | 6179 | .comptime_args = .{ |
| 5936 | 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 | 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 | 6450 | assert(error_set_type.names_map == .none); |
| 6207 | 6451 | assert(std.sort.isSorted(NullTerminatedString, error_set_type.names.get(ip), {}, NullTerminatedString.indexLessThan)); |
| 6208 | 6452 | const names = error_set_type.names.get(ip); |
| 6209 | const names_map = try ip.addMap(gpa, names.len); | |
| 6210 | addStringsToMap(ip, names_map, names); | |
| 6453 | const names_map = try ip.addMap(gpa, tid, names.len); | |
| 6454 | ip.addStringsToMap(names_map, names); | |
| 6211 | 6455 | const names_len = error_set_type.names.len; |
| 6212 | 6456 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names_len); |
| 6213 | 6457 | items.appendAssumeCapacity(.{ |
| ... | ... | @@ -7107,8 +7351,8 @@ pub fn getStructType( |
| 7107 | 7351 | const items = local.getMutableItems(gpa); |
| 7108 | 7352 | const extra = local.getMutableExtra(gpa); |
| 7109 | 7353 | |
| 7110 | const names_map = try ip.addMap(gpa, ini.fields_len); | |
| 7111 | errdefer _ = ip.maps.pop(); | |
| 7354 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); | |
| 7355 | errdefer local.mutate.maps.len -= 1; | |
| 7112 | 7356 | |
| 7113 | 7357 | const zir_index = switch (ini.key) { |
| 7114 | 7358 | inline else => |x| x.zir_index, |
| ... | ... | @@ -7655,17 +7899,18 @@ pub fn getErrorSetType( |
| 7655 | 7899 | const extra = local.getMutableExtra(gpa); |
| 7656 | 7900 | try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).Struct.fields.len + names.len); |
| 7657 | 7901 | |
| 7902 | const names_map = try ip.addMap(gpa, tid, names.len); | |
| 7903 | errdefer local.mutate.maps.len -= 1; | |
| 7904 | ||
| 7658 | 7905 | // The strategy here is to add the type unconditionally, then to ask if it |
| 7659 | 7906 | // already exists, and if so, revert the lengths of the mutated arrays. |
| 7660 | 7907 | // This is similar to what `getOrPutTrailingString` does. |
| 7661 | 7908 | const prev_extra_len = extra.mutate.len; |
| 7662 | 7909 | errdefer extra.mutate.len = prev_extra_len; |
| 7663 | 7910 | |
| 7664 | const predicted_names_map: MapIndex = @enumFromInt(ip.maps.items.len); | |
| 7665 | ||
| 7666 | 7911 | const error_set_extra_index = addExtraAssumeCapacity(extra, Tag.ErrorSet{ |
| 7667 | 7912 | .names_len = @intCast(names.len), |
| 7668 | .names_map = predicted_names_map, | |
| 7913 | .names_map = names_map, | |
| 7669 | 7914 | }); |
| 7670 | 7915 | extra.appendSliceAssumeCapacity(.{@ptrCast(names)}); |
| 7671 | 7916 | errdefer extra.mutate.len = prev_extra_len; |
| ... | ... | @@ -7685,11 +7930,7 @@ pub fn getErrorSetType( |
| 7685 | 7930 | }); |
| 7686 | 7931 | errdefer items.mutate.len -= 1; |
| 7687 | 7932 | |
| 7688 | const names_map = try ip.addMap(gpa, names.len); | |
| 7689 | assert(names_map == predicted_names_map); | |
| 7690 | errdefer _ = ip.maps.pop(); | |
| 7691 | ||
| 7692 | addStringsToMap(ip, names_map, names); | |
| 7933 | ip.addStringsToMap(names_map, names); | |
| 7693 | 7934 | |
| 7694 | 7935 | return gop.put(); |
| 7695 | 7936 | } |
| ... | ... | @@ -7955,6 +8196,7 @@ fn finishFuncInstance( |
| 7955 | 8196 | const fn_owner_decl = ip.declPtr(ip.funcDeclOwner(generic_owner)); |
| 7956 | 8197 | const decl_index = try ip.createDecl(gpa, tid, .{ |
| 7957 | 8198 | .name = undefined, |
| 8199 | .fqn = undefined, | |
| 7958 | 8200 | .src_namespace = fn_owner_decl.src_namespace, |
| 7959 | 8201 | .has_tv = true, |
| 7960 | 8202 | .owns_tv = true, |
| ... | ... | @@ -7980,6 +8222,8 @@ fn finishFuncInstance( |
| 7980 | 8222 | decl.name = try ip.getOrPutStringFmt(gpa, tid, "{}__anon_{d}", .{ |
| 7981 | 8223 | fn_owner_decl.name.fmt(ip), @intFromEnum(decl_index), |
| 7982 | 8224 | }, .no_embedded_nulls); |
| 8225 | decl.fqn = try ip.namespacePtr(fn_owner_decl.src_namespace) | |
| 8226 | .internFullyQualifiedName(ip, gpa, tid, decl.name); | |
| 7983 | 8227 | } |
| 7984 | 8228 | |
| 7985 | 8229 | pub const EnumTypeInit = struct { |
| ... | ... | @@ -8052,7 +8296,7 @@ pub const WipEnumType = struct { |
| 8052 | 8296 | return null; |
| 8053 | 8297 | } |
| 8054 | 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 | 8300 | const field_index = map.count(); |
| 8057 | 8301 | const indexes = extra_items[wip.values_start..][0..field_index]; |
| 8058 | 8302 | const adapter: Index.Adapter = .{ .indexes = @ptrCast(indexes) }; |
| ... | ... | @@ -8098,8 +8342,8 @@ pub fn getEnumType( |
| 8098 | 8342 | try items.ensureUnusedCapacity(1); |
| 8099 | 8343 | const extra = local.getMutableExtra(gpa); |
| 8100 | 8344 | |
| 8101 | const names_map = try ip.addMap(gpa, ini.fields_len); | |
| 8102 | errdefer _ = ip.maps.pop(); | |
| 8345 | const names_map = try ip.addMap(gpa, tid, ini.fields_len); | |
| 8346 | errdefer local.mutate.maps.len -= 1; | |
| 8103 | 8347 | |
| 8104 | 8348 | switch (ini.tag_mode) { |
| 8105 | 8349 | .auto => { |
| ... | ... | @@ -8152,11 +8396,11 @@ pub fn getEnumType( |
| 8152 | 8396 | }, |
| 8153 | 8397 | .explicit, .nonexhaustive => { |
| 8154 | 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 | 8400 | break :m values_map.toOptional(); |
| 8157 | 8401 | }; |
| 8158 | 8402 | errdefer if (ini.has_values) { |
| 8159 | _ = ip.maps.pop(); | |
| 8403 | local.mutate.maps.len -= 1; | |
| 8160 | 8404 | }; |
| 8161 | 8405 | |
| 8162 | 8406 | try extra.ensureUnusedCapacity(@typeInfo(EnumExplicit).Struct.fields.len + |
| ... | ... | @@ -8245,8 +8489,8 @@ pub fn getGeneratedTagEnumType( |
| 8245 | 8489 | try items.ensureUnusedCapacity(1); |
| 8246 | 8490 | const extra = local.getMutableExtra(gpa); |
| 8247 | 8491 | |
| 8248 | const names_map = try ip.addMap(gpa, ini.names.len); | |
| 8249 | errdefer _ = ip.maps.pop(); | |
| 8492 | const names_map = try ip.addMap(gpa, tid, ini.names.len); | |
| 8493 | errdefer local.mutate.maps.len -= 1; | |
| 8250 | 8494 | ip.addStringsToMap(names_map, ini.names); |
| 8251 | 8495 | |
| 8252 | 8496 | const fields_len: u32 = @intCast(ini.names.len); |
| ... | ... | @@ -8279,8 +8523,8 @@ pub fn getGeneratedTagEnumType( |
| 8279 | 8523 | ini.values.len); // field values |
| 8280 | 8524 | |
| 8281 | 8525 | const values_map: OptionalMapIndex = if (ini.values.len != 0) m: { |
| 8282 | const map = try ip.addMap(gpa, ini.values.len); | |
| 8283 | addIndexesToMap(ip, map, ini.values); | |
| 8526 | const map = try ip.addMap(gpa, tid, ini.values.len); | |
| 8527 | ip.addIndexesToMap(map, ini.values); | |
| 8284 | 8528 | break :m map.toOptional(); |
| 8285 | 8529 | } else .none; |
| 8286 | 8530 | // We don't clean up the values map on error! |
| ... | ... | @@ -8311,7 +8555,9 @@ pub fn getGeneratedTagEnumType( |
| 8311 | 8555 | errdefer extra.mutate.len = prev_extra_len; |
| 8312 | 8556 | errdefer switch (ini.tag_mode) { |
| 8313 | 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 | }; |
| 8316 | 8562 | |
| 8317 | 8563 | var gop = try ip.getOrPutKey(gpa, tid, .{ .enum_type = .{ |
| ... | ... | @@ -8415,7 +8661,7 @@ fn addStringsToMap( |
| 8415 | 8661 | map_index: MapIndex, |
| 8416 | 8662 | strings: []const NullTerminatedString, |
| 8417 | 8663 | ) void { |
| 8418 | const map = &ip.maps.items[@intFromEnum(map_index)]; | |
| 8664 | const map = map_index.get(ip); | |
| 8419 | 8665 | const adapter: NullTerminatedString.Adapter = .{ .strings = strings }; |
| 8420 | 8666 | for (strings) |string| { |
| 8421 | 8667 | const gop = map.getOrPutAssumeCapacityAdapted(string, adapter); |
| ... | ... | @@ -8428,7 +8674,7 @@ fn addIndexesToMap( |
| 8428 | 8674 | map_index: MapIndex, |
| 8429 | 8675 | indexes: []const Index, |
| 8430 | 8676 | ) void { |
| 8431 | const map = &ip.maps.items[@intFromEnum(map_index)]; | |
| 8677 | const map = map_index.get(ip); | |
| 8432 | 8678 | const adapter: Index.Adapter = .{ .indexes = indexes }; |
| 8433 | 8679 | for (indexes) |index| { |
| 8434 | 8680 | const gop = map.getOrPutAssumeCapacityAdapted(index, adapter); |
| ... | ... | @@ -8436,12 +8682,14 @@ fn addIndexesToMap( |
| 8436 | 8682 | } |
| 8437 | 8683 | } |
| 8438 | 8684 | |
| 8439 | fn addMap(ip: *InternPool, gpa: Allocator, cap: usize) Allocator.Error!MapIndex { | |
| 8440 | const ptr = try ip.maps.addOne(gpa); | |
| 8441 | errdefer _ = ip.maps.pop(); | |
| 8442 | ptr.* = .{}; | |
| 8443 | try ptr.ensureTotalCapacity(gpa, cap); | |
| 8444 | return @enumFromInt(ip.maps.items.len - 1); | |
| 8685 | fn addMap(ip: *InternPool, gpa: Allocator, tid: Zcu.PerThread.Id, cap: usize) Allocator.Error!MapIndex { | |
| 8686 | const maps = ip.getLocal(tid).getMutableMaps(gpa); | |
| 8687 | const unwrapped: MapIndex.Unwrapped = .{ .tid = tid, .index = maps.mutate.len }; | |
| 8688 | const ptr = try maps.addOne(); | |
| 8689 | errdefer maps.mutate.len = unwrapped.index; | |
| 8690 | ptr[0].* = .{}; | |
| 8691 | try ptr[0].ensureTotalCapacity(gpa, cap); | |
| 8692 | return unwrapped.wrap(ip); | |
| 8445 | 8693 | } |
| 8446 | 8694 | |
| 8447 | 8695 | /// This operation only happens under compile error conditions. |
| ... | ... | @@ -9167,10 +9415,13 @@ pub fn errorUnionPayload(ip: *const InternPool, ty: Index) Index { |
| 9167 | 9415 | /// The is only legal because the initializer is not part of the hash. |
| 9168 | 9416 | pub fn mutateVarInit(ip: *InternPool, index: Index, init_index: Index) void { |
| 9169 | 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 | 9422 | const item = unwrapped_index.getItem(ip); |
| 9172 | 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 | } |
| 9175 | 9426 | |
| 9176 | 9427 | pub fn dump(ip: *const InternPool) void { |
| ... | ... | @@ -9185,14 +9436,14 @@ fn dumpStatsFallible(ip: *const InternPool, arena: Allocator) anyerror!void { |
| 9185 | 9436 | var decls_len: usize = 0; |
| 9186 | 9437 | for (ip.locals) |*local| { |
| 9187 | 9438 | items_len += local.mutate.items.len; |
| 9188 | extra_len += local.mutate.extra.len; | |
| 9439 | extra_len += local.mutate.extra.list.len; | |
| 9189 | 9440 | limbs_len += local.mutate.limbs.len; |
| 9190 | 9441 | decls_len += local.mutate.decls.buckets_list.len; |
| 9191 | 9442 | } |
| 9192 | 9443 | const items_size = (1 + 4) * items_len; |
| 9193 | 9444 | const extra_size = 4 * extra_len; |
| 9194 | 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; | |
| 9196 | 9447 | |
| 9197 | 9448 | // TODO: map overhead size is not taken into account |
| 9198 | 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 | 9870 | try bw.flush(); |
| 9620 | 9871 | } |
| 9621 | 9872 | |
| 9622 | pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Module.Decl { | |
| 9873 | pub fn declPtr(ip: *InternPool, decl_index: DeclIndex) *Zcu.Decl { | |
| 9623 | 9874 | return @constCast(ip.declPtrConst(decl_index)); |
| 9624 | 9875 | } |
| 9625 | 9876 | |
| 9626 | pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Module.Decl { | |
| 9877 | pub fn declPtrConst(ip: *const InternPool, decl_index: DeclIndex) *const Zcu.Decl { | |
| 9627 | 9878 | const unwrapped_decl_index = decl_index.unwrap(ip); |
| 9628 | 9879 | const decls = ip.getLocalShared(unwrapped_decl_index.tid).decls.acquire(); |
| 9629 | 9880 | const decls_bucket = decls.view().items(.@"0")[unwrapped_decl_index.bucket_index]; |
| 9630 | 9881 | return &decls_bucket[unwrapped_decl_index.index]; |
| 9631 | 9882 | } |
| 9632 | 9883 | |
| 9633 | pub 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 | ||
| 9640 | 9884 | pub fn createDecl( |
| 9641 | 9885 | ip: *InternPool, |
| 9642 | 9886 | gpa: Allocator, |
| 9643 | 9887 | tid: Zcu.PerThread.Id, |
| 9644 | initialization: Module.Decl, | |
| 9888 | initialization: Zcu.Decl, | |
| 9645 | 9889 | ) Allocator.Error!DeclIndex { |
| 9646 | 9890 | const local = ip.getLocal(tid); |
| 9647 | 9891 | const free_list_next = local.mutate.decls.free_list; |
| ... | ... | @@ -9658,7 +9902,7 @@ pub fn createDecl( |
| 9658 | 9902 | var arena = decls.arena.promote(decls.gpa); |
| 9659 | 9903 | defer decls.arena.* = arena.state; |
| 9660 | 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 | 9908 | const unwrapped_decl_index: DeclIndex.Unwrapped = .{ |
| ... | ... | @@ -9681,11 +9925,18 @@ pub fn destroyDecl(ip: *InternPool, tid: Zcu.PerThread.Id, decl_index: DeclIndex |
| 9681 | 9925 | local.mutate.decls.free_list = @intFromEnum(decl_index); |
| 9682 | 9926 | } |
| 9683 | 9927 | |
| 9928 | pub 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 | ||
| 9684 | 9935 | pub fn createNamespace( |
| 9685 | 9936 | ip: *InternPool, |
| 9686 | 9937 | gpa: Allocator, |
| 9687 | 9938 | tid: Zcu.PerThread.Id, |
| 9688 | initialization: Module.Namespace, | |
| 9939 | initialization: Zcu.Namespace, | |
| 9689 | 9940 | ) Allocator.Error!NamespaceIndex { |
| 9690 | 9941 | const local = ip.getLocal(tid); |
| 9691 | 9942 | const free_list_next = local.mutate.namespaces.free_list; |
| ... | ... | @@ -9703,7 +9954,7 @@ pub fn createNamespace( |
| 9703 | 9954 | var arena = namespaces.arena.promote(namespaces.gpa); |
| 9704 | 9955 | defer namespaces.arena.* = arena.state; |
| 9705 | 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 | 9960 | const unwrapped_namespace_index: NamespaceIndex.Unwrapped = .{ |
| ... | ... | @@ -9735,6 +9986,27 @@ pub fn destroyNamespace( |
| 9735 | 9986 | local.mutate.namespaces.free_list = @intFromEnum(namespace_index); |
| 9736 | 9987 | } |
| 9737 | 9988 | |
| 9989 | pub 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 | ||
| 9995 | pub 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 | ||
| 9738 | 10010 | const EmbeddedNulls = enum { |
| 9739 | 10011 | no_embedded_nulls, |
| 9740 | 10012 | maybe_embedded_nulls, |
| ... | ... | @@ -9813,7 +10085,7 @@ pub fn getOrPutTrailingString( |
| 9813 | 10085 | } |
| 9814 | 10086 | const key: []const u8 = strings.view().items(.@"0")[start..]; |
| 9815 | 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 | 10089 | const has_embedded_null = std.mem.indexOfScalar(u8, key, 0) != null; |
| 9818 | 10090 | switch (embedded_nulls) { |
| 9819 | 10091 | .no_embedded_nulls => assert(!has_embedded_null), |
| ... | ... | @@ -9859,10 +10131,10 @@ pub fn getOrPutTrailingString( |
| 9859 | 10131 | defer shard.mutate.string_map.len += 1; |
| 9860 | 10132 | const map_header = map.header().*; |
| 9861 | 10133 | if (shard.mutate.string_map.len < map_header.capacity * 3 / 5) { |
| 10134 | strings.appendAssumeCapacity(.{0}); | |
| 9862 | 10135 | const entry = &map.entries[map_index]; |
| 9863 | 10136 | entry.hash = hash; |
| 9864 | 10137 | entry.release(@enumFromInt(@intFromEnum(value))); |
| 9865 | strings.appendAssumeCapacity(.{0}); | |
| 9866 | 10138 | return value; |
| 9867 | 10139 | } |
| 9868 | 10140 | const arena_state = &ip.getLocal(tid).mutate.arena; |
| ... | ... | @@ -9901,12 +10173,12 @@ pub fn getOrPutTrailingString( |
| 9901 | 10173 | map_index &= new_map_mask; |
| 9902 | 10174 | if (map.entries[map_index].value == .none) break; |
| 9903 | 10175 | } |
| 10176 | strings.appendAssumeCapacity(.{0}); | |
| 9904 | 10177 | map.entries[map_index] = .{ |
| 9905 | 10178 | .value = @enumFromInt(@intFromEnum(value)), |
| 9906 | 10179 | .hash = hash, |
| 9907 | 10180 | }; |
| 9908 | 10181 | shard.shared.string_map.release(new_map); |
| 9909 | strings.appendAssumeCapacity(.{0}); | |
| 9910 | 10182 | return value; |
| 9911 | 10183 | } |
| 9912 | 10184 | |
| ... | ... | @@ -10654,7 +10926,7 @@ pub fn addFieldName( |
| 10654 | 10926 | name: NullTerminatedString, |
| 10655 | 10927 | ) ?u32 { |
| 10656 | 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 | 10930 | const field_index = map.count(); |
| 10659 | 10931 | const strings = extra_items[names_start..][0..field_index]; |
| 10660 | 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 | 10944 | return a_info.flags.alignment == b_info.flags.alignment and |
| 10673 | 10945 | (a_info.child == b_info.child or a_info.flags.alignment != .none); |
| 10674 | 10946 | } |
| 10947 | ||
| 10948 | const 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 | ||
| 11092 | pub 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 | ||
| 11101 | pub 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 | 835 | } |
| 836 | 836 | |
| 837 | 837 | fn trackZir(block: *Block, inst: Zir.Inst.Index) Allocator.Error!InternPool.TrackedInst.Index { |
| 838 | const sema = block.sema; | |
| 839 | const gpa = sema.gpa; | |
| 840 | const zcu = sema.pt.zcu; | |
| 841 | const ip = &zcu.intern_pool; | |
| 842 | const file_index = block.getFileScopeIndex(zcu); | |
| 843 | return ip.trackZir(gpa, file_index, inst); | |
| 838 | const pt = block.sema.pt; | |
| 839 | return pt.zcu.intern_pool.trackZir(pt.zcu.gpa, pt.tid, .{ | |
| 840 | .file = block.getFileScopeIndex(pt.zcu), | |
| 841 | .inst = inst, | |
| 842 | }); | |
| 844 | 843 | } |
| 845 | 844 | }; |
| 846 | 845 | |
| ... | ... | @@ -2878,7 +2877,7 @@ fn createAnonymousDeclTypeNamed( |
| 2878 | 2877 | switch (name_strategy) { |
| 2879 | 2878 | .anon => {}, // handled after switch |
| 2880 | 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 | 2881 | return new_decl_index; |
| 2883 | 2882 | }, |
| 2884 | 2883 | .func => func_strat: { |
| ... | ... | @@ -2923,7 +2922,7 @@ fn createAnonymousDeclTypeNamed( |
| 2923 | 2922 | |
| 2924 | 2923 | try writer.writeByte(')'); |
| 2925 | 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 | 2926 | return new_decl_index; |
| 2928 | 2927 | }, |
| 2929 | 2928 | .dbg_var => { |
| ... | ... | @@ -2937,7 +2936,7 @@ fn createAnonymousDeclTypeNamed( |
| 2937 | 2936 | const name = try ip.getOrPutStringFmt(gpa, pt.tid, "{}.{s}", .{ |
| 2938 | 2937 | block.type_name_ctx.fmt(ip), zir_data[i].str_op.getStr(sema.code), |
| 2939 | 2938 | }, .no_embedded_nulls); |
| 2940 | try zcu.initNewAnonDecl(new_decl_index, val, name); | |
| 2939 | try pt.initNewAnonDecl(new_decl_index, val, name, .none); | |
| 2941 | 2940 | return new_decl_index; |
| 2942 | 2941 | }, |
| 2943 | 2942 | else => {}, |
| ... | ... | @@ -2958,7 +2957,7 @@ fn createAnonymousDeclTypeNamed( |
| 2958 | 2957 | const name = ip.getOrPutStringFmt(gpa, pt.tid, "{}__{s}_{d}", .{ |
| 2959 | 2958 | block.type_name_ctx.fmt(ip), anon_prefix, @intFromEnum(new_decl_index), |
| 2960 | 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 | 2961 | return new_decl_index; |
| 2963 | 2962 | } |
| 2964 | 2963 | |
| ... | ... | @@ -3474,7 +3473,7 @@ fn zirErrorSetDecl( |
| 3474 | 3473 | const name_index: Zir.NullTerminatedString = @enumFromInt(sema.code.extra[extra_index]); |
| 3475 | 3474 | const name = sema.code.nullTerminatedString(name_index); |
| 3476 | 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 | 3477 | const result = names.getOrPutAssumeCapacity(name_ip); |
| 3479 | 3478 | assert(!result.found_existing); // verified in AstGen |
| 3480 | 3479 | } |
| ... | ... | @@ -5527,13 +5526,12 @@ fn failWithBadStructFieldAccess( |
| 5527 | 5526 | const zcu = pt.zcu; |
| 5528 | 5527 | const ip = &zcu.intern_pool; |
| 5529 | 5528 | const decl = zcu.declPtr(struct_type.decl.unwrap().?); |
| 5530 | const fqn = try decl.fullyQualifiedName(pt); | |
| 5531 | 5529 | |
| 5532 | 5530 | const msg = msg: { |
| 5533 | 5531 | const msg = try sema.errMsg( |
| 5534 | 5532 | field_src, |
| 5535 | 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 | 5536 | errdefer msg.destroy(sema.gpa); |
| 5539 | 5537 | try sema.errNote(struct_ty.srcLoc(zcu), msg, "struct declared here", .{}); |
| ... | ... | @@ -5554,15 +5552,13 @@ fn failWithBadUnionFieldAccess( |
| 5554 | 5552 | const zcu = pt.zcu; |
| 5555 | 5553 | const ip = &zcu.intern_pool; |
| 5556 | 5554 | const gpa = sema.gpa; |
| 5557 | ||
| 5558 | 5555 | const decl = zcu.declPtr(union_obj.decl); |
| 5559 | const fqn = try decl.fullyQualifiedName(pt); | |
| 5560 | 5556 | |
| 5561 | 5557 | const msg = msg: { |
| 5562 | 5558 | const msg = try sema.errMsg( |
| 5563 | 5559 | field_src, |
| 5564 | 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 | 5563 | errdefer msg.destroy(gpa); |
| 5568 | 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 | 6055 | else => |e| return e, |
| 6060 | 6056 | }; |
| 6061 | 6057 | |
| 6062 | const result = zcu.importPkg(c_import_mod) catch |err| | |
| 6058 | const result = pt.importPkg(c_import_mod) catch |err| | |
| 6063 | 6059 | return sema.fail(&child_block, src, "C import failed: {s}", .{@errorName(err)}); |
| 6064 | 6060 | |
| 6065 | 6061 | const path_digest = zcu.filePathDigest(result.file_index); |
| ... | ... | @@ -6721,13 +6717,7 @@ fn addDbgVar( |
| 6721 | 6717 | if (block.need_debug_scope) |ptr| ptr.* = true; |
| 6722 | 6718 | |
| 6723 | 6719 | // Add the name to the AIR. |
| 6724 | const name_extra_index: u32 = @intCast(sema.air_extra.items.len); | |
| 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; | |
| 6720 | const name_extra_index = try sema.appendAirString(name); | |
| 6731 | 6721 | |
| 6732 | 6722 | _ = try block.addInst(.{ |
| 6733 | 6723 | .tag = air_tag, |
| ... | ... | @@ -6738,6 +6728,16 @@ fn addDbgVar( |
| 6738 | 6728 | }); |
| 6739 | 6729 | } |
| 6740 | 6730 | |
| 6731 | pub 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 | ||
| 6741 | 6741 | fn zirDeclRef(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { |
| 6742 | 6742 | const pt = sema.pt; |
| 6743 | 6743 | const mod = pt.zcu; |
| ... | ... | @@ -8357,13 +8357,6 @@ fn instantiateGenericCall( |
| 8357 | 8357 | } |
| 8358 | 8358 | } else { |
| 8359 | 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 | 8360 | const param_name: Zir.NullTerminatedString = switch (param_tag) { |
| 8368 | 8361 | .param_anytype => fn_zir.instructions.items(.data)[@intFromEnum(param_inst)].str_tok.start, |
| 8369 | 8362 | .param => name: { |
| ... | ... | @@ -8373,6 +8366,16 @@ fn instantiateGenericCall( |
| 8373 | 8366 | }, |
| 8374 | 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 | 8379 | try child_block.params.append(sema.arena, .{ |
| 8377 | 8380 | .ty = arg_ty.toIntern(), // This is the type after coercion |
| 8378 | 8381 | .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 | 8705 | inst_data.get(sema.code), |
| 8703 | 8706 | .no_embedded_nulls, |
| 8704 | 8707 | ); |
| 8705 | _ = try pt.zcu.getErrorValue(name); | |
| 8708 | _ = try pt.getErrorValue(name); | |
| 8706 | 8709 | // Create an error set type with only this error value, and return the value. |
| 8707 | 8710 | const error_set_type = try pt.singleErrorSetType(name); |
| 8708 | 8711 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| ... | ... | @@ -8732,7 +8735,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8732 | 8735 | const err_name = ip.indexToKey(val.toIntern()).err.name; |
| 8733 | 8736 | return Air.internedToRef((try pt.intValue( |
| 8734 | 8737 | err_int_ty, |
| 8735 | try mod.getErrorValue(err_name), | |
| 8738 | try pt.getErrorValue(err_name), | |
| 8736 | 8739 | )).toIntern()); |
| 8737 | 8740 | } |
| 8738 | 8741 | |
| ... | ... | @@ -8743,10 +8746,7 @@ fn zirIntFromError(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8743 | 8746 | const names = ip.indexToKey(err_set_ty_index).error_set_type.names; |
| 8744 | 8747 | switch (names.len) { |
| 8745 | 8748 | 0 => return Air.internedToRef((try pt.intValue(err_int_ty, 0)).toIntern()), |
| 8746 | 1 => { | |
| 8747 | const int: Module.ErrorInt = @intCast(mod.global_error_set.getIndex(names.get(ip)[0]).?); | |
| 8748 | return pt.intRef(err_int_ty, int); | |
| 8749 | }, | |
| 8749 | 1 => return pt.intRef(err_int_ty, ip.getErrorValueIfExists(names.get(ip)[0]).?), | |
| 8750 | 8750 | else => {}, |
| 8751 | 8751 | } |
| 8752 | 8752 | }, |
| ... | ... | @@ -8762,6 +8762,7 @@ fn zirErrorFromInt(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD |
| 8762 | 8762 | |
| 8763 | 8763 | const pt = sema.pt; |
| 8764 | 8764 | const mod = pt.zcu; |
| 8765 | const ip = &mod.intern_pool; | |
| 8765 | 8766 | const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; |
| 8766 | 8767 | const src = block.nodeOffset(extra.node); |
| 8767 | 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 | 8772 | |
| 8772 | 8773 | if (try sema.resolveDefinedValue(block, operand_src, operand)) |value| { |
| 8773 | 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 | 8781 | return sema.fail(block, operand_src, "integer value '{d}' represents no error", .{int}); |
| 8776 | 8782 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 8777 | 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 | 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 | 13949 | const operand_src = block.tokenOffset(inst_data.src_tok); |
| 13944 | 13950 | const operand = inst_data.get(sema.code); |
| 13945 | 13951 | |
| 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 | 13953 | error.ImportOutsideModulePath => { |
| 13948 | 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 | 14008 | inst_data.get(sema.code), |
| 14003 | 14009 | .no_embedded_nulls, |
| 14004 | 14010 | ); |
| 14005 | _ = try mod.getErrorValue(name); | |
| 14011 | _ = try pt.getErrorValue(name); | |
| 14006 | 14012 | const error_set_type = try pt.singleErrorSetType(name); |
| 14007 | 14013 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 14008 | 14014 | .ty = error_set_type.toIntern(), |
| ... | ... | @@ -19561,7 +19567,7 @@ fn zirRetErrValue( |
| 19561 | 19567 | inst_data.get(sema.code), |
| 19562 | 19568 | .no_embedded_nulls, |
| 19563 | 19569 | ); |
| 19564 | _ = try mod.getErrorValue(err_name); | |
| 19570 | _ = try pt.getErrorValue(err_name); | |
| 19565 | 19571 | // Return the error code from the function. |
| 19566 | 19572 | const error_set_type = try pt.singleErrorSetType(err_name); |
| 19567 | 19573 | const result_inst = Air.internedToRef((try pt.intern(.{ .err = .{ |
| ... | ... | @@ -21604,7 +21610,7 @@ fn zirReify( |
| 21604 | 21610 | const name = try sema.sliceToIpString(block, src, name_val, .{ |
| 21605 | 21611 | .needed_comptime_reason = "error set contents must be comptime-known", |
| 21606 | 21612 | }); |
| 21607 | _ = try mod.getErrorValue(name); | |
| 21613 | _ = try pt.getErrorValue(name); | |
| 21608 | 21614 | const gop = names.getOrPutAssumeCapacity(name); |
| 21609 | 21615 | if (gop.found_existing) { |
| 21610 | 21616 | return sema.fail(block, src, "duplicate error '{}'", .{ |
| ... | ... | @@ -26500,7 +26506,7 @@ fn zirBuiltinExtern( |
| 26500 | 26506 | const new_decl_index = try pt.allocateNewDecl(sema.owner_decl.src_namespace); |
| 26501 | 26507 | errdefer pt.destroyDecl(new_decl_index); |
| 26502 | 26508 | const new_decl = mod.declPtr(new_decl_index); |
| 26503 | try mod.initNewAnonDecl( | |
| 26509 | try pt.initNewAnonDecl( | |
| 26504 | 26510 | new_decl_index, |
| 26505 | 26511 | Value.fromInterned( |
| 26506 | 26512 | if (Type.fromInterned(ptr_info.child).zigTypeTag(mod) == .Fn) |
| ... | ... | @@ -26522,6 +26528,7 @@ fn zirBuiltinExtern( |
| 26522 | 26528 | } }), |
| 26523 | 26529 | ), |
| 26524 | 26530 | options.name, |
| 26531 | .none, | |
| 26525 | 26532 | ); |
| 26526 | 26533 | new_decl.owns_tv = true; |
| 26527 | 26534 | // Note that this will queue the anon decl for codegen, so that the backend can |
| ... | ... | @@ -27481,7 +27488,7 @@ fn fieldVal( |
| 27481 | 27488 | }, |
| 27482 | 27489 | .simple_type => |t| { |
| 27483 | 27490 | assert(t == .anyerror); |
| 27484 | _ = try mod.getErrorValue(field_name); | |
| 27491 | _ = try pt.getErrorValue(field_name); | |
| 27485 | 27492 | }, |
| 27486 | 27493 | else => unreachable, |
| 27487 | 27494 | } |
| ... | ... | @@ -27721,7 +27728,7 @@ fn fieldPtr( |
| 27721 | 27728 | }, |
| 27722 | 27729 | .simple_type => |t| { |
| 27723 | 27730 | assert(t == .anyerror); |
| 27724 | _ = try mod.getErrorValue(field_name); | |
| 27731 | _ = try pt.getErrorValue(field_name); | |
| 27725 | 27732 | }, |
| 27726 | 27733 | else => unreachable, |
| 27727 | 27734 | } |
| ... | ... | @@ -36735,24 +36742,23 @@ fn generateUnionTagTypeNumbered( |
| 36735 | 36742 | |
| 36736 | 36743 | const new_decl_index = try pt.allocateNewDecl(block.namespace); |
| 36737 | 36744 | errdefer pt.destroyDecl(new_decl_index); |
| 36738 | const fqn = try union_owner_decl.fullyQualifiedName(pt); | |
| 36739 | 36745 | const name = try ip.getOrPutStringFmt( |
| 36740 | 36746 | gpa, |
| 36741 | 36747 | pt.tid, |
| 36742 | 36748 | "@typeInfo({}).Union.tag_type.?", |
| 36743 | .{fqn.fmt(ip)}, | |
| 36749 | .{union_owner_decl.fqn.fmt(ip)}, | |
| 36744 | 36750 | .no_embedded_nulls, |
| 36745 | 36751 | ); |
| 36746 | try mod.initNewAnonDecl( | |
| 36752 | try pt.initNewAnonDecl( | |
| 36747 | 36753 | new_decl_index, |
| 36748 | 36754 | Value.@"unreachable", |
| 36749 | 36755 | name, |
| 36756 | name.toOptional(), | |
| 36750 | 36757 | ); |
| 36751 | 36758 | errdefer pt.abortAnonDecl(new_decl_index); |
| 36752 | 36759 | |
| 36753 | 36760 | const new_decl = mod.declPtr(new_decl_index); |
| 36754 | 36761 | new_decl.owns_tv = true; |
| 36755 | new_decl.name_fully_qualified = true; | |
| 36756 | 36762 | |
| 36757 | 36763 | const enum_ty = try ip.getGeneratedTagEnumType(gpa, pt.tid, .{ |
| 36758 | 36764 | .decl = new_decl_index, |
| ... | ... | @@ -36784,22 +36790,21 @@ fn generateUnionTagTypeSimple( |
| 36784 | 36790 | const gpa = sema.gpa; |
| 36785 | 36791 | |
| 36786 | 36792 | const new_decl_index = new_decl_index: { |
| 36787 | const fqn = try union_owner_decl.fullyQualifiedName(pt); | |
| 36788 | 36793 | const new_decl_index = try pt.allocateNewDecl(block.namespace); |
| 36789 | 36794 | errdefer pt.destroyDecl(new_decl_index); |
| 36790 | 36795 | const name = try ip.getOrPutStringFmt( |
| 36791 | 36796 | gpa, |
| 36792 | 36797 | pt.tid, |
| 36793 | 36798 | "@typeInfo({}).Union.tag_type.?", |
| 36794 | .{fqn.fmt(ip)}, | |
| 36799 | .{union_owner_decl.fqn.fmt(ip)}, | |
| 36795 | 36800 | .no_embedded_nulls, |
| 36796 | 36801 | ); |
| 36797 | try mod.initNewAnonDecl( | |
| 36802 | try pt.initNewAnonDecl( | |
| 36798 | 36803 | new_decl_index, |
| 36799 | 36804 | Value.@"unreachable", |
| 36800 | 36805 | name, |
| 36806 | name.toOptional(), | |
| 36801 | 36807 | ); |
| 36802 | mod.declPtr(new_decl_index).name_fully_qualified = true; | |
| 36803 | 36808 | break :new_decl_index new_decl_index; |
| 36804 | 36809 | }; |
| 36805 | 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 | 268 | return; |
| 269 | 269 | }, |
| 270 | 270 | .inferred_error_set_type => |func_index| { |
| 271 | try writer.writeAll("@typeInfo(@typeInfo(@TypeOf("); | |
| 272 | 271 | const owner_decl = mod.funcOwnerDeclPtr(func_index); |
| 273 | try owner_decl.renderFullyQualifiedName(mod, writer); | |
| 274 | try writer.writeAll(")).Fn.return_type.?).ErrorUnion.error_set"); | |
| 272 | try writer.print("@typeInfo(@typeInfo(@TypeOf({})).Fn.return_type.?).ErrorUnion.error_set", .{ | |
| 273 | owner_decl.fqn.fmt(ip), | |
| 274 | }); | |
| 275 | 275 | }, |
| 276 | 276 | .error_set_type => |error_set_type| { |
| 277 | 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 | 334 | const struct_type = ip.loadStructType(ty.toIntern()); |
| 335 | 335 | if (struct_type.decl.unwrap()) |decl_index| { |
| 336 | 336 | const decl = mod.declPtr(decl_index); |
| 337 | try decl.renderFullyQualifiedName(mod, writer); | |
| 337 | try writer.print("{}", .{decl.fqn.fmt(ip)}); | |
| 338 | 338 | } else if (ip.loadStructType(ty.toIntern()).namespace.unwrap()) |namespace_index| { |
| 339 | 339 | const namespace = mod.namespacePtr(namespace_index); |
| 340 | try namespace.renderFullyQualifiedName(mod, .empty, writer); | |
| 340 | try namespace.renderFullyQualifiedName(ip, .empty, writer); | |
| 341 | 341 | } else { |
| 342 | 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 | 367 | |
| 368 | 368 | .union_type => { |
| 369 | 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 | 372 | .opaque_type => { |
| 373 | 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 | 376 | .enum_type => { |
| 377 | 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 | 380 | .func_type => |fn_info| { |
| 381 | 381 | if (fn_info.is_noinline) { |
| ... | ... | @@ -3451,7 +3451,7 @@ pub fn typeDeclInst(ty: Type, zcu: *const Zcu) ?InternPool.TrackedInst.Index { |
| 3451 | 3451 | }; |
| 3452 | 3452 | } |
| 3453 | 3453 | |
| 3454 | pub fn typeDeclSrcLine(ty: Type, zcu: *const Zcu) ?u32 { | |
| 3454 | pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 { | |
| 3455 | 3455 | const ip = &zcu.intern_pool; |
| 3456 | 3456 | const tracked = switch (ip.indexToKey(ty.toIntern())) { |
| 3457 | 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 | 417 | var bigint_buffer: BigIntSpace = undefined; |
| 418 | 418 | const bigint = BigIntMutable.init( |
| 419 | 419 | &bigint_buffer.limbs, |
| 420 | mod.global_error_set.getIndex(name).?, | |
| 420 | ip.getErrorValueIfExists(name).?, | |
| 421 | 421 | ).toConst(); |
| 422 | 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 | 427 | if (val.unionTag(mod)) |union_tag| { |
| 428 | 428 | const union_obj = mod.typeToUnion(ty).?; |
| 429 | 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 | 431 | const field_val = try val.fieldValue(pt, field_index); |
| 432 | 432 | const byte_count: usize = @intCast(field_type.abiSize(pt)); |
| 433 | 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 | 1455 | }; |
| 1456 | 1456 | } |
| 1457 | 1457 | |
| 1458 | pub fn getErrorInt(val: Value, mod: *const Module) Module.ErrorInt { | |
| 1459 | return if (getErrorName(val, mod).unwrap()) |err_name| | |
| 1460 | @intCast(mod.global_error_set.getIndex(err_name).?) | |
| 1458 | pub fn getErrorInt(val: Value, zcu: *Zcu) Module.ErrorInt { | |
| 1459 | return if (getErrorName(val, zcu).unwrap()) |err_name| | |
| 1460 | zcu.intern_pool.getErrorValueIfExists(err_name).? | |
| 1461 | 1461 | else |
| 1462 | 1462 | 0; |
| 1463 | 1463 | } |
src/Zcu.zig+61-312| ... | ... | @@ -102,7 +102,7 @@ multi_exports: std.AutoArrayHashMapUnmanaged(AnalUnit, extern struct { |
| 102 | 102 | /// `Compilation.update` of the process for a given `Compilation`. |
| 103 | 103 | /// |
| 104 | 104 | /// Indexes correspond 1:1 to `files`. |
| 105 | import_table: std.StringArrayHashMapUnmanaged(*File) = .{}, | |
| 105 | import_table: std.StringArrayHashMapUnmanaged(File.Index) = .{}, | |
| 106 | 106 | |
| 107 | 107 | /// The set of all the files which have been loaded with `@embedFile` in the Module. |
| 108 | 108 | /// 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 | 141 | /// are stored here. |
| 142 | 142 | cimport_errors: std.AutoArrayHashMapUnmanaged(AnalUnit, std.zig.ErrorBundle) = .{}, |
| 143 | 143 | |
| 144 | /// Key is the error name, index is the error tag value. Index 0 has a length-0 string. | |
| 145 | global_error_set: GlobalErrorSet = .{}, | |
| 146 | ||
| 147 | 144 | /// Maximum amount of distinct error values, set by --error-limit |
| 148 | 145 | error_limit: ErrorInt, |
| 149 | 146 | |
| ... | ... | @@ -326,7 +323,10 @@ pub const Reference = struct { |
| 326 | 323 | }; |
| 327 | 324 | |
| 328 | 325 | pub const Decl = struct { |
| 326 | /// Equal to `fqn` if already fully qualified. | |
| 329 | 327 | name: InternPool.NullTerminatedString, |
| 328 | /// Fully qualified name. | |
| 329 | fqn: InternPool.NullTerminatedString, | |
| 330 | 330 | /// The most recent Value of the Decl after a successful semantic analysis. |
| 331 | 331 | /// Populated when `has_tv`. |
| 332 | 332 | val: Value, |
| ... | ... | @@ -384,8 +384,6 @@ pub const Decl = struct { |
| 384 | 384 | is_pub: bool, |
| 385 | 385 | /// Whether the corresponding AST decl has a `export` keyword. |
| 386 | 386 | is_exported: bool, |
| 387 | /// If true `name` is already fully qualified. | |
| 388 | name_fully_qualified: bool = false, | |
| 389 | 387 | /// What kind of a declaration is this. |
| 390 | 388 | kind: Kind, |
| 391 | 389 | |
| ... | ... | @@ -408,25 +406,6 @@ pub const Decl = struct { |
| 408 | 406 | return extra.data.getBodies(@intCast(extra.end), zir); |
| 409 | 407 | } |
| 410 | 408 | |
| 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 | 409 | pub fn typeOf(decl: Decl, zcu: *const Zcu) Type { |
| 431 | 410 | assert(decl.has_tv); |
| 432 | 411 | return decl.val.typeOf(zcu); |
| ... | ... | @@ -646,23 +625,27 @@ pub const Namespace = struct { |
| 646 | 625 | return zcu.fileByIndex(ns.file_scope); |
| 647 | 626 | } |
| 648 | 627 | |
| 628 | pub fn fileScopeIp(ns: Namespace, ip: *InternPool) *File { | |
| 629 | return ip.filePtr(ns.file_scope); | |
| 630 | } | |
| 631 | ||
| 649 | 632 | // This renders e.g. "std.fs.Dir.OpenOptions" |
| 650 | 633 | pub fn renderFullyQualifiedName( |
| 651 | 634 | ns: Namespace, |
| 652 | zcu: *Zcu, | |
| 635 | ip: *InternPool, | |
| 653 | 636 | name: InternPool.NullTerminatedString, |
| 654 | 637 | writer: anytype, |
| 655 | 638 | ) @TypeOf(writer).Error!void { |
| 656 | 639 | if (ns.parent.unwrap()) |parent| { |
| 657 | try zcu.namespacePtr(parent).renderFullyQualifiedName( | |
| 658 | zcu, | |
| 659 | zcu.declPtr(ns.decl_index).name, | |
| 640 | try ip.namespacePtr(parent).renderFullyQualifiedName( | |
| 641 | ip, | |
| 642 | ip.declPtr(ns.decl_index).name, | |
| 660 | 643 | writer, |
| 661 | 644 | ); |
| 662 | 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 | } |
| 667 | 650 | |
| 668 | 651 | /// This renders e.g. "std/fs.zig:Dir.OpenOptions" |
| ... | ... | @@ -686,46 +669,45 @@ pub const Namespace = struct { |
| 686 | 669 | if (name != .empty) try writer.print("{c}{}", .{ sep, name.fmt(&zcu.intern_pool) }); |
| 687 | 670 | } |
| 688 | 671 | |
| 689 | pub fn fullyQualifiedName( | |
| 672 | pub fn internFullyQualifiedName( | |
| 690 | 673 | ns: Namespace, |
| 691 | pt: Zcu.PerThread, | |
| 674 | ip: *InternPool, | |
| 675 | gpa: Allocator, | |
| 676 | tid: Zcu.PerThread.Id, | |
| 692 | 677 | name: InternPool.NullTerminatedString, |
| 693 | 678 | ) !InternPool.NullTerminatedString { |
| 694 | const zcu = pt.zcu; | |
| 695 | const ip = &zcu.intern_pool; | |
| 696 | ||
| 697 | const gpa = zcu.gpa; | |
| 698 | const strings = ip.getLocal(pt.tid).getMutableStrings(gpa); | |
| 679 | const strings = ip.getLocal(tid).getMutableStrings(gpa); | |
| 699 | 680 | // Protects reads of interned strings from being reallocated during the call to |
| 700 | 681 | // renderFullyQualifiedName. |
| 701 | 682 | const slice = try strings.addManyAsSlice(count: { |
| 702 | 683 | var count: usize = name.length(ip) + 1; |
| 703 | 684 | var cur_ns = &ns; |
| 704 | 685 | while (true) { |
| 705 | const decl = zcu.declPtr(cur_ns.decl_index); | |
| 706 | cur_ns = zcu.namespacePtr(cur_ns.parent.unwrap() orelse { | |
| 707 | count += ns.fileScope(zcu).fullyQualifiedNameLen(); | |
| 686 | const decl = ip.declPtr(cur_ns.decl_index); | |
| 687 | cur_ns = ip.namespacePtr(cur_ns.parent.unwrap() orelse { | |
| 688 | count += ns.fileScopeIp(ip).fullyQualifiedNameLen(); | |
| 708 | 689 | break :count count; |
| 709 | 690 | }); |
| 710 | 691 | count += decl.name.length(ip) + 1; |
| 711 | 692 | } |
| 712 | 693 | }); |
| 713 | 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 | 696 | assert(fbs.pos == slice[0].len); |
| 716 | 697 | |
| 717 | 698 | // Sanitize the name for nvptx which is more restrictive. |
| 718 | 699 | // TODO This should be handled by the backend, not the frontend. Have a |
| 719 | 700 | // look at how the C backend does it for inspiration. |
| 720 | const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch; | |
| 721 | if (cpu_arch.isNvptx()) { | |
| 722 | for (slice[0]) |*byte| switch (byte.*) { | |
| 723 | '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_', | |
| 724 | else => {}, | |
| 725 | }; | |
| 726 | } | |
| 701 | // FIXME This has bitrotted and is no longer able to be implemented here. | |
| 702 | //const cpu_arch = zcu.root_mod.resolved_target.result.cpu.arch; | |
| 703 | //if (cpu_arch.isNvptx()) { | |
| 704 | // for (slice[0]) |*byte| switch (byte.*) { | |
| 705 | // '{', '}', '*', '[', ']', '(', ')', ',', ' ', '\'' => byte.* = '_', | |
| 706 | // else => {}, | |
| 707 | // }; | |
| 708 | //} | |
| 727 | 709 | |
| 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 | } |
| 730 | 712 | |
| 731 | 713 | pub fn getType(ns: Namespace, zcu: *Zcu) Type { |
| ... | ... | @@ -882,7 +864,7 @@ pub const File = struct { |
| 882 | 864 | }; |
| 883 | 865 | } |
| 884 | 866 | |
| 885 | pub fn fullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString { | |
| 867 | pub fn internFullyQualifiedName(file: File, pt: Zcu.PerThread) !InternPool.NullTerminatedString { | |
| 886 | 868 | const gpa = pt.zcu.gpa; |
| 887 | 869 | const ip = &pt.zcu.intern_pool; |
| 888 | 870 | const strings = ip.getLocal(pt.tid).getMutableStrings(gpa); |
| ... | ... | @@ -910,7 +892,7 @@ pub const File = struct { |
| 910 | 892 | } |
| 911 | 893 | |
| 912 | 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 | 896 | // Don't add the same module root twice. Note that since we always add module roots at the |
| 915 | 897 | // front of the references array (see below), this loop is actually O(1) on valid code. |
| 916 | 898 | if (ref == .root) { |
| ... | ... | @@ -942,7 +924,7 @@ pub const File = struct { |
| 942 | 924 | |
| 943 | 925 | /// Mark this file and every file referenced by it as multi_pkg and report an |
| 944 | 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 | 928 | file.multi_pkg = true; |
| 947 | 929 | file.status = .astgen_failure; |
| 948 | 930 | |
| ... | ... | @@ -962,9 +944,9 @@ pub const File = struct { |
| 962 | 944 | const import_path = file.zir.nullTerminatedString(item.data.name); |
| 963 | 945 | if (mem.eql(u8, import_path, "builtin")) continue; |
| 964 | 946 | |
| 965 | const res = mod.importFile(file, import_path) catch continue; | |
| 947 | const res = pt.importFile(file, import_path) catch continue; | |
| 966 | 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 | 1015 | } |
| 1034 | 1016 | }; |
| 1035 | 1017 | |
| 1018 | pub 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 | 1026 | /// Canonical reference to a position within a source file. |
| 1037 | 1027 | pub const SrcLoc = struct { |
| 1038 | 1028 | file_scope: *File, |
| ... | ... | @@ -2406,7 +2396,6 @@ pub const CompileError = error{ |
| 2406 | 2396 | pub fn init(mod: *Module, thread_count: usize) !void { |
| 2407 | 2397 | const gpa = mod.gpa; |
| 2408 | 2398 | try mod.intern_pool.init(gpa, thread_count); |
| 2409 | try mod.global_error_set.put(gpa, .empty, {}); | |
| 2410 | 2399 | } |
| 2411 | 2400 | |
| 2412 | 2401 | pub fn deinit(zcu: *Zcu) void { |
| ... | ... | @@ -2421,8 +2410,7 @@ pub fn deinit(zcu: *Zcu) void { |
| 2421 | 2410 | for (zcu.import_table.keys()) |key| { |
| 2422 | 2411 | gpa.free(key); |
| 2423 | 2412 | } |
| 2424 | for (0..zcu.import_table.entries.len) |file_index_usize| { | |
| 2425 | const file_index: File.Index = @enumFromInt(file_index_usize); | |
| 2413 | for (zcu.import_table.values()) |file_index| { | |
| 2426 | 2414 | pt.destroyFile(file_index); |
| 2427 | 2415 | } |
| 2428 | 2416 | zcu.import_table.deinit(gpa); |
| ... | ... | @@ -2479,8 +2467,6 @@ pub fn deinit(zcu: *Zcu) void { |
| 2479 | 2467 | zcu.single_exports.deinit(gpa); |
| 2480 | 2468 | zcu.multi_exports.deinit(gpa); |
| 2481 | 2469 | |
| 2482 | zcu.global_error_set.deinit(gpa); | |
| 2483 | ||
| 2484 | 2470 | zcu.potentially_outdated.deinit(gpa); |
| 2485 | 2471 | zcu.outdated.deinit(gpa); |
| 2486 | 2472 | zcu.outdated_ready.deinit(gpa); |
| ... | ... | @@ -3020,183 +3006,7 @@ pub const ImportFileResult = struct { |
| 3020 | 3006 | is_pkg: bool, |
| 3021 | 3007 | }; |
| 3022 | 3008 | |
| 3023 | pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult { | |
| 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. | |
| 3102 | pub 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 | ||
| 3199 | fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { | |
| 3009 | pub fn computePathDigest(zcu: *Zcu, mod: *Package.Module, sub_file_path: []const u8) Cache.BinDigest { | |
| 3200 | 3010 | const want_local_cache = mod == zcu.main_mod; |
| 3201 | 3011 | var path_hash: Cache.HashHelper = .{}; |
| 3202 | 3012 | path_hash.addBytes(build_options.version); |
| ... | ... | @@ -3292,43 +3102,11 @@ pub fn addUnitReference(zcu: *Zcu, src_unit: AnalUnit, referenced_unit: AnalUnit |
| 3292 | 3102 | gop.value_ptr.* = @intCast(ref_idx); |
| 3293 | 3103 | } |
| 3294 | 3104 | |
| 3295 | pub 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 | ||
| 3303 | pub 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 | ||
| 3311 | 3105 | pub fn errorSetBits(mod: *Module) u16 { |
| 3312 | 3106 | if (mod.error_limit == 0) return 0; |
| 3313 | 3107 | return std.math.log2_int_ceil(ErrorInt, mod.error_limit + 1); // +1 for no error |
| 3314 | 3108 | } |
| 3315 | 3109 | |
| 3316 | pub 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 | ||
| 3332 | 3110 | pub fn errNote( |
| 3333 | 3111 | mod: *Module, |
| 3334 | 3112 | src_loc: LazySrcLoc, |
| ... | ... | @@ -3394,41 +3172,6 @@ pub fn handleUpdateExports( |
| 3394 | 3172 | }; |
| 3395 | 3173 | } |
| 3396 | 3174 | |
| 3397 | pub 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 | ||
| 3432 | 3175 | pub fn addGlobalAssembly(mod: *Module, decl_index: Decl.Index, source: []const u8) !void { |
| 3433 | 3176 | const gop = try mod.global_assembly.getOrPut(mod.gpa, decl_index); |
| 3434 | 3177 | if (gop.found_existing) { |
| ... | ... | @@ -3744,22 +3487,28 @@ pub fn resolveReferences(zcu: *Zcu) !std.AutoHashMapUnmanaged(AnalUnit, Resolved |
| 3744 | 3487 | return result; |
| 3745 | 3488 | } |
| 3746 | 3489 | |
| 3747 | pub fn fileByIndex(zcu: *const Zcu, i: File.Index) *File { | |
| 3748 | return zcu.import_table.values()[@intFromEnum(i)]; | |
| 3490 | pub fn fileByIndex(zcu: *Zcu, file_index: File.Index) *File { | |
| 3491 | return zcu.intern_pool.filePtr(file_index); | |
| 3749 | 3492 | } |
| 3750 | 3493 | |
| 3751 | 3494 | /// Returns the `Decl` of the struct that represents this `File`. |
| 3752 | pub fn fileRootDecl(zcu: *const Zcu, i: File.Index) Decl.OptionalIndex { | |
| 3495 | pub fn fileRootDecl(zcu: *const Zcu, file_index: File.Index) Decl.OptionalIndex { | |
| 3753 | 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 | } |
| 3756 | 3501 | |
| 3757 | pub fn setFileRootDecl(zcu: *Zcu, i: File.Index, root_decl: Decl.OptionalIndex) void { | |
| 3502 | pub fn setFileRootDecl(zcu: *Zcu, file_index: File.Index, root_decl: Decl.OptionalIndex) void { | |
| 3758 | 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 | } |
| 3761 | 3508 | |
| 3762 | pub fn filePathDigest(zcu: *const Zcu, i: File.Index) Cache.BinDigest { | |
| 3509 | pub fn filePathDigest(zcu: *const Zcu, file_index: File.Index) Cache.BinDigest { | |
| 3763 | 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 | 342 | /// the Compilation mutex when acting on shared state. |
| 343 | 343 | fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, old_zir: Zir) !void { |
| 344 | 344 | const zcu = pt.zcu; |
| 345 | const ip = &zcu.intern_pool; | |
| 345 | 346 | const gpa = zcu.gpa; |
| 346 | 347 | const new_zir = file.zir; |
| 347 | 348 | |
| ... | ... | @@ -355,109 +356,117 @@ fn updateZirRefs(pt: Zcu.PerThread, file: *Zcu.File, file_index: Zcu.File.Index, |
| 355 | 356 | |
| 356 | 357 | // TODO: this should be done after all AstGen workers complete, to avoid |
| 357 | 358 | // iterating over this full set for every updated file. |
| 358 | for (zcu.intern_pool.tracked_insts.keys(), 0..) |*ti, idx_raw| { | |
| 359 | const ti_idx: InternPool.TrackedInst.Index = @enumFromInt(idx_raw); | |
| 360 | if (ti.file != file_index) continue; | |
| 361 | const old_inst = ti.inst; | |
| 362 | ti.inst = inst_map.get(ti.inst) orelse { | |
| 363 | // Tracking failed for this instruction. Invalidate associated `src_hash` deps. | |
| 364 | zcu.comp.mutex.lock(); | |
| 365 | defer zcu.comp.mutex.unlock(); | |
| 366 | log.debug("tracking failed for %{d}", .{old_inst}); | |
| 367 | try zcu.markDependeeOutdated(.{ .src_hash = ti_idx }); | |
| 368 | continue; | |
| 369 | }; | |
| 359 | for (ip.locals, 0..) |*local, tid| { | |
| 360 | local.mutate.tracked_insts.mutex.lock(); | |
| 361 | defer local.mutate.tracked_insts.mutex.unlock(); | |
| 362 | const tracked_insts_list = local.getMutableTrackedInsts(gpa); | |
| 363 | for (tracked_insts_list.view().items(.@"0"), 0..) |*tracked_inst, tracked_inst_unwrapped_index| { | |
| 364 | if (tracked_inst.file != file_index) continue; | |
| 365 | const old_inst = tracked_inst.inst; | |
| 366 | const tracked_inst_index = (InternPool.TrackedInst.Index.Unwrapped{ | |
| 367 | .tid = @enumFromInt(tid), | |
| 368 | .index = @intCast(tracked_inst_unwrapped_index), | |
| 369 | }).wrap(ip); | |
| 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 | }; | |
| 370 | 378 | |
| 371 | if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: { | |
| 372 | if (new_zir.getAssociatedSrcHash(ti.inst)) |new_hash| { | |
| 373 | if (std.zig.srcHashEql(old_hash, new_hash)) { | |
| 374 | break :hash_changed; | |
| 379 | if (old_zir.getAssociatedSrcHash(old_inst)) |old_hash| hash_changed: { | |
| 380 | if (new_zir.getAssociatedSrcHash(tracked_inst.inst)) |new_hash| { | |
| 381 | if (std.zig.srcHashEql(old_hash, new_hash)) { | |
| 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: {} -> {}", .{ | |
| 377 | old_inst, | |
| 378 | ti.inst, | |
| 379 | std.fmt.fmtSliceHexLower(&old_hash), | |
| 380 | std.fmt.fmtSliceHexLower(&new_hash), | |
| 381 | }); | |
| 391 | // The source hash associated with this instruction changed - invalidate relevant dependencies. | |
| 392 | zcu.comp.mutex.lock(); | |
| 393 | defer zcu.comp.mutex.unlock(); | |
| 394 | try zcu.markDependeeOutdated(.{ .src_hash = tracked_inst_index }); | |
| 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 | } | |
| 388 | 396 | |
| 389 | // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies. | |
| 390 | const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) { | |
| 391 | .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) { | |
| 392 | .struct_decl, .union_decl, .opaque_decl, .enum_decl => true, | |
| 397 | // If this is a `struct_decl` etc, we must invalidate any outdated namespace dependencies. | |
| 398 | const has_namespace = switch (old_tag[@intFromEnum(old_inst)]) { | |
| 399 | .extended => switch (old_data[@intFromEnum(old_inst)].extended.opcode) { | |
| 400 | .struct_decl, .union_decl, .opaque_decl, .enum_decl => true, | |
| 401 | else => false, | |
| 402 | }, | |
| 393 | 403 | else => false, |
| 394 | }, | |
| 395 | else => false, | |
| 396 | }; | |
| 397 | if (!has_namespace) continue; | |
| 398 | ||
| 399 | var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{}; | |
| 400 | defer old_names.deinit(zcu.gpa); | |
| 401 | { | |
| 402 | var it = old_zir.declIterator(old_inst); | |
| 403 | while (it.next()) |decl_inst| { | |
| 404 | const decl_name = old_zir.getDeclaration(decl_inst)[0].name; | |
| 405 | switch (decl_name) { | |
| 406 | .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue, | |
| 407 | _ => if (decl_name.isNamedTest(old_zir)) continue, | |
| 404 | }; | |
| 405 | if (!has_namespace) continue; | |
| 406 | ||
| 407 | var old_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .{}; | |
| 408 | defer old_names.deinit(zcu.gpa); | |
| 409 | { | |
| 410 | var it = old_zir.declIterator(old_inst); | |
| 411 | while (it.next()) |decl_inst| { | |
| 412 | const decl_name = old_zir.getDeclaration(decl_inst)[0].name; | |
| 413 | switch (decl_name) { | |
| 414 | .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue, | |
| 415 | _ => if (decl_name.isNamedTest(old_zir)) continue, | |
| 416 | } | |
| 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 | } | |
| 419 | var any_change = false; | |
| 420 | { | |
| 421 | var it = new_zir.declIterator(ti.inst); | |
| 422 | while (it.next()) |decl_inst| { | |
| 423 | const decl_name = old_zir.getDeclaration(decl_inst)[0].name; | |
| 424 | switch (decl_name) { | |
| 425 | .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue, | |
| 426 | _ => if (decl_name.isNamedTest(old_zir)) continue, | |
| 427 | var any_change = false; | |
| 428 | { | |
| 429 | var it = new_zir.declIterator(tracked_inst.inst); | |
| 430 | while (it.next()) |decl_inst| { | |
| 431 | const decl_name = old_zir.getDeclaration(decl_inst)[0].name; | |
| 432 | switch (decl_name) { | |
| 433 | .@"comptime", .@"usingnamespace", .unnamed_test, .decltest => continue, | |
| 434 | _ => 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).?; | |
| 429 | const name_ip = try zcu.intern_pool.getOrPutString( | |
| 430 | zcu.gpa, | |
| 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 | |
| 453 | } | |
| 454 | // The only elements remaining in `old_names` now are any names which were removed. | |
| 455 | for (old_names.keys()) |name_ip| { | |
| 437 | 456 | any_change = true; |
| 438 | 457 | zcu.comp.mutex.lock(); |
| 439 | 458 | defer zcu.comp.mutex.unlock(); |
| 440 | 459 | try zcu.markDependeeOutdated(.{ .namespace_name = .{ |
| 441 | .namespace = ti_idx, | |
| 460 | .namespace = tracked_inst_index, | |
| 442 | 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 | } | |
| 456 | 464 | |
| 457 | if (any_change) { | |
| 458 | zcu.comp.mutex.lock(); | |
| 459 | defer zcu.comp.mutex.unlock(); | |
| 460 | try zcu.markDependeeOutdated(.{ .namespace = ti_idx }); | |
| 465 | if (any_change) { | |
| 466 | zcu.comp.mutex.lock(); | |
| 467 | defer zcu.comp.mutex.unlock(); | |
| 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 | 557 | }; |
| 549 | 558 | } |
| 550 | 559 | |
| 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 | 561 | defer decl_prog_node.end(); |
| 553 | 562 | |
| 554 | 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 | 756 | defer liveness.deinit(gpa); |
| 748 | 757 | |
| 749 | 758 | if (build_options.enable_debug_extensions and comp.verbose_air) { |
| 750 | const fqn = try decl.fullyQualifiedName(pt); | |
| 751 | std.debug.print("# Begin Function AIR: {}:\n", .{fqn.fmt(ip)}); | |
| 759 | std.debug.print("# Begin Function AIR: {}:\n", .{decl.fqn.fmt(ip)}); | |
| 752 | 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 | } |
| 755 | 763 | |
| 756 | 764 | if (std.debug.runtime_safety) { |
| ... | ... | @@ -781,7 +789,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai |
| 781 | 789 | }; |
| 782 | 790 | } |
| 783 | 791 | |
| 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 | 793 | defer codegen_prog_node.end(); |
| 786 | 794 | |
| 787 | 795 | if (!air.typesFullyResolved(zcu)) { |
| ... | ... | @@ -818,7 +826,7 @@ pub fn linkerUpdateFunc(pt: Zcu.PerThread, func_index: InternPool.Index, air: Ai |
| 818 | 826 | |
| 819 | 827 | /// https://github.com/ziglang/zig/issues/14307 |
| 820 | 828 | pub 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 | 830 | const root_decl_index = pt.zcu.fileRootDecl(import_file_result.file_index); |
| 823 | 831 | if (root_decl_index == .none) { |
| 824 | 832 | return pt.semaFile(import_file_result.file_index); |
| ... | ... | @@ -855,7 +863,10 @@ fn getFileRootStruct( |
| 855 | 863 | const decls = file.zir.bodySlice(extra_index, decls_len); |
| 856 | 864 | extra_index += decls_len; |
| 857 | 865 | |
| 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 | 870 | const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{ |
| 860 | 871 | .layout = .auto, |
| 861 | 872 | .fields_len = fields_len, |
| ... | ... | @@ -996,8 +1007,8 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 996 | 1007 | zcu.setFileRootDecl(file_index, new_decl_index.toOptional()); |
| 997 | 1008 | zcu.namespacePtr(new_namespace_index).decl_index = new_decl_index; |
| 998 | 1009 | |
| 999 | new_decl.name = try file.fullyQualifiedName(pt); | |
| 1000 | new_decl.name_fully_qualified = true; | |
| 1010 | new_decl.fqn = try file.internFullyQualifiedName(pt); | |
| 1011 | new_decl.name = new_decl.fqn; | |
| 1001 | 1012 | new_decl.is_pub = true; |
| 1002 | 1013 | new_decl.is_exported = false; |
| 1003 | 1014 | new_decl.alignment = .none; |
| ... | ... | @@ -1016,7 +1027,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1016 | 1027 | switch (zcu.comp.cache_use) { |
| 1017 | 1028 | .whole => |whole| if (whole.cache_manifest) |man| { |
| 1018 | 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 | 1031 | return error.AnalysisFail; |
| 1021 | 1032 | }; |
| 1022 | 1033 | |
| ... | ... | @@ -1025,7 +1036,7 @@ fn semaFile(pt: Zcu.PerThread, file_index: Zcu.File.Index) Zcu.SemaError!void { |
| 1025 | 1036 | file.mod.root.sub_path, |
| 1026 | 1037 | file.sub_file_path, |
| 1027 | 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 | 1040 | return error.AnalysisFail; |
| 1030 | 1041 | }; |
| 1031 | 1042 | errdefer gpa.free(resolved_path); |
| ... | ... | @@ -1058,10 +1069,8 @@ fn semaDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.SemaDeclResult { |
| 1058 | 1069 | } |
| 1059 | 1070 | |
| 1060 | 1071 | log.debug("semaDecl '{d}'", .{@intFromEnum(decl_index)}); |
| 1061 | log.debug("decl name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)}); | |
| 1062 | defer blk: { | |
| 1063 | log.debug("finish decl name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)}); | |
| 1064 | } | |
| 1072 | log.debug("decl name '{}'", .{decl.fqn.fmt(ip)}); | |
| 1073 | defer log.debug("finish decl name '{}'", .{decl.fqn.fmt(ip)}); | |
| 1065 | 1074 | |
| 1066 | 1075 | const old_has_tv = decl.has_tv; |
| 1067 | 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 | 1093 | const std_mod = zcu.std_mod; |
| 1085 | 1094 | if (decl.getFileScope(zcu).mod != std_mod) break :ip_index .none; |
| 1086 | 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 | 1097 | const std_file_root_decl_index = zcu.fileRootDecl(std_file_imported.file_index); |
| 1089 | 1098 | const std_decl = zcu.declPtr(std_file_root_decl_index.unwrap().?); |
| 1090 | 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 | 1160 | defer sema.deinit(); |
| 1152 | 1161 | |
| 1153 | 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( | |
| 1155 | gpa, | |
| 1156 | decl.getFileScopeIndex(zcu), | |
| 1157 | decl_inst, | |
| 1158 | ) }); | |
| 1163 | try sema.declareDependency(.{ .src_hash = try ip.trackZir(gpa, pt.tid, .{ | |
| 1164 | .file = decl.getFileScopeIndex(zcu), | |
| 1165 | .inst = decl_inst, | |
| 1166 | }) }); | |
| 1159 | 1167 | |
| 1160 | 1168 | var block_scope: Sema.Block = .{ |
| 1161 | 1169 | .parent = null, |
| ... | ... | @@ -1359,6 +1367,195 @@ pub fn semaAnonOwnerDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !Zcu.Sem |
| 1359 | 1367 | }; |
| 1360 | 1368 | } |
| 1361 | 1369 | |
| 1370 | pub 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. | |
| 1456 | pub 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 | ||
| 1362 | 1559 | pub fn embedFile( |
| 1363 | 1560 | pt: Zcu.PerThread, |
| 1364 | 1561 | cur_file: *Zcu.File, |
| ... | ... | @@ -1432,20 +1629,6 @@ pub fn embedFile( |
| 1432 | 1629 | return pt.newEmbedFile(cur_file.mod, sub_file_path, resolved_path, gop.value_ptr, src_loc); |
| 1433 | 1630 | } |
| 1434 | 1631 | |
| 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. | |
| 1437 | pub 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. | |
| 1443 | pub 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 | 1632 | /// https://github.com/ziglang/zig/issues/14307 |
| 1450 | 1633 | fn newEmbedFile( |
| 1451 | 1634 | pt: Zcu.PerThread, |
| ... | ... | @@ -1718,7 +1901,10 @@ const ScanDeclIter = struct { |
| 1718 | 1901 | } |
| 1719 | 1902 | |
| 1720 | 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 | }); | |
| 1722 | 1908 | |
| 1723 | 1909 | // We create a Decl for it regardless of analysis status. |
| 1724 | 1910 | |
| ... | ... | @@ -1728,6 +1914,7 @@ const ScanDeclIter = struct { |
| 1728 | 1914 | const was_exported = decl.is_exported; |
| 1729 | 1915 | assert(decl.kind == kind); // ZIR tracking should preserve this |
| 1730 | 1916 | decl.name = decl_name; |
| 1917 | decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name); | |
| 1731 | 1918 | decl.is_pub = declaration.flags.is_pub; |
| 1732 | 1919 | decl.is_exported = declaration.flags.is_export; |
| 1733 | 1920 | break :decl_index .{ was_exported, decl_index }; |
| ... | ... | @@ -1737,6 +1924,7 @@ const ScanDeclIter = struct { |
| 1737 | 1924 | const new_decl = zcu.declPtr(new_decl_index); |
| 1738 | 1925 | new_decl.kind = kind; |
| 1739 | 1926 | new_decl.name = decl_name; |
| 1927 | new_decl.fqn = try namespace.internFullyQualifiedName(ip, gpa, pt.tid, decl_name); | |
| 1740 | 1928 | new_decl.is_pub = declaration.flags.is_pub; |
| 1741 | 1929 | new_decl.is_exported = declaration.flags.is_export; |
| 1742 | 1930 | new_decl.zir_decl_index = tracked_inst.toOptional(); |
| ... | ... | @@ -1761,10 +1949,9 @@ const ScanDeclIter = struct { |
| 1761 | 1949 | if (!comp.config.is_test) break :a false; |
| 1762 | 1950 | if (decl_mod != zcu.main_mod) break :a false; |
| 1763 | 1951 | if (is_named_test and comp.test_filters.len > 0) { |
| 1764 | const decl_fqn = try namespace.fullyQualifiedName(pt, decl_name); | |
| 1765 | const decl_fqn_slice = decl_fqn.toSlice(ip); | |
| 1952 | const decl_fqn = decl.fqn.toSlice(ip); | |
| 1766 | 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 | 1955 | } else break :a false; |
| 1769 | 1956 | } |
| 1770 | 1957 | zcu.test_functions.putAssumeCapacity(decl_index, {}); // may clobber on incremental update |
| ... | ... | @@ -1794,6 +1981,20 @@ const ScanDeclIter = struct { |
| 1794 | 1981 | } |
| 1795 | 1982 | }; |
| 1796 | 1983 | |
| 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. | |
| 1986 | pub 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. | |
| 1992 | pub 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 | ||
| 1797 | 1998 | pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: Allocator) Zcu.SemaError!Air { |
| 1798 | 1999 | const tracy = trace(@src()); |
| 1799 | 2000 | defer tracy.end(); |
| ... | ... | @@ -1805,12 +2006,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 1805 | 2006 | const decl_index = func.owner_decl; |
| 1806 | 2007 | const decl = mod.declPtr(decl_index); |
| 1807 | 2008 | |
| 1808 | log.debug("func name '{}'", .{(try decl.fullyQualifiedName(pt)).fmt(ip)}); | |
| 1809 | defer blk: { | |
| 1810 | log.debug("finish func name '{}'", .{(decl.fullyQualifiedName(pt) catch break :blk).fmt(ip)}); | |
| 1811 | } | |
| 2009 | log.debug("func name '{}'", .{decl.fqn.fmt(ip)}); | |
| 2010 | defer log.debug("finish func name '{}'", .{decl.fqn.fmt(ip)}); | |
| 1812 | 2011 | |
| 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 | 2013 | defer decl_prog_node.end(); |
| 1815 | 2014 | |
| 1816 | 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 | 2110 | runtime_params_len; |
| 1912 | 2111 | |
| 1913 | 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 | 2114 | const gop = sema.inst_map.getOrPutAssumeCapacity(inst); |
| 1916 | 2115 | if (gop.found_existing) continue; // provided above by comptime arg |
| 1917 | 2116 | |
| 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 | 2124 | const param_ty = fn_ty_info.param_types.get(ip)[runtime_param_index]; |
| 1919 | 2125 | runtime_param_index += 1; |
| 1920 | 2126 | |
| ... | ... | @@ -1935,7 +2141,10 @@ pub fn analyzeFnBody(pt: Zcu.PerThread, func_index: InternPool.Index, arena: All |
| 1935 | 2141 | .tag = .arg, |
| 1936 | 2142 | .data = .{ .arg = .{ |
| 1937 | 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 | 2262 | const gpa = zcu.gpa; |
| 2054 | 2263 | const decl_index = try zcu.intern_pool.createDecl(gpa, pt.tid, .{ |
| 2055 | 2264 | .name = undefined, |
| 2265 | .fqn = undefined, | |
| 2056 | 2266 | .src_namespace = namespace, |
| 2057 | 2267 | .has_tv = false, |
| 2058 | 2268 | .owns_tv = false, |
| ... | ... | @@ -2077,6 +2287,36 @@ pub fn allocateNewDecl(pt: Zcu.PerThread, namespace: Zcu.Namespace.Index) !Zcu.D |
| 2077 | 2287 | return decl_index; |
| 2078 | 2288 | } |
| 2079 | 2289 | |
| 2290 | pub 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 | ||
| 2297 | pub 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 | ||
| 2301 | pub 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 | ||
| 2080 | 2320 | fn lockAndClearFileCompileError(pt: Zcu.PerThread, file: *Zcu.File) void { |
| 2081 | 2321 | switch (file.status) { |
| 2082 | 2322 | .success_zir, .retryable_failure => {}, |
| ... | ... | @@ -2229,7 +2469,7 @@ pub fn populateTestFunctions( |
| 2229 | 2469 | const gpa = zcu.gpa; |
| 2230 | 2470 | const ip = &zcu.intern_pool; |
| 2231 | 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 | 2473 | const root_decl_index = zcu.fileRootDecl(builtin_file_index); |
| 2234 | 2474 | const root_decl = zcu.declPtr(root_decl_index.unwrap().?); |
| 2235 | 2475 | const builtin_namespace = zcu.namespacePtr(root_decl.src_namespace); |
| ... | ... | @@ -2260,7 +2500,7 @@ pub fn populateTestFunctions( |
| 2260 | 2500 | |
| 2261 | 2501 | for (test_fn_vals, zcu.test_functions.keys()) |*test_fn_val, test_decl_index| { |
| 2262 | 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 | 2504 | const test_decl_name_len = test_decl_name.length(ip); |
| 2265 | 2505 | const test_name_anon_decl: InternPool.Key.Ptr.BaseAddr.AnonDecl = n: { |
| 2266 | 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 | 2606 | |
| 2367 | 2607 | const decl = zcu.declPtr(decl_index); |
| 2368 | 2608 | |
| 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 | 2610 | defer codegen_prog_node.end(); |
| 2371 | 2611 | |
| 2372 | 2612 | if (comp.bin_file) |lf| { |
| ... | ... | @@ -2396,6 +2636,87 @@ pub fn linkerUpdateDecl(pt: Zcu.PerThread, decl_index: Zcu.Decl.Index) !void { |
| 2396 | 2636 | } |
| 2397 | 2637 | } |
| 2398 | 2638 | |
| 2639 | pub 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 | ||
| 2681 | pub 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 | 2720 | /// Shortcut for calling `intern_pool.get`. |
| 2400 | 2721 | pub fn intern(pt: Zcu.PerThread, key: InternPool.Key) Allocator.Error!InternPool.Index { |
| 2401 | 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 | 3218 | const zcu = pt.zcu; |
| 2898 | 3219 | const gpa = zcu.gpa; |
| 2899 | 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 | 3222 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index).unwrap().?; |
| 2902 | 3223 | const std_namespace = zcu.declPtr(std_file_root_decl).getOwnedInnerNamespace(zcu).?; |
| 2903 | 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 | 4231 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4232 | 4232 | self.arg_index = arg_index + 1; |
| 4233 | 4233 | |
| 4234 | const pt = self.pt; | |
| 4235 | const mod = pt.zcu; | |
| 4236 | 4234 | const ty = self.typeOfIndex(inst); |
| 4237 | 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); | |
| 4240 | 4236 | |
| 4241 | try self.dbg_info_relocs.append(self.gpa, .{ | |
| 4242 | .tag = tag, | |
| 4243 | .ty = ty, | |
| 4244 | .name = name, | |
| 4245 | .mcv = self.args[arg_index], | |
| 4246 | }); | |
| 4237 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | |
| 4238 | if (name_nts != .none) { | |
| 4239 | const name = self.air.nullTerminatedString(@intFromEnum(name_nts)); | |
| 4240 | try self.dbg_info_relocs.append(self.gpa, .{ | |
| 4241 | .tag = tag, | |
| 4242 | .ty = ty, | |
| 4243 | .name = name, | |
| 4244 | .mcv = self.args[arg_index], | |
| 4245 | }); | |
| 4246 | } | |
| 4247 | 4247 | |
| 4248 | 4248 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4249 | 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 | 4206 | while (self.args[arg_index] == .none) arg_index += 1; |
| 4207 | 4207 | self.arg_index = arg_index + 1; |
| 4208 | 4208 | |
| 4209 | const pt = self.pt; | |
| 4210 | const mod = pt.zcu; | |
| 4211 | 4209 | const ty = self.typeOfIndex(inst); |
| 4212 | 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); | |
| 4215 | 4211 | |
| 4216 | try self.dbg_info_relocs.append(self.gpa, .{ | |
| 4217 | .tag = tag, | |
| 4218 | .ty = ty, | |
| 4219 | .name = name, | |
| 4220 | .mcv = self.args[arg_index], | |
| 4221 | }); | |
| 4212 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | |
| 4213 | if (name_nts != .none) { | |
| 4214 | const name = self.air.nullTerminatedString(@intFromEnum(name_nts)); | |
| 4215 | try self.dbg_info_relocs.append(self.gpa, .{ | |
| 4216 | .tag = tag, | |
| 4217 | .ty = ty, | |
| 4218 | .name = name, | |
| 4219 | .mcv = self.args[arg_index], | |
| 4220 | }); | |
| 4221 | } | |
| 4222 | 4222 | |
| 4223 | 4223 | const result: MCValue = if (self.liveness.isUnused(inst)) .dead else self.args[arg_index]; |
| 4224 | 4224 | return self.finishAir(inst, result, .{ .none, .none, .none }); |
src/arch/riscv64/CodeGen.zig+3-2| ... | ... | @@ -933,7 +933,7 @@ fn formatDecl( |
| 933 | 933 | _: std.fmt.FormatOptions, |
| 934 | 934 | writer: anytype, |
| 935 | 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 | } |
| 938 | 938 | fn fmtDecl(func: *Func, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { |
| 939 | 939 | return .{ .data = .{ |
| ... | ... | @@ -4051,7 +4051,8 @@ fn genArgDbgInfo(func: Func, inst: Air.Inst.Index, mcv: MCValue) !void { |
| 4051 | 4051 | const arg = func.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 4052 | 4052 | const ty = arg.ty.toType(); |
| 4053 | 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)); | |
| 4055 | 4056 | |
| 4056 | 4057 | switch (func.debug_output) { |
| 4057 | 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 | 3614 | const arg = self.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 3615 | 3615 | const ty = arg.ty.toType(); |
| 3616 | 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)); | |
| 3618 | 3619 | |
| 3619 | 3620 | switch (self.debug_output) { |
| 3620 | 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 | 2585 | |
| 2586 | 2586 | switch (func.debug_output) { |
| 2587 | 2587 | .dwarf => |dwarf| { |
| 2588 | const src_index = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; | |
| 2589 | const name = mod.getParamName(func.func_index, src_index); | |
| 2590 | try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{ | |
| 2591 | .wasm_local = arg.local.value, | |
| 2592 | }); | |
| 2588 | const name_nts = func.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | |
| 2589 | if (name_nts != .none) { | |
| 2590 | const name = func.air.nullTerminatedString(@intFromEnum(name_nts)); | |
| 2591 | try dwarf.genArgDbgInfo(name, arg_ty, mod.funcOwnerDeclIndex(func.func_index), .{ | |
| 2592 | .wasm_local = arg.local.value, | |
| 2593 | }); | |
| 2594 | } | |
| 2593 | 2595 | }, |
| 2594 | 2596 | else => {}, |
| 2595 | 2597 | } |
| ... | ... | @@ -3302,7 +3304,7 @@ fn lowerConstant(func: *CodeGen, val: Value, ty: Type) InnerError!WValue { |
| 3302 | 3304 | } |
| 3303 | 3305 | }, |
| 3304 | 3306 | .err => |err| { |
| 3305 | const int = try mod.getErrorValue(err.name); | |
| 3307 | const int = try pt.getErrorValue(err.name); | |
| 3306 | 3308 | return WValue{ .imm32 = int }; |
| 3307 | 3309 | }, |
| 3308 | 3310 | .error_union => |error_union| { |
| ... | ... | @@ -3450,30 +3452,25 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { |
| 3450 | 3452 | /// Returns a `Value` as a signed 32 bit value. |
| 3451 | 3453 | /// It's illegal to provide a value with a type that cannot be represented |
| 3452 | 3454 | /// as an integer value. |
| 3453 | fn valueAsI32(func: *const CodeGen, val: Value, ty: Type) i32 { | |
| 3455 | fn valueAsI32(func: *const CodeGen, val: Value) i32 { | |
| 3454 | 3456 | const pt = func.pt; |
| 3455 | 3457 | const mod = pt.zcu; |
| 3458 | const ip = &mod.intern_pool; | |
| 3456 | 3459 | |
| 3457 | switch (val.ip_index) { | |
| 3458 | .none => {}, | |
| 3460 | switch (val.toIntern()) { | |
| 3459 | 3461 | .bool_true => return 1, |
| 3460 | 3462 | .bool_false => return 0, |
| 3461 | else => return switch (mod.intern_pool.indexToKey(val.ip_index)) { | |
| 3462 | .enum_tag => |enum_tag| intIndexAsI32(&mod.intern_pool, enum_tag.int, pt), | |
| 3463 | else => return switch (ip.indexToKey(val.ip_index)) { | |
| 3464 | .enum_tag => |enum_tag| intIndexAsI32(ip, enum_tag.int, pt), | |
| 3463 | 3465 | .int => |int| intStorageAsI32(int.storage, pt), |
| 3464 | 3466 | .ptr => |ptr| { |
| 3465 | 3467 | assert(ptr.base_addr == .int); |
| 3466 | 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 | 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 | } |
| 3478 | 3475 | |
| 3479 | 3476 | fn 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 | 4093 | |
| 4097 | 4094 | for (items, 0..) |ref, i| { |
| 4098 | 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 | 4097 | if (lowest_maybe == null or int_val < lowest_maybe.?) { |
| 4101 | 4098 | lowest_maybe = int_val; |
| 4102 | 4099 | } |
| ... | ... | @@ -7284,8 +7281,8 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { |
| 7284 | 7281 | defer arena_allocator.deinit(); |
| 7285 | 7282 | const arena = arena_allocator.allocator(); |
| 7286 | 7283 | |
| 7287 | const fqn = try mod.declPtr(enum_decl_index).fullyQualifiedName(pt); | |
| 7288 | const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{fqn.fmt(ip)}); | |
| 7284 | const decl = mod.declPtr(enum_decl_index); | |
| 7285 | const func_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{}", .{decl.fqn.fmt(ip)}); | |
| 7289 | 7286 | |
| 7290 | 7287 | // check if we already generated code for this. |
| 7291 | 7288 | if (func.bin_file.findGlobalSymbol(func_name)) |loc| { |
| ... | ... | @@ -7452,7 +7449,7 @@ fn airErrorSetHasValue(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7452 | 7449 | var lowest: ?u32 = null; |
| 7453 | 7450 | var highest: ?u32 = null; |
| 7454 | 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 | 7453 | if (lowest) |*l| { |
| 7457 | 7454 | if (err_int < l.*) { |
| 7458 | 7455 | l.* = err_int; |
src/arch/x86_64/CodeGen.zig+8-6| ... | ... | @@ -1077,7 +1077,7 @@ fn formatDecl( |
| 1077 | 1077 | _: std.fmt.FormatOptions, |
| 1078 | 1078 | writer: anytype, |
| 1079 | 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 | } |
| 1082 | 1082 | fn fmtDecl(self: *Self, decl_index: InternPool.DeclIndex) std.fmt.Formatter(formatDecl) { |
| 1083 | 1083 | return .{ .data = .{ |
| ... | ... | @@ -11920,9 +11920,11 @@ fn airArg(self: *Self, inst: Air.Inst.Index) !void { |
| 11920 | 11920 | else => return self.fail("TODO implement arg for {}", .{src_mcv}), |
| 11921 | 11921 | }; |
| 11922 | 11922 | |
| 11923 | const src_index = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.src_index; | |
| 11924 | const name = mod.getParamName(self.owner.func_index, src_index); | |
| 11925 | try self.genArgDbgInfo(arg_ty, name, src_mcv); | |
| 11923 | const name_nts = self.air.instructions.items(.data)[@intFromEnum(inst)].arg.name; | |
| 11924 | switch (name_nts) { | |
| 11925 | .none => {}, | |
| 11926 | _ => try self.genArgDbgInfo(arg_ty, self.air.nullTerminatedString(@intFromEnum(name_nts)), src_mcv), | |
| 11927 | } | |
| 11926 | 11928 | |
| 11927 | 11929 | break :result dst_mcv; |
| 11928 | 11930 | }; |
| ... | ... | @@ -16433,7 +16435,7 @@ fn airErrorName(self: *Self, inst: Air.Inst.Index) !void { |
| 16433 | 16435 | .size = .dword, |
| 16434 | 16436 | .index = err_reg.to64(), |
| 16435 | 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 | 16448 | .size = .dword, |
| 16447 | 16449 | .index = err_reg.to64(), |
| 16448 | 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 | 137 | |
| 138 | 138 | if (lazy_sym.ty.isAnyError(pt.zcu)) { |
| 139 | 139 | alignment.* = .@"4"; |
| 140 | const err_names = pt.zcu.global_error_set.keys(); | |
| 140 | const err_names = ip.global_error_set.getNamesFromMainThread(); | |
| 141 | 141 | mem.writeInt(u32, try code.addManyAsArray(4), @intCast(err_names.len), endian); |
| 142 | 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 | 144 | for (err_names) |err_name_nts| { |
| 145 | 145 | const err_name = err_name_nts.toSlice(ip); |
| 146 | 146 | mem.writeInt(u32, code.items[offset..][0..4], @intCast(code.items.len), endian); |
| ... | ... | @@ -243,13 +243,13 @@ pub fn generateSymbol( |
| 243 | 243 | int_val.writeTwosComplement(try code.addManyAsSlice(abi_size), endian); |
| 244 | 244 | }, |
| 245 | 245 | .err => |err| { |
| 246 | const int = try mod.getErrorValue(err.name); | |
| 246 | const int = try pt.getErrorValue(err.name); | |
| 247 | 247 | try code.writer().writeInt(u16, @intCast(int), endian); |
| 248 | 248 | }, |
| 249 | 249 | .error_union => |error_union| { |
| 250 | 250 | const payload_ty = ty.errorUnionPayload(mod); |
| 251 | 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 | 253 | .payload => 0, |
| 254 | 254 | }; |
| 255 | 255 | |
| ... | ... | @@ -1058,7 +1058,7 @@ pub fn genTypedValue( |
| 1058 | 1058 | }, |
| 1059 | 1059 | .ErrorSet => { |
| 1060 | 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 | 1062 | return GenResult.mcv(.{ .immediate = error_index }); |
| 1063 | 1063 | }, |
| 1064 | 1064 | .ErrorUnion => { |
src/codegen/c.zig+14-21| ... | ... | @@ -2194,13 +2194,9 @@ pub const DeclGen = struct { |
| 2194 | 2194 | }) else { |
| 2195 | 2195 | // MSVC has a limit of 4095 character token length limit, and fmtIdent can (worst case), |
| 2196 | 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; | |
| 2198 | var name_stream = std.io.fixedBufferStream(&name); | |
| 2199 | decl.renderFullyQualifiedName(zcu, name_stream.writer()) catch |err| switch (err) { | |
| 2200 | error.NoSpaceLeft => {}, | |
| 2201 | }; | |
| 2197 | const fqn_slice = decl.fqn.toSlice(ip); | |
| 2202 | 2198 | try writer.print("{}__{d}", .{ |
| 2203 | fmtIdent(name_stream.getWritten()), | |
| 2199 | fmtIdent(fqn_slice[0..@min(fqn_slice.len, 100)]), | |
| 2204 | 2200 | @intFromEnum(decl_index), |
| 2205 | 2201 | }); |
| 2206 | 2202 | } |
| ... | ... | @@ -2587,11 +2583,9 @@ pub fn genTypeDecl( |
| 2587 | 2583 | try writer.writeByte(';'); |
| 2588 | 2584 | const owner_decl = zcu.declPtr(owner_decl_index); |
| 2589 | 2585 | const owner_mod = zcu.namespacePtr(owner_decl.src_namespace).fileScope(zcu).mod; |
| 2590 | if (!owner_mod.strip) { | |
| 2591 | try writer.writeAll(" /* "); | |
| 2592 | try owner_decl.renderFullyQualifiedName(zcu, writer); | |
| 2593 | try writer.writeAll(" */"); | |
| 2594 | } | |
| 2586 | if (!owner_mod.strip) try writer.print(" /* {} */", .{ | |
| 2587 | owner_decl.fqn.fmt(&zcu.intern_pool), | |
| 2588 | }); | |
| 2595 | 2589 | try writer.writeByte('\n'); |
| 2596 | 2590 | }, |
| 2597 | 2591 | }, |
| ... | ... | @@ -2628,10 +2622,11 @@ pub fn genErrDecls(o: *Object) !void { |
| 2628 | 2622 | |
| 2629 | 2623 | var max_name_len: usize = 0; |
| 2630 | 2624 | // 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 | 2627 | try writer.writeAll("enum {\n"); |
| 2633 | 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 | 2630 | const name = name_nts.toSlice(ip); |
| 2636 | 2631 | max_name_len = @max(name.len, max_name_len); |
| 2637 | 2632 | const err_val = try pt.intern(.{ .err = .{ |
| ... | ... | @@ -2650,7 +2645,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2650 | 2645 | defer o.dg.gpa.free(name_buf); |
| 2651 | 2646 | |
| 2652 | 2647 | @memcpy(name_buf[0..name_prefix.len], name_prefix); |
| 2653 | for (zcu.global_error_set.keys()) |name| { | |
| 2648 | for (names) |name| { | |
| 2654 | 2649 | const name_slice = name.toSlice(ip); |
| 2655 | 2650 | @memcpy(name_buf[name_prefix.len..][0..name_slice.len], name_slice); |
| 2656 | 2651 | const identifier = name_buf[0 .. name_prefix.len + name_slice.len]; |
| ... | ... | @@ -2680,7 +2675,7 @@ pub fn genErrDecls(o: *Object) !void { |
| 2680 | 2675 | } |
| 2681 | 2676 | |
| 2682 | 2677 | const name_array_ty = try pt.arrayType(.{ |
| 2683 | .len = zcu.global_error_set.count(), | |
| 2678 | .len = 1 + names.len, | |
| 2684 | 2679 | .child = .slice_const_u8_sentinel_0_type, |
| 2685 | 2680 | }); |
| 2686 | 2681 | |
| ... | ... | @@ -2694,9 +2689,9 @@ pub fn genErrDecls(o: *Object) !void { |
| 2694 | 2689 | .complete, |
| 2695 | 2690 | ); |
| 2696 | 2691 | try writer.writeAll(" = {"); |
| 2697 | for (zcu.global_error_set.keys(), 0..) |name_nts, value| { | |
| 2692 | for (names, 1..) |name_nts, val| { | |
| 2698 | 2693 | const name = name_nts.toSlice(ip); |
| 2699 | if (value != 0) try writer.writeByte(','); | |
| 2694 | if (val > 1) try writer.writeAll(", "); | |
| 2700 | 2695 | try writer.print("{{" ++ name_prefix ++ "{}, {}}}", .{ |
| 2701 | 2696 | fmtIdent(name), |
| 2702 | 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 | 4558 | const extra = f.air.extraData(Air.DbgInlineBlock, ty_pl.payload); |
| 4564 | 4559 | const owner_decl = zcu.funcOwnerDeclPtr(extra.data.func); |
| 4565 | 4560 | const writer = f.object.writer(); |
| 4566 | try writer.writeAll("/* inline:"); | |
| 4567 | try owner_decl.renderFullyQualifiedName(zcu, writer); | |
| 4568 | try writer.writeAll(" */\n"); | |
| 4561 | try writer.print("/* inline:{} */\n", .{owner_decl.fqn.fmt(&zcu.intern_pool)}); | |
| 4569 | 4562 | return lowerBlock(f, inst, @ptrCast(f.air.extra[extra.end..][0..extra.data.body_len])); |
| 4570 | 4563 | } |
| 4571 | 4564 | |
| ... | ... | @@ -6881,7 +6874,7 @@ fn airErrorName(f: *Function, inst: Air.Inst.Index) !CValue { |
| 6881 | 6874 | |
| 6882 | 6875 | try writer.writeAll(" = zig_errorName["); |
| 6883 | 6876 | try f.writeCValue(writer, operand, .Other); |
| 6884 | try writer.writeAll("];\n"); | |
| 6877 | try writer.writeAll(" - 1];\n"); | |
| 6885 | 6878 | return local; |
| 6886 | 6879 | } |
| 6887 | 6880 |
src/codegen/llvm.zig+34-38| ... | ... | @@ -1036,20 +1036,21 @@ pub const Object = struct { |
| 1036 | 1036 | |
| 1037 | 1037 | const pt = o.pt; |
| 1038 | 1038 | const mod = pt.zcu; |
| 1039 | const ip = &mod.intern_pool; | |
| 1039 | 1040 | |
| 1040 | const error_name_list = mod.global_error_set.keys(); | |
| 1041 | const llvm_errors = try mod.gpa.alloc(Builder.Constant, error_name_list.len); | |
| 1041 | const error_name_list = ip.global_error_set.getNamesFromMainThread(); | |
| 1042 | const llvm_errors = try mod.gpa.alloc(Builder.Constant, 1 + error_name_list.len); | |
| 1042 | 1043 | defer mod.gpa.free(llvm_errors); |
| 1043 | 1044 | |
| 1044 | 1045 | // TODO: Address space |
| 1045 | 1046 | const slice_ty = Type.slice_const_u8_sentinel_0; |
| 1046 | 1047 | const llvm_usize_ty = try o.lowerType(Type.usize); |
| 1047 | 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); | |
| 1049 | 1050 | |
| 1050 | 1051 | llvm_errors[0] = try o.builder.undefConst(llvm_slice_ty); |
| 1051 | for (llvm_errors[1..], error_name_list[1..]) |*llvm_error, name| { | |
| 1052 | const name_string = try o.builder.stringNull(name.toSlice(&mod.intern_pool)); | |
| 1052 | for (llvm_errors[1..], error_name_list) |*llvm_error, name| { | |
| 1053 | const name_string = try o.builder.stringNull(name.toSlice(ip)); | |
| 1053 | 1054 | const name_init = try o.builder.stringConst(name_string); |
| 1054 | 1055 | const name_variable_index = |
| 1055 | 1056 | try o.builder.addVariable(.empty, name_init.typeOf(&o.builder), .default); |
| ... | ... | @@ -1085,7 +1086,7 @@ pub const Object = struct { |
| 1085 | 1086 | // If there is no such function in the module, it means the source code does not need it. |
| 1086 | 1087 | const name = o.builder.strtabStringIfExists(lt_errors_fn_name) orelse return; |
| 1087 | 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; | |
| 1089 | 1090 | |
| 1090 | 1091 | var wip = try Builder.WipFunction.init(&o.builder, .{ |
| 1091 | 1092 | .function = llvm_fn.ptrConst(&o.builder).kind.function, |
| ... | ... | @@ -1096,12 +1097,12 @@ pub const Object = struct { |
| 1096 | 1097 | |
| 1097 | 1098 | // Example source of the following LLVM IR: |
| 1098 | 1099 | // fn __zig_lt_errors_len(index: u16) bool { |
| 1099 | // return index < total_errors_len; | |
| 1100 | // return index <= total_errors_len; | |
| 1100 | 1101 | // } |
| 1101 | 1102 | |
| 1102 | 1103 | const lhs = wip.arg(0); |
| 1103 | 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 | 1106 | _ = try wip.ret(is_lt); |
| 1106 | 1107 | try wip.finish(); |
| 1107 | 1108 | } |
| ... | ... | @@ -1744,7 +1745,7 @@ pub const Object = struct { |
| 1744 | 1745 | if (export_indices.len != 0) { |
| 1745 | 1746 | return updateExportedGlobal(self, zcu, global_index, export_indices); |
| 1746 | 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 | 1749 | try global_index.rename(fqn, &self.builder); |
| 1749 | 1750 | global_index.setLinkage(.internal, &self.builder); |
| 1750 | 1751 | if (comp.config.dll_export_fns) |
| ... | ... | @@ -2811,7 +2812,7 @@ pub const Object = struct { |
| 2811 | 2812 | const zcu = pt.zcu; |
| 2812 | 2813 | |
| 2813 | 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; | |
| 2815 | 2816 | |
| 2816 | 2817 | const builtin_str = try zcu.intern_pool.getOrPutString(zcu.gpa, pt.tid, "builtin", .no_embedded_nulls); |
| 2817 | 2818 | const std_file_root_decl = zcu.fileRootDecl(std_file_imported.file_index); |
| ... | ... | @@ -2863,10 +2864,7 @@ pub const Object = struct { |
| 2863 | 2864 | const is_extern = decl.isExtern(zcu); |
| 2864 | 2865 | const function_index = try o.builder.addFunction( |
| 2865 | 2866 | try o.lowerType(zig_fn_type), |
| 2866 | try o.builder.strtabString((if (is_extern) | |
| 2867 | decl.name | |
| 2868 | else | |
| 2869 | try decl.fullyQualifiedName(pt)).toSlice(ip)), | |
| 2867 | try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)), | |
| 2870 | 2868 | toLlvmAddressSpace(decl.@"addrspace", target), |
| 2871 | 2869 | ); |
| 2872 | 2870 | gop.value_ptr.* = function_index.ptrConst(&o.builder).global; |
| ... | ... | @@ -3077,14 +3075,12 @@ pub const Object = struct { |
| 3077 | 3075 | |
| 3078 | 3076 | const pt = o.pt; |
| 3079 | 3077 | const zcu = pt.zcu; |
| 3078 | const ip = &zcu.intern_pool; | |
| 3080 | 3079 | const decl = zcu.declPtr(decl_index); |
| 3081 | 3080 | const is_extern = decl.isExtern(zcu); |
| 3082 | 3081 | |
| 3083 | 3082 | const variable_index = try o.builder.addVariable( |
| 3084 | try o.builder.strtabString((if (is_extern) | |
| 3085 | decl.name | |
| 3086 | else | |
| 3087 | try decl.fullyQualifiedName(pt)).toSlice(&zcu.intern_pool)), | |
| 3083 | try o.builder.strtabString((if (is_extern) decl.name else decl.fqn).toSlice(ip)), | |
| 3088 | 3084 | try o.lowerType(decl.typeOf(zcu)), |
| 3089 | 3085 | toLlvmGlobalAddressSpace(decl.@"addrspace", zcu.getTarget()), |
| 3090 | 3086 | ); |
| ... | ... | @@ -3312,7 +3308,7 @@ pub const Object = struct { |
| 3312 | 3308 | return int_ty; |
| 3313 | 3309 | } |
| 3314 | 3310 | |
| 3315 | const fqn = try mod.declPtr(struct_type.decl.unwrap().?).fullyQualifiedName(pt); | |
| 3311 | const decl = mod.declPtr(struct_type.decl.unwrap().?); | |
| 3316 | 3312 | |
| 3317 | 3313 | var llvm_field_types = std.ArrayListUnmanaged(Builder.Type){}; |
| 3318 | 3314 | defer llvm_field_types.deinit(o.gpa); |
| ... | ... | @@ -3377,7 +3373,7 @@ pub const Object = struct { |
| 3377 | 3373 | ); |
| 3378 | 3374 | } |
| 3379 | 3375 | |
| 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 | 3377 | try o.type_map.put(o.gpa, t.toIntern(), ty); |
| 3382 | 3378 | |
| 3383 | 3379 | o.builder.namedTypeSetBody( |
| ... | ... | @@ -3466,7 +3462,7 @@ pub const Object = struct { |
| 3466 | 3462 | return enum_tag_ty; |
| 3467 | 3463 | } |
| 3468 | 3464 | |
| 3469 | const fqn = try mod.declPtr(union_obj.decl).fullyQualifiedName(pt); | |
| 3465 | const decl = mod.declPtr(union_obj.decl); | |
| 3470 | 3466 | |
| 3471 | 3467 | const aligned_field_ty = Type.fromInterned(union_obj.field_types.get(ip)[layout.most_aligned_field]); |
| 3472 | 3468 | const aligned_field_llvm_ty = try o.lowerType(aligned_field_ty); |
| ... | ... | @@ -3486,7 +3482,7 @@ pub const Object = struct { |
| 3486 | 3482 | }; |
| 3487 | 3483 | |
| 3488 | 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 | 3486 | try o.type_map.put(o.gpa, t.toIntern(), ty); |
| 3491 | 3487 | |
| 3492 | 3488 | o.builder.namedTypeSetBody( |
| ... | ... | @@ -3514,7 +3510,7 @@ pub const Object = struct { |
| 3514 | 3510 | llvm_fields_len += 1; |
| 3515 | 3511 | } |
| 3516 | 3512 | |
| 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 | 3514 | try o.type_map.put(o.gpa, t.toIntern(), ty); |
| 3519 | 3515 | |
| 3520 | 3516 | o.builder.namedTypeSetBody( |
| ... | ... | @@ -3527,8 +3523,7 @@ pub const Object = struct { |
| 3527 | 3523 | const gop = try o.type_map.getOrPut(o.gpa, t.toIntern()); |
| 3528 | 3524 | if (!gop.found_existing) { |
| 3529 | 3525 | const decl = mod.declPtr(ip.loadOpaqueType(t.toIntern()).decl); |
| 3530 | const fqn = try decl.fullyQualifiedName(pt); | |
| 3531 | gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(fqn.toSlice(ip))); | |
| 3526 | gop.value_ptr.* = try o.builder.opaqueType(try o.builder.string(decl.fqn.toSlice(ip))); | |
| 3532 | 3527 | } |
| 3533 | 3528 | return gop.value_ptr.*; |
| 3534 | 3529 | }, |
| ... | ... | @@ -3826,7 +3821,7 @@ pub const Object = struct { |
| 3826 | 3821 | return lowerBigInt(o, ty, bigint); |
| 3827 | 3822 | }, |
| 3828 | 3823 | .err => |err| { |
| 3829 | const int = try mod.getErrorValue(err.name); | |
| 3824 | const int = try pt.getErrorValue(err.name); | |
| 3830 | 3825 | const llvm_int = try o.builder.intConst(try o.errorIntType(), int); |
| 3831 | 3826 | return llvm_int; |
| 3832 | 3827 | }, |
| ... | ... | @@ -4587,11 +4582,11 @@ pub const Object = struct { |
| 4587 | 4582 | |
| 4588 | 4583 | const usize_ty = try o.lowerType(Type.usize); |
| 4589 | 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 | 4586 | const target = zcu.root_mod.resolved_target.result; |
| 4592 | 4587 | const function_index = try o.builder.addFunction( |
| 4593 | 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 | 4590 | toLlvmAddressSpace(.generic, target), |
| 4596 | 4591 | ); |
| 4597 | 4592 | |
| ... | ... | @@ -5175,8 +5170,6 @@ pub const FuncGen = struct { |
| 5175 | 5170 | const line_number = decl.navSrcLine(zcu) + 1; |
| 5176 | 5171 | self.inlined = self.wip.debug_location; |
| 5177 | 5172 | |
| 5178 | const fqn = try decl.fullyQualifiedName(pt); | |
| 5179 | ||
| 5180 | 5173 | const fn_ty = try pt.funcType(.{ |
| 5181 | 5174 | .param_types = &.{}, |
| 5182 | 5175 | .return_type = .void_type, |
| ... | ... | @@ -5185,7 +5178,7 @@ pub const FuncGen = struct { |
| 5185 | 5178 | self.scope = try o.builder.debugSubprogram( |
| 5186 | 5179 | self.file, |
| 5187 | 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 | 5182 | line_number, |
| 5190 | 5183 | line_number + func.lbrace_line, |
| 5191 | 5184 | try o.lowerDebugType(fn_ty), |
| ... | ... | @@ -8867,19 +8860,21 @@ pub const FuncGen = struct { |
| 8867 | 8860 | self.arg_index += 1; |
| 8868 | 8861 | |
| 8869 | 8862 | // 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; | |
| 8871 | 8864 | |
| 8872 | 8865 | const inst_ty = self.typeOfIndex(inst); |
| 8873 | 8866 | if (needDbgVarWorkaround(o)) return arg_val; |
| 8874 | 8867 | |
| 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 | 8871 | const func_index = self.dg.decl.getOwnedFunctionIndex(); |
| 8877 | 8872 | const func = mod.funcInfo(func_index); |
| 8878 | 8873 | const lbrace_line = mod.declPtr(func.owner_decl).navSrcLine(mod) + func.lbrace_line + 1; |
| 8879 | 8874 | const lbrace_col = func.lbrace_column + 1; |
| 8880 | 8875 | |
| 8881 | 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 | 8878 | self.file, |
| 8884 | 8879 | self.scope, |
| 8885 | 8880 | lbrace_line, |
| ... | ... | @@ -9664,7 +9659,7 @@ pub const FuncGen = struct { |
| 9664 | 9659 | defer wip_switch.finish(&self.wip); |
| 9665 | 9660 | |
| 9666 | 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 | 9663 | const this_tag_int_value = try o.builder.intConst(try o.errorIntType(), err_int); |
| 9669 | 9664 | try wip_switch.addCase(this_tag_int_value, valid_block, &self.wip); |
| 9670 | 9665 | } |
| ... | ... | @@ -9702,18 +9697,19 @@ pub const FuncGen = struct { |
| 9702 | 9697 | const o = self.dg.object; |
| 9703 | 9698 | const pt = o.pt; |
| 9704 | 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()); | |
| 9706 | 9702 | |
| 9707 | 9703 | // TODO: detect when the type changes and re-emit this function. |
| 9708 | 9704 | const gop = try o.named_enum_map.getOrPut(o.gpa, enum_type.decl); |
| 9709 | 9705 | if (gop.found_existing) return gop.value_ptr.*; |
| 9710 | 9706 | errdefer assert(o.named_enum_map.remove(enum_type.decl)); |
| 9711 | 9707 | |
| 9712 | const fqn = try zcu.declPtr(enum_type.decl).fullyQualifiedName(pt); | |
| 9708 | const decl = zcu.declPtr(enum_type.decl); | |
| 9713 | 9709 | const target = zcu.root_mod.resolved_target.result; |
| 9714 | 9710 | const function_index = try o.builder.addFunction( |
| 9715 | 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 | 9713 | toLlvmAddressSpace(.generic, target), |
| 9718 | 9714 | ); |
| 9719 | 9715 |
src/codegen/spirv.zig+5-8| ... | ... | @@ -963,7 +963,7 @@ const DeclGen = struct { |
| 963 | 963 | break :cache result_id; |
| 964 | 964 | }, |
| 965 | 965 | .err => |err| { |
| 966 | const value = try mod.getErrorValue(err.name); | |
| 966 | const value = try pt.getErrorValue(err.name); | |
| 967 | 967 | break :cache try self.constInt(ty, value, repr); |
| 968 | 968 | }, |
| 969 | 969 | .error_union => |error_union| { |
| ... | ... | @@ -3012,12 +3012,11 @@ const DeclGen = struct { |
| 3012 | 3012 | // Append the actual code into the functions section. |
| 3013 | 3013 | try self.spv.addFunction(spv_decl_index, self.func); |
| 3014 | 3014 | |
| 3015 | const fqn = try decl.fullyQualifiedName(self.pt); | |
| 3016 | try self.spv.debugName(result_id, fqn.toSlice(ip)); | |
| 3015 | try self.spv.debugName(result_id, decl.fqn.toSlice(ip)); | |
| 3017 | 3016 | |
| 3018 | 3017 | // Temporarily generate a test kernel declaration if this is a test function. |
| 3019 | 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 | 3022 | .global => { |
| ... | ... | @@ -3041,8 +3040,7 @@ const DeclGen = struct { |
| 3041 | 3040 | .storage_class = final_storage_class, |
| 3042 | 3041 | }); |
| 3043 | 3042 | |
| 3044 | const fqn = try decl.fullyQualifiedName(self.pt); | |
| 3045 | try self.spv.debugName(result_id, fqn.toSlice(ip)); | |
| 3043 | try self.spv.debugName(result_id, decl.fqn.toSlice(ip)); | |
| 3046 | 3044 | try self.spv.declareDeclDeps(spv_decl_index, &.{}); |
| 3047 | 3045 | }, |
| 3048 | 3046 | .invocation_global => { |
| ... | ... | @@ -3086,8 +3084,7 @@ const DeclGen = struct { |
| 3086 | 3084 | try self.func.body.emit(self.spv.gpa, .OpFunctionEnd, {}); |
| 3087 | 3085 | try self.spv.addFunction(spv_decl_index, self.func); |
| 3088 | 3086 | |
| 3089 | const fqn = try decl.fullyQualifiedName(self.pt); | |
| 3090 | try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{fqn.fmt(ip)}); | |
| 3087 | try self.spv.debugNameFmt(initializer_id, "initializer of {}", .{decl.fqn.fmt(ip)}); | |
| 3091 | 3088 | |
| 3092 | 3089 | try self.spv.sections.types_globals_constants.emit(self.spv.gpa, .OpExtInst, .{ |
| 3093 | 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 | 1176 | gop.value_ptr.* = .{}; |
| 1177 | 1177 | } |
| 1178 | 1178 | const unnamed_consts = gop.value_ptr; |
| 1179 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1180 | 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 | 1183 | defer gpa.free(sym_name); |
| 1183 | 1184 | const ty = val.typeOf(mod); |
| 1184 | 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 | 1428 | const mod = pt.zcu; |
| 1428 | 1429 | const decl = mod.declPtr(decl_index); |
| 1429 | 1430 | |
| 1430 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1431 | ||
| 1432 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | |
| 1431 | log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(&mod.intern_pool), decl }); | |
| 1433 | 1432 | const required_alignment: u32 = @intCast(decl.getAlignment(pt).toByteUnits() orelse 0); |
| 1434 | 1433 | |
| 1435 | 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 | 1440 | |
| 1442 | 1441 | if (atom.size != 0) { |
| 1443 | 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 | 1444 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1)); |
| 1446 | 1445 | sym.type = .{ .complex_type = complex_type, .base_type = .NULL }; |
| 1447 | 1446 | |
| ... | ... | @@ -1449,7 +1448,7 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd |
| 1449 | 1448 | const need_realloc = code.len > capacity or !mem.isAlignedGeneric(u64, sym.value, required_alignment); |
| 1450 | 1449 | if (need_realloc) { |
| 1451 | 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 | 1452 | log.debug(" (required alignment 0x{x}", .{required_alignment}); |
| 1454 | 1453 | |
| 1455 | 1454 | if (vaddr != sym.value) { |
| ... | ... | @@ -1465,13 +1464,13 @@ fn updateDeclCode(self: *Coff, pt: Zcu.PerThread, decl_index: InternPool.DeclInd |
| 1465 | 1464 | self.getAtomPtr(atom_index).size = code_len; |
| 1466 | 1465 | } else { |
| 1467 | 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 | 1468 | sym.section_number = @as(coff.SectionNumber, @enumFromInt(sect_index + 1)); |
| 1470 | 1469 | sym.type = .{ .complex_type = complex_type, .base_type = .NULL }; |
| 1471 | 1470 | |
| 1472 | 1471 | const vaddr = try self.allocateAtom(atom_index, code_len, required_alignment); |
| 1473 | 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 | 1474 | self.getAtomPtr(atom_index).size = code_len; |
| 1476 | 1475 | sym.value = vaddr; |
| 1477 | 1476 |
src/link/Dwarf.zig+4-6| ... | ... | @@ -1082,9 +1082,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec |
| 1082 | 1082 | defer tracy.end(); |
| 1083 | 1083 | |
| 1084 | 1084 | const decl = pt.zcu.declPtr(decl_index); |
| 1085 | const decl_linkage_name = try decl.fullyQualifiedName(pt); | |
| 1086 | ||
| 1087 | log.debug("initDeclState {}{*}", .{ decl_linkage_name.fmt(&pt.zcu.intern_pool), decl }); | |
| 1085 | log.debug("initDeclState {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); | |
| 1088 | 1086 | |
| 1089 | 1087 | const gpa = self.allocator; |
| 1090 | 1088 | var decl_state: DeclState = .{ |
| ... | ... | @@ -1157,7 +1155,7 @@ pub fn initDeclState(self: *Dwarf, pt: Zcu.PerThread, decl_index: InternPool.Dec |
| 1157 | 1155 | |
| 1158 | 1156 | // .debug_info subprogram |
| 1159 | 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 | 1159 | try dbg_info_buffer.ensureUnusedCapacity(1 + ptr_width_bytes + 4 + 4 + |
| 1162 | 1160 | (decl_name_slice.len + 1) + (decl_linkage_name_slice.len + 1)); |
| 1163 | 1161 | |
| ... | ... | @@ -2700,7 +2698,7 @@ pub fn flushModule(self: *Dwarf, pt: Zcu.PerThread) !void { |
| 2700 | 2698 | try addDbgInfoErrorSetNames( |
| 2701 | 2699 | pt, |
| 2702 | 2700 | Type.anyerror, |
| 2703 | pt.zcu.global_error_set.keys(), | |
| 2701 | pt.zcu.intern_pool.global_error_set.getNamesFromMainThread(), | |
| 2704 | 2702 | target, |
| 2705 | 2703 | &dbg_info_buffer, |
| 2706 | 2704 | ); |
| ... | ... | @@ -2869,7 +2867,7 @@ fn addDbgInfoErrorSetNames( |
| 2869 | 2867 | mem.writeInt(u64, dbg_info_buffer.addManyAsArrayAssumeCapacity(8), 0, target_endian); |
| 2870 | 2868 | |
| 2871 | 2869 | for (error_names) |error_name| { |
| 2872 | const int = try pt.zcu.getErrorValue(error_name); | |
| 2870 | const int = try pt.getErrorValue(error_name); | |
| 2873 | 2871 | const error_name_slice = error_name.toSlice(&pt.zcu.intern_pool); |
| 2874 | 2872 | // DW.AT.enumerator |
| 2875 | 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 | 907 | ) !void { |
| 908 | 908 | const gpa = elf_file.base.comp.gpa; |
| 909 | 909 | const mod = pt.zcu; |
| 910 | const ip = &mod.intern_pool; | |
| 910 | 911 | const decl = mod.declPtr(decl_index); |
| 911 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 912 | 912 | |
| 913 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | |
| 913 | log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl }); | |
| 914 | 914 | |
| 915 | 915 | const required_alignment = decl.getAlignment(pt).max( |
| 916 | 916 | target_util.minFunctionAlignment(mod.getTarget()), |
| ... | ... | @@ -923,7 +923,7 @@ fn updateDeclCode( |
| 923 | 923 | sym.output_section_index = shdr_index; |
| 924 | 924 | atom_ptr.output_section_index = shdr_index; |
| 925 | 925 | |
| 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 | 927 | atom_ptr.flags.alive = true; |
| 928 | 928 | atom_ptr.name_offset = sym.name_offset; |
| 929 | 929 | esym.st_name = sym.name_offset; |
| ... | ... | @@ -940,7 +940,7 @@ fn updateDeclCode( |
| 940 | 940 | const need_realloc = code.len > capacity or !required_alignment.check(@intCast(atom_ptr.value)); |
| 941 | 941 | if (need_realloc) { |
| 942 | 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 | 944 | if (old_vaddr != atom_ptr.value) { |
| 945 | 945 | sym.value = 0; |
| 946 | 946 | esym.st_value = 0; |
| ... | ... | @@ -1007,11 +1007,11 @@ fn updateTlv( |
| 1007 | 1007 | code: []const u8, |
| 1008 | 1008 | ) !void { |
| 1009 | 1009 | const mod = pt.zcu; |
| 1010 | const ip = &mod.intern_pool; | |
| 1010 | 1011 | const gpa = mod.gpa; |
| 1011 | 1012 | const decl = mod.declPtr(decl_index); |
| 1012 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1013 | 1013 | |
| 1014 | log.debug("updateTlv {} ({*})", .{ decl_name.fmt(&mod.intern_pool), decl }); | |
| 1014 | log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(ip), decl }); | |
| 1015 | 1015 | |
| 1016 | 1016 | const required_alignment = decl.getAlignment(pt); |
| 1017 | 1017 | |
| ... | ... | @@ -1023,7 +1023,7 @@ fn updateTlv( |
| 1023 | 1023 | sym.output_section_index = shndx; |
| 1024 | 1024 | atom_ptr.output_section_index = shndx; |
| 1025 | 1025 | |
| 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 | 1027 | atom_ptr.flags.alive = true; |
| 1028 | 1028 | atom_ptr.name_offset = sym.name_offset; |
| 1029 | 1029 | esym.st_value = 0; |
| ... | ... | @@ -1286,9 +1286,8 @@ pub fn lowerUnnamedConst( |
| 1286 | 1286 | } |
| 1287 | 1287 | const unnamed_consts = gop.value_ptr; |
| 1288 | 1288 | const decl = mod.declPtr(decl_index); |
| 1289 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1290 | 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 | 1291 | defer gpa.free(name); |
| 1293 | 1292 | const ty = val.typeOf(mod); |
| 1294 | 1293 | const sym_index = switch (try self.lowerConst( |
| ... | ... | @@ -1473,9 +1472,8 @@ pub fn updateDeclLineNumber( |
| 1473 | 1472 | defer tracy.end(); |
| 1474 | 1473 | |
| 1475 | 1474 | const decl = pt.zcu.declPtr(decl_index); |
| 1476 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1477 | 1475 | |
| 1478 | log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl }); | |
| 1476 | log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); | |
| 1479 | 1477 | |
| 1480 | 1478 | if (self.dwarf) |*dw| { |
| 1481 | 1479 | try dw.updateDeclLineNumber(pt.zcu, decl_index); |
src/link/MachO/ZigObject.zig+10-14| ... | ... | @@ -809,10 +809,10 @@ fn updateDeclCode( |
| 809 | 809 | ) !void { |
| 810 | 810 | const gpa = macho_file.base.comp.gpa; |
| 811 | 811 | const mod = pt.zcu; |
| 812 | const ip = &mod.intern_pool; | |
| 812 | 813 | const decl = mod.declPtr(decl_index); |
| 813 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 814 | 814 | |
| 815 | log.debug("updateDeclCode {}{*}", .{ decl_name.fmt(&mod.intern_pool), decl }); | |
| 815 | log.debug("updateDeclCode {}{*}", .{ decl.fqn.fmt(ip), decl }); | |
| 816 | 816 | |
| 817 | 817 | const required_alignment = decl.getAlignment(pt); |
| 818 | 818 | |
| ... | ... | @@ -824,7 +824,7 @@ fn updateDeclCode( |
| 824 | 824 | sym.out_n_sect = sect_index; |
| 825 | 825 | atom.out_n_sect = sect_index; |
| 826 | 826 | |
| 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 | 828 | atom.flags.alive = true; |
| 829 | 829 | atom.name = sym.name; |
| 830 | 830 | nlist.n_strx = sym.name; |
| ... | ... | @@ -843,7 +843,7 @@ fn updateDeclCode( |
| 843 | 843 | |
| 844 | 844 | if (need_realloc) { |
| 845 | 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 | 847 | if (old_vaddr != atom.value) { |
| 848 | 848 | sym.value = 0; |
| 849 | 849 | nlist.n_value = 0; |
| ... | ... | @@ -893,25 +893,22 @@ fn updateTlv( |
| 893 | 893 | sect_index: u8, |
| 894 | 894 | code: []const u8, |
| 895 | 895 | ) !void { |
| 896 | const ip = &pt.zcu.intern_pool; | |
| 896 | 897 | const decl = pt.zcu.declPtr(decl_index); |
| 897 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 898 | 898 | |
| 899 | log.debug("updateTlv {} ({*})", .{ decl_name.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); | |
| 899 | log.debug("updateTlv {} ({*})", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); | |
| 903 | 900 | |
| 904 | 901 | // 1. Lower TLV initializer |
| 905 | 902 | const init_sym_index = try self.createTlvInitializer( |
| 906 | 903 | macho_file, |
| 907 | decl_name_slice, | |
| 908 | required_alignment, | |
| 904 | decl.fqn.toSlice(ip), | |
| 905 | decl.getAlignment(pt), | |
| 909 | 906 | sect_index, |
| 910 | 907 | code, |
| 911 | 908 | ); |
| 912 | 909 | |
| 913 | 910 | // 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 | } |
| 916 | 913 | |
| 917 | 914 | fn createTlvInitializer( |
| ... | ... | @@ -1099,9 +1096,8 @@ pub fn lowerUnnamedConst( |
| 1099 | 1096 | } |
| 1100 | 1097 | const unnamed_consts = gop.value_ptr; |
| 1101 | 1098 | const decl = mod.declPtr(decl_index); |
| 1102 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1103 | 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 | 1101 | defer gpa.free(name); |
| 1106 | 1102 | const sym_index = switch (try self.lowerConst( |
| 1107 | 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 | 483 | } |
| 484 | 484 | const unnamed_consts = gop.value_ptr; |
| 485 | 485 | |
| 486 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 487 | ||
| 488 | 486 | const index = unnamed_consts.items.len; |
| 489 | 487 | // 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 }); | |
| 491 | 489 | |
| 492 | 490 | const sym_index = try self.allocateSymbolIndex(); |
| 493 | 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 | 227 | var error_info = std.ArrayList(u8).init(self.object.gpa); |
| 228 | 228 | defer error_info.deinit(); |
| 229 | 229 | |
| 230 | try error_info.appendSlice("zig_errors"); | |
| 231 | const mod = self.base.comp.module.?; | |
| 232 | for (mod.global_error_set.keys()) |name| { | |
| 230 | try error_info.appendSlice("zig_errors:"); | |
| 231 | const ip = &self.base.comp.module.?.intern_pool; | |
| 232 | for (ip.global_error_set.getNamesFromMainThread()) |name| { | |
| 233 | 233 | // Errors can contain pretty much any character - to encode them in a string we must escape |
| 234 | 234 | // them somehow. Easiest here is to use some established scheme, one which also preseves the |
| 235 | 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 | 238 | try error_info.append(':'); |
| 239 | 239 | try std.Uri.Component.percentEncode( |
| 240 | 240 | error_info.writer(), |
| 241 | name.toSlice(&mod.intern_pool), | |
| 241 | name.toSlice(ip), | |
| 242 | 242 | struct { |
| 243 | 243 | fn isValidChar(c: u8) bool { |
| 244 | 244 | return switch (c) { |
src/link/Wasm/ZigObject.zig+20-16| ... | ... | @@ -346,8 +346,7 @@ fn finishUpdateDecl( |
| 346 | 346 | const atom_index = decl_info.atom; |
| 347 | 347 | const atom = wasm_file.getAtomPtr(atom_index); |
| 348 | 348 | const sym = zig_object.symbol(atom.sym_index); |
| 349 | const full_name = try decl.fullyQualifiedName(pt); | |
| 350 | sym.name = try zig_object.string_table.insert(gpa, full_name.toSlice(ip)); | |
| 349 | sym.name = try zig_object.string_table.insert(gpa, decl.fqn.toSlice(ip)); | |
| 351 | 350 | try atom.code.appendSlice(gpa, code); |
| 352 | 351 | atom.size = @intCast(code.len); |
| 353 | 352 | |
| ... | ... | @@ -387,7 +386,7 @@ fn finishUpdateDecl( |
| 387 | 386 | // Will be freed upon freeing of decl or after cleanup of Wasm binary. |
| 388 | 387 | const full_segment_name = try std.mem.concat(gpa, u8, &.{ |
| 389 | 388 | segment_name, |
| 390 | full_name.toSlice(ip), | |
| 389 | decl.fqn.toSlice(ip), | |
| 391 | 390 | }); |
| 392 | 391 | errdefer gpa.free(full_segment_name); |
| 393 | 392 | sym.tag = .data; |
| ... | ... | @@ -436,9 +435,8 @@ pub fn getOrCreateAtomForDecl( |
| 436 | 435 | const sym_index = try zig_object.allocateSymbol(gpa); |
| 437 | 436 | gop.value_ptr.* = .{ .atom = try wasm_file.createAtom(sym_index, zig_object.index) }; |
| 438 | 437 | const decl = pt.zcu.declPtr(decl_index); |
| 439 | const full_name = try decl.fullyQualifiedName(pt); | |
| 440 | 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 | 441 | return gop.value_ptr.atom; |
| 444 | 442 | } |
| ... | ... | @@ -494,9 +492,8 @@ pub fn lowerUnnamedConst( |
| 494 | 492 | const parent_atom_index = try zig_object.getOrCreateAtomForDecl(wasm_file, pt, decl_index); |
| 495 | 493 | const parent_atom = wasm_file.getAtom(parent_atom_index); |
| 496 | 494 | const local_index = parent_atom.locals.items.len; |
| 497 | const fqn = try decl.fullyQualifiedName(pt); | |
| 498 | 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 | 498 | defer gpa.free(name); |
| 502 | 499 | |
| ... | ... | @@ -655,13 +652,22 @@ fn populateErrorNameTable(zig_object: *ZigObject, wasm_file: *Wasm, tid: Zcu.Per |
| 655 | 652 | // Addend for each relocation to the table |
| 656 | 653 | var addend: u32 = 0; |
| 657 | 654 | const pt: Zcu.PerThread = .{ .zcu = wasm_file.base.comp.module.?, .tid = tid }; |
| 658 | for (pt.zcu.global_error_set.keys()) |error_name| { | |
| 659 | const atom = wasm_file.getAtomPtr(atom_index); | |
| 655 | const slice_ty = Type.slice_const_u8_sentinel_0; | |
| 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; | |
| 660 | 663 | |
| 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 | 669 | const len: u32 = @intCast(error_name_slice.len + 1); // names are 0-terminated |
| 663 | 670 | |
| 664 | const slice_ty = Type.slice_const_u8_sentinel_0; | |
| 665 | 671 | const offset = @as(u32, @intCast(atom.code.items.len)); |
| 666 | 672 | // first we create the data for the slice of the name |
| 667 | 673 | 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 | 686 | try names_atom.code.ensureUnusedCapacity(gpa, len); |
| 681 | 687 | names_atom.code.appendSliceAssumeCapacity(error_name_slice[0..len]); |
| 682 | 688 | |
| 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 | 691 | names_atom.size = addend; |
| 686 | 692 | zig_object.error_names_atom = names_atom_index; |
| ... | ... | @@ -1045,7 +1051,7 @@ fn setupErrorsLen(zig_object: *ZigObject, wasm_file: *Wasm) !void { |
| 1045 | 1051 | const gpa = wasm_file.base.comp.gpa; |
| 1046 | 1052 | const sym_index = zig_object.findGlobalSymbol("__zig_errors_len") orelse return; |
| 1047 | 1053 | |
| 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 | 1055 | // overwrite existing atom if it already exists (maybe the error set has increased) |
| 1050 | 1056 | // if not, allcoate a new atom. |
| 1051 | 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 | 1133 | ) !void { |
| 1128 | 1134 | if (zig_object.dwarf) |*dw| { |
| 1129 | 1135 | const decl = pt.zcu.declPtr(decl_index); |
| 1130 | const decl_name = try decl.fullyQualifiedName(pt); | |
| 1131 | ||
| 1132 | log.debug("updateDeclLineNumber {}{*}", .{ decl_name.fmt(&pt.zcu.intern_pool), decl }); | |
| 1136 | log.debug("updateDeclLineNumber {}{*}", .{ decl.fqn.fmt(&pt.zcu.intern_pool), decl }); | |
| 1133 | 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 | 356 | fn writeArg(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { |
| 357 | 357 | const arg = w.air.instructions.items(.data)[@intFromEnum(inst)].arg; |
| 358 | 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 | } |
| 361 | 367 | |
| 362 | 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 | 299 | int.ptr_ty.fmt(pt), |
| 300 | 300 | int.addr, |
| 301 | 301 | }), |
| 302 | .decl_ptr => |decl| { | |
| 303 | try zcu.declPtr(decl).renderFullyQualifiedName(zcu, writer); | |
| 302 | .decl_ptr => |decl_index| { | |
| 303 | try writer.print("{}", .{zcu.declPtr(decl_index).fqn.fmt(ip)}); | |
| 304 | 304 | }, |
| 305 | 305 | .anon_decl_ptr => |anon| { |
| 306 | 306 | const ty = Value.fromInterned(anon.val).typeOf(zcu); |