| ... | @@ -1571,6 +1571,13 @@ pub const EmbedFile = struct { | ... | @@ -1571,6 +1571,13 @@ pub const EmbedFile = struct { |
| 1571 | /// This is how zig knows what other Decl objects to invalidate if the file | 1571 | /// This is how zig knows what other Decl objects to invalidate if the file |
| 1572 | /// changes on disk. | 1572 | /// changes on disk. |
| 1573 | owner_decl: *Decl, | 1573 | owner_decl: *Decl, |
| | 1574 | |
| | 1575 | fn destroy(embed_file: *EmbedFile, mod: *Module) void { |
| | 1576 | const gpa = mod.gpa; |
| | 1577 | gpa.free(embed_file.sub_file_path); |
| | 1578 | gpa.free(embed_file.bytes); |
| | 1579 | gpa.destroy(embed_file); |
| | 1580 | } |
| 1574 | }; | 1581 | }; |
| 1575 | | 1582 | |
| 1576 | /// This struct holds data necessary to construct API-facing `AllErrors.Message`. | 1583 | /// This struct holds data necessary to construct API-facing `AllErrors.Message`. |
| ... | @@ -2359,6 +2366,15 @@ pub fn deinit(mod: *Module) void { | ... | @@ -2359,6 +2366,15 @@ pub fn deinit(mod: *Module) void { |
| 2359 | } | 2366 | } |
| 2360 | mod.import_table.deinit(gpa); | 2367 | mod.import_table.deinit(gpa); |
| 2361 | | 2368 | |
| | 2369 | { |
| | 2370 | var it = mod.embed_table.iterator(); |
| | 2371 | while (it.next()) |entry| { |
| | 2372 | gpa.free(entry.key_ptr.*); |
| | 2373 | entry.value_ptr.*.destroy(mod); |
| | 2374 | } |
| | 2375 | mod.embed_table.deinit(gpa); |
| | 2376 | } |
| | 2377 | |
| 2362 | mod.deletion_set.deinit(gpa); | 2378 | mod.deletion_set.deinit(gpa); |
| 2363 | | 2379 | |
| 2364 | // The callsite of `Compilation.create` owns the `main_pkg`, however | 2380 | // The callsite of `Compilation.create` owns the `main_pkg`, however |
| ... | @@ -3642,7 +3658,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -3642,7 +3658,7 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 3642 | | 3658 | |
| 3643 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); | 3659 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); |
| 3644 | if (gop.found_existing) return gop.value_ptr.*; | 3660 | if (gop.found_existing) return gop.value_ptr.*; |
| 3645 | keep_resolved_path = true; // It's now owned by embed_table. | 3661 | errdefer assert(mod.embed_table.remove(resolved_path)); |
| 3646 | | 3662 | |
| 3647 | const new_file = try gpa.create(EmbedFile); | 3663 | const new_file = try gpa.create(EmbedFile); |
| 3648 | errdefer gpa.destroy(new_file); | 3664 | errdefer gpa.destroy(new_file); |
| ... | @@ -3663,11 +3679,13 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -3663,11 +3679,13 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 3663 | const stat = try file.stat(); | 3679 | const stat = try file.stat(); |
| 3664 | const size_usize = try std.math.cast(usize, stat.size); | 3680 | const size_usize = try std.math.cast(usize, stat.size); |
| 3665 | const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0); | 3681 | const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0); |
| | 3682 | errdefer gpa.free(bytes); |
| 3666 | | 3683 | |
| 3667 | log.debug("new embedFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, rel_file_path={s}", .{ | 3684 | log.debug("new embedFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, rel_file_path={s}", .{ |
| 3668 | resolved_root_path, resolved_path, sub_file_path, rel_file_path, | 3685 | resolved_root_path, resolved_path, sub_file_path, rel_file_path, |
| 3669 | }); | 3686 | }); |
| 3670 | | 3687 | |
| | 3688 | keep_resolved_path = true; // It's now owned by embed_table. |
| 3671 | gop.value_ptr.* = new_file; | 3689 | gop.value_ptr.* = new_file; |
| 3672 | new_file.* = .{ | 3690 | new_file.* = .{ |
| 3673 | .sub_file_path = sub_file_path, | 3691 | .sub_file_path = sub_file_path, |