aboutsummaryrefslogtreecommitdiff
path: root/src/Package/Module.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/Package/Module.zig')
-rw-r--r--src/Package/Module.zig40
1 files changed, 37 insertions, 3 deletions
diff --git a/src/Package/Module.zig b/src/Package/Module.zig
index 6fadbf1dd5..c6eb1e8c90 100644
--- a/src/Package/Module.zig
+++ b/src/Package/Module.zig
@@ -63,6 +63,11 @@ pub const CreateOptions = struct {
builtin_mod: ?*Package.Module,
+ /// Allocated into the given `arena`. Should be shared across all module creations in a Compilation.
+ /// Ignored if `builtin_mod` is passed or if `!have_zcu`.
+ /// Otherwise, may be `null` only if this Compilation consists of a single module.
+ builtin_modules: ?*std.StringHashMapUnmanaged(*Module),
+
pub const Paths = struct {
root: Package.Path,
/// Relative to `root`. May contain path separators.
@@ -364,11 +369,37 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.wasi_exec_model = options.global.wasi_exec_model,
}, arena);
+ const new = if (options.builtin_modules) |builtins| new: {
+ const gop = try builtins.getOrPut(arena, generated_builtin_source);
+ if (gop.found_existing) break :b gop.value_ptr.*;
+ errdefer builtins.removeByPtr(gop.key_ptr);
+ const new = try arena.create(Module);
+ gop.value_ptr.* = new;
+ break :new new;
+ } else try arena.create(Module);
+ errdefer if (options.builtin_modules) |builtins| assert(builtins.remove(generated_builtin_source));
+
const new_file = try arena.create(File);
- const digest = Cache.HashHelper.oneShot(generated_builtin_source);
- const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ digest);
- const new = try arena.create(Module);
+ const bin_digest, const hex_digest = digest: {
+ var hasher: Cache.Hasher = Cache.hasher_init;
+ hasher.update(generated_builtin_source);
+
+ var bin_digest: Cache.BinDigest = undefined;
+ hasher.final(&bin_digest);
+
+ var hex_digest: Cache.HexDigest = undefined;
+ _ = std.fmt.bufPrint(
+ &hex_digest,
+ "{s}",
+ .{std.fmt.fmtSliceHexLower(&bin_digest)},
+ ) catch unreachable;
+
+ break :digest .{ bin_digest, hex_digest };
+ };
+
+ const builtin_sub_path = try arena.dupe(u8, "b" ++ std.fs.path.sep_str ++ hex_digest);
+
new.* = .{
.root = .{
.root_dir = options.global_cache_directory,
@@ -415,6 +446,9 @@ pub fn create(arena: Allocator, options: CreateOptions) !*Package.Module {
.status = .never_loaded,
.mod = new,
.root_decl = .none,
+ // We might as well use this digest for the File `path digest`, since there's a
+ // one-to-one correspondence here between distinct paths and distinct contents.
+ .path_digest = bin_digest,
};
break :b new;
};