authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-12-18 17:10:28-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-01 17:51:20-07:00
logfe87bae7e39657c96015aa7f3c7a35a0b01da1ad
tree1f5bfe4101613eebe88713d0ba7d8cba3c0f8b79
parent90cc408c1479e5e7ccd82369253d19f79d2812a5

frontend: fix handling of special builtin module

it's allocated differently and imported differently

4 files changed, 51 insertions(+), 42 deletions(-)

src/Builtin.zig+5-1
...@@ -266,11 +266,14 @@ pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void {...@@ -266,11 +266,14 @@ pub fn populateFile(comp: *Compilation, mod: *Module, file: *File) !void {
266 else => |e| return e,266 else => |e| return e,
267 }267 }
268268
269 log.debug("parsing and generating '{s}'", .{mod.root_src_path});
270
269 file.tree = try std.zig.Ast.parse(comp.gpa, file.source, .zig);271 file.tree = try std.zig.Ast.parse(comp.gpa, file.source, .zig);
270 file.tree_loaded = true;
271 assert(file.tree.errors.len == 0); // builtin.zig must parse272 assert(file.tree.errors.len == 0); // builtin.zig must parse
273 file.tree_loaded = true;
272274
273 file.zir = try AstGen.generate(comp.gpa, file.tree);275 file.zir = try AstGen.generate(comp.gpa, file.tree);
276 assert(!file.zir.hasCompileErrors()); // builtin.zig must not have astgen errors
274 file.zir_loaded = true;277 file.zir_loaded = true;
275 file.status = .success_zir;278 file.status = .success_zir;
276}279}
...@@ -296,3 +299,4 @@ const assert = std.debug.assert;...@@ -296,3 +299,4 @@ const assert = std.debug.assert;
296const AstGen = @import("AstGen.zig");299const AstGen = @import("AstGen.zig");
297const File = @import("Module.zig").File;300const File = @import("Module.zig").File;
298const Compilation = @import("Compilation.zig");301const Compilation = @import("Compilation.zig");
302const log = std.log.scoped(.builtin);
src/Module.zig+44-20
...@@ -14,7 +14,9 @@ const BigIntMutable = std.math.big.int.Mutable;...@@ -14,7 +14,9 @@ const BigIntMutable = std.math.big.int.Mutable;
14const Target = std.Target;14const Target = std.Target;
15const Ast = std.zig.Ast;15const Ast = std.zig.Ast;
1616
17const Module = @This();17/// Deprecated, use `Zcu`.
18const Module = Zcu;
19const Zcu = @This();
18const Compilation = @import("Compilation.zig");20const Compilation = @import("Compilation.zig");
19const Cache = std.Build.Cache;21const Cache = std.Build.Cache;
20const Value = @import("value.zig").Value;22const Value = @import("value.zig").Value;
...@@ -947,15 +949,21 @@ pub const File = struct {...@@ -947,15 +949,21 @@ pub const File = struct {
947949
948 pub fn deinit(file: *File, mod: *Module) void {950 pub fn deinit(file: *File, mod: *Module) void {
949 const gpa = mod.gpa;951 const gpa = mod.gpa;
952 const is_builtin = file.mod.isBuiltin();
950 log.debug("deinit File {s}", .{file.sub_file_path});953 log.debug("deinit File {s}", .{file.sub_file_path});
954 if (is_builtin) {
955 file.unloadTree(gpa);
956 file.unloadZir(gpa);
957 } else {
958 gpa.free(file.sub_file_path);
959 file.unload(gpa);
960 }
951 file.deleted_decls.deinit(gpa);961 file.deleted_decls.deinit(gpa);
952 file.outdated_decls.deinit(gpa);962 file.outdated_decls.deinit(gpa);
953 file.references.deinit(gpa);963 file.references.deinit(gpa);
954 if (file.root_decl.unwrap()) |root_decl| {964 if (file.root_decl.unwrap()) |root_decl| {
955 mod.destroyDecl(root_decl);965 mod.destroyDecl(root_decl);
956 }966 }
957 gpa.free(file.sub_file_path);
958 file.unload(gpa);
959 if (file.prev_zir) |prev_zir| {967 if (file.prev_zir) |prev_zir| {
960 prev_zir.deinit(gpa);968 prev_zir.deinit(gpa);
961 gpa.destroy(prev_zir);969 gpa.destroy(prev_zir);
...@@ -1017,8 +1025,9 @@ pub const File = struct {...@@ -1017,8 +1025,9 @@ pub const File = struct {
10171025
1018 pub fn destroy(file: *File, mod: *Module) void {1026 pub fn destroy(file: *File, mod: *Module) void {
1019 const gpa = mod.gpa;1027 const gpa = mod.gpa;
1028 const is_builtin = file.mod.isBuiltin();
1020 file.deinit(mod);1029 file.deinit(mod);
1021 gpa.destroy(file);1030 if (!is_builtin) gpa.destroy(file);
1022 }1031 }
10231032
1024 pub fn renderFullyQualifiedName(file: File, writer: anytype) !void {1033 pub fn renderFullyQualifiedName(file: File, writer: anytype) !void {
...@@ -3408,6 +3417,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {...@@ -3408,6 +3417,9 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
3408 if (file.root_decl != .none) return;3417 if (file.root_decl != .none) return;
34093418
3410 const gpa = mod.gpa;3419 const gpa = mod.gpa;
3420 log.debug("semaFile mod={s} sub_file_path={s}", .{
3421 file.mod.fully_qualified_name, file.sub_file_path,
3422 });
34113423
3412 // Because these three things each reference each other, `undefined`3424 // Because these three things each reference each other, `undefined`
3413 // placeholders are used before being set after the struct type gains an3425 // placeholders are used before being set after the struct type gains an
...@@ -3523,6 +3535,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -3523,6 +3535,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3523 defer tracy.end();3535 defer tracy.end();
35243536
3525 const decl = mod.declPtr(decl_index);3537 const decl = mod.declPtr(decl_index);
3538 const ip = &mod.intern_pool;
35263539
3527 if (decl.getFileScope(mod).status != .success_zir) {3540 if (decl.getFileScope(mod).status != .success_zir) {
3528 return error.AnalysisFail;3541 return error.AnalysisFail;
...@@ -3532,7 +3545,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -3532,7 +3545,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3532 const zir = decl.getFileScope(mod).zir;3545 const zir = decl.getFileScope(mod).zir;
3533 const zir_datas = zir.instructions.items(.data);3546 const zir_datas = zir.instructions.items(.data);
35343547
3535 // TODO: figure out how this works under incremental changes to builtin.zig!
3536 const builtin_type_target_index: InternPool.Index = blk: {3548 const builtin_type_target_index: InternPool.Index = blk: {
3537 const std_mod = mod.std_mod;3549 const std_mod = mod.std_mod;
3538 if (decl.getFileScope(mod).mod != std_mod) break :blk .none;3550 if (decl.getFileScope(mod).mod != std_mod) break :blk .none;
...@@ -3540,12 +3552,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -3540,12 +3552,11 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3540 const std_file = (try mod.importPkg(std_mod)).file;3552 const std_file = (try mod.importPkg(std_mod)).file;
3541 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);3553 const std_decl = mod.declPtr(std_file.root_decl.unwrap().?);
3542 const std_namespace = std_decl.getInnerNamespace(mod).?;3554 const std_namespace = std_decl.getInnerNamespace(mod).?;
3543 const builtin_str = try mod.intern_pool.getOrPutString(gpa, "builtin");3555 const builtin_str = try ip.getOrPutString(gpa, "builtin");
3544 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none);3556 const builtin_decl = mod.declPtr(std_namespace.decls.getKeyAdapted(builtin_str, DeclAdapter{ .mod = mod }) orelse break :blk .none);
3545 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;3557 const builtin_namespace = builtin_decl.getInnerNamespaceIndex(mod).unwrap() orelse break :blk .none;
3546 if (decl.src_namespace != builtin_namespace) break :blk .none;3558 if (decl.src_namespace != builtin_namespace) break :blk .none;
3547 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.3559 // We're in builtin.zig. This could be a builtin we need to add to a specific InternPool index.
3548 const decl_name = mod.intern_pool.stringToSlice(decl.name);
3549 for ([_]struct { []const u8, InternPool.Index }{3560 for ([_]struct { []const u8, InternPool.Index }{
3550 .{ "AtomicOrder", .atomic_order_type },3561 .{ "AtomicOrder", .atomic_order_type },
3551 .{ "AtomicRmwOp", .atomic_rmw_op_type },3562 .{ "AtomicRmwOp", .atomic_rmw_op_type },
...@@ -3559,6 +3570,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -3559,6 +3570,7 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3559 .{ "ExternOptions", .extern_options_type },3570 .{ "ExternOptions", .extern_options_type },
3560 .{ "Type", .type_info_type },3571 .{ "Type", .type_info_type },
3561 }) |pair| {3572 }) |pair| {
3573 const decl_name = ip.stringToSlice(decl.name);
3562 if (std.mem.eql(u8, decl_name, pair[0])) {3574 if (std.mem.eql(u8, decl_name, pair[0])) {
3563 break :blk pair[1];3575 break :blk pair[1];
3564 }3576 }
...@@ -3654,7 +3666,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {...@@ -3654,7 +3666,6 @@ fn semaDecl(mod: *Module, decl_index: Decl.Index) !bool {
3654 return true;3666 return true;
3655 }3667 }
36563668
3657 const ip = &mod.intern_pool;
3658 switch (ip.indexToKey(decl_tv.val.toIntern())) {3669 switch (ip.indexToKey(decl_tv.val.toIntern())) {
3659 .func => |func| {3670 .func => |func| {
3660 const owns_tv = func.owner_decl == decl_index;3671 const owns_tv = func.owner_decl == decl_index;
...@@ -3798,25 +3809,24 @@ pub const ImportFileResult = struct {...@@ -3798,25 +3809,24 @@ pub const ImportFileResult = struct {
3798 is_pkg: bool,3809 is_pkg: bool,
3799};3810};
38003811
3801/// https://github.com/ziglang/zig/issues/143073812pub fn importPkg(zcu: *Zcu, mod: *Package.Module) !ImportFileResult {
3802pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {3813 const gpa = zcu.gpa;
3803 const gpa = mod.gpa;
38043814
3805 // The resolved path is used as the key in the import table, to detect if3815 // The resolved path is used as the key in the import table, to detect if
3806 // an import refers to the same as another, despite different relative paths3816 // an import refers to the same as another, despite different relative paths
3807 // or differently mapped package names.3817 // or differently mapped package names.
3808 const resolved_path = try std.fs.path.resolve(gpa, &.{3818 const resolved_path = try std.fs.path.resolve(gpa, &.{
3809 pkg.root.root_dir.path orelse ".",3819 mod.root.root_dir.path orelse ".",
3810 pkg.root.sub_path,3820 mod.root.sub_path,
3811 pkg.root_src_path,3821 mod.root_src_path,
3812 });3822 });
3813 var keep_resolved_path = false;3823 var keep_resolved_path = false;
3814 defer if (!keep_resolved_path) gpa.free(resolved_path);3824 defer if (!keep_resolved_path) gpa.free(resolved_path);
38153825
3816 const gop = try mod.import_table.getOrPut(gpa, resolved_path);3826 const gop = try zcu.import_table.getOrPut(gpa, resolved_path);
3817 errdefer _ = mod.import_table.pop();3827 errdefer _ = zcu.import_table.pop();
3818 if (gop.found_existing) {3828 if (gop.found_existing) {
3819 try gop.value_ptr.*.addReference(mod.*, .{ .root = pkg });3829 try gop.value_ptr.*.addReference(zcu.*, .{ .root = mod });
3820 return ImportFileResult{3830 return ImportFileResult{
3821 .file = gop.value_ptr.*,3831 .file = gop.value_ptr.*,
3822 .is_new = false,3832 .is_new = false,
...@@ -3824,7 +3834,18 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {...@@ -3824,7 +3834,18 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {
3824 };3834 };
3825 }3835 }
38263836
3827 const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);3837 if (mod.builtin_file) |builtin_file| {
3838 keep_resolved_path = true; // It's now owned by import_table.
3839 gop.value_ptr.* = builtin_file;
3840 try builtin_file.addReference(zcu.*, .{ .root = mod });
3841 return .{
3842 .file = builtin_file,
3843 .is_new = false,
3844 .is_pkg = true,
3845 };
3846 }
3847
3848 const sub_file_path = try gpa.dupe(u8, mod.root_src_path);
3828 errdefer gpa.free(sub_file_path);3849 errdefer gpa.free(sub_file_path);
38293850
3830 const new_file = try gpa.create(File);3851 const new_file = try gpa.create(File);
...@@ -3842,10 +3863,10 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {...@@ -3842,10 +3863,10 @@ pub fn importPkg(mod: *Module, pkg: *Package.Module) !ImportFileResult {
3842 .tree = undefined,3863 .tree = undefined,
3843 .zir = undefined,3864 .zir = undefined,
3844 .status = .never_loaded,3865 .status = .never_loaded,
3845 .mod = pkg,3866 .mod = mod,
3846 .root_decl = .none,3867 .root_decl = .none,
3847 };3868 };
3848 try new_file.addReference(mod.*, .{ .root = pkg });3869 try new_file.addReference(zcu.*, .{ .root = mod });
3849 return ImportFileResult{3870 return ImportFileResult{
3850 .file = new_file,3871 .file = new_file,
3851 .is_new = true,3872 .is_new = true,
...@@ -4267,6 +4288,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err...@@ -4267,6 +4288,9 @@ fn scanDecl(iter: *ScanDeclIter, decl_sub_index: usize, flags: u4) Allocator.Err
4267 },4288 },
4268 };4289 };
4269 if (want_analysis) {4290 if (want_analysis) {
4291 log.debug("scanDecl queue analyze_decl file='{s}' decl_name='{s}' decl_index={d}", .{
4292 namespace.file_scope.sub_file_path, ip.stringToSlice(decl_name), new_decl_index,
4293 });
4270 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });4294 comp.work_queue.writeItemAssumeCapacity(.{ .analyze_decl = new_decl_index });
4271 }4295 }
4272 new_decl.is_pub = is_pub;4296 new_decl.is_pub = is_pub;
src/codegen.zig+1-4
...@@ -119,10 +119,7 @@ pub fn generateLazySymbol(...@@ -119,10 +119,7 @@ pub fn generateLazySymbol(
119119
120 const comp = bin_file.comp;120 const comp = bin_file.comp;
121 const zcu = comp.module.?;121 const zcu = comp.module.?;
122 const decl_index = lazy_sym.ty.getOwnerDecl(zcu);122 const target = comp.root_mod.resolved_target.result;
123 const decl = zcu.declPtr(decl_index);
124 const namespace = zcu.namespacePtr(decl.src_namespace);
125 const target = namespace.file_scope.mod.resolved_target.result;
126 const endian = target.cpu.arch.endian();123 const endian = target.cpu.arch.endian();
127 const gpa = comp.gpa;124 const gpa = comp.gpa;
128125
src/main.zig+1-17
...@@ -2662,23 +2662,7 @@ fn buildOutputType(...@@ -2662,23 +2662,7 @@ fn buildOutputType(
2662 const std_mod = m: {2662 const std_mod = m: {
2663 if (main_mod_is_std) break :m main_mod;2663 if (main_mod_is_std) break :m main_mod;
2664 if (create_module.modules.get("std")) |cli_mod| break :m cli_mod.resolved.?;2664 if (create_module.modules.get("std")) |cli_mod| break :m cli_mod.resolved.?;
26652665 break :m null;
2666 break :m try Package.Module.create(arena, .{
2667 .global_cache_directory = global_cache_directory,
2668 .paths = .{
2669 .root = .{
2670 .root_dir = zig_lib_directory,
2671 .sub_path = "std",
2672 },
2673 .root_src_path = "std.zig",
2674 },
2675 .fully_qualified_name = "std",
2676 .cc_argv = &.{},
2677 .inherited = .{},
2678 .global = create_module.resolved_options,
2679 .parent = main_mod,
2680 .builtin_mod = main_mod.getBuiltinDependency(),
2681 });
2682 };2666 };
26832667
2684 const root_mod = if (arg_mode == .zig_test) root_mod: {2668 const root_mod = if (arg_mode == .zig_test) root_mod: {