| ... | @@ -4865,14 +4865,31 @@ pub fn importFile( | ... | @@ -4865,14 +4865,31 @@ pub fn importFile( |
| 4865 | }; | 4865 | }; |
| 4866 | } | 4866 | } |
| 4867 | | 4867 | |
| 4868 | pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*EmbedFile { | 4868 | pub fn embedFile(mod: *Module, cur_file: *File, import_string: []const u8) !*EmbedFile { |
| 4869 | const gpa = mod.gpa; | 4869 | const gpa = mod.gpa; |
| 4870 | | 4870 | |
| 4871 | // The resolved path is used as the key in the table, to detect if | 4871 | if (cur_file.pkg.table.get(import_string)) |pkg| { |
| 4872 | // a file refers to the same as another, despite different relative paths. | 4872 | const resolved_path = try std.fs.path.resolve(gpa, &[_][]const u8{ |
| | 4873 | pkg.root_src_directory.path orelse ".", pkg.root_src_path, |
| | 4874 | }); |
| | 4875 | var keep_resolved_path = false; |
| | 4876 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| | 4877 | |
| | 4878 | const gop = try mod.embed_table.getOrPut(gpa, resolved_path); |
| | 4879 | errdefer assert(mod.embed_table.remove(resolved_path)); |
| | 4880 | if (gop.found_existing) return gop.value_ptr.*; |
| | 4881 | |
| | 4882 | const sub_file_path = try gpa.dupe(u8, pkg.root_src_path); |
| | 4883 | errdefer gpa.free(sub_file_path); |
| | 4884 | |
| | 4885 | return newEmbedFile(mod, pkg, sub_file_path, resolved_path, &keep_resolved_path, gop); |
| | 4886 | } |
| | 4887 | |
| | 4888 | // The resolved path is used as the key in the table, to detect if a file |
| | 4889 | // refers to the same as another, despite different relative paths. |
| 4873 | const cur_pkg_dir_path = cur_file.pkg.root_src_directory.path orelse "."; | 4890 | const cur_pkg_dir_path = cur_file.pkg.root_src_directory.path orelse "."; |
| 4874 | const resolved_path = try std.fs.path.resolve(gpa, &[_][]const u8{ | 4891 | const resolved_path = try std.fs.path.resolve(gpa, &[_][]const u8{ |
| 4875 | cur_pkg_dir_path, cur_file.sub_file_path, "..", rel_file_path, | 4892 | cur_pkg_dir_path, cur_file.sub_file_path, "..", import_string, |
| 4876 | }); | 4893 | }); |
| 4877 | var keep_resolved_path = false; | 4894 | var keep_resolved_path = false; |
| 4878 | defer if (!keep_resolved_path) gpa.free(resolved_path); | 4895 | defer if (!keep_resolved_path) gpa.free(resolved_path); |
| ... | @@ -4881,9 +4898,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -4881,9 +4898,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4881 | errdefer assert(mod.embed_table.remove(resolved_path)); | 4898 | errdefer assert(mod.embed_table.remove(resolved_path)); |
| 4882 | if (gop.found_existing) return gop.value_ptr.*; | 4899 | if (gop.found_existing) return gop.value_ptr.*; |
| 4883 | | 4900 | |
| 4884 | const new_file = try gpa.create(EmbedFile); | | |
| 4885 | errdefer gpa.destroy(new_file); | | |
| 4886 | | | |
| 4887 | const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); | 4901 | const resolved_root_path = try std.fs.path.resolve(gpa, &[_][]const u8{cur_pkg_dir_path}); |
| 4888 | defer gpa.free(resolved_root_path); | 4902 | defer gpa.free(resolved_root_path); |
| 4889 | | 4903 | |
| ... | @@ -4902,7 +4916,23 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -4902,7 +4916,23 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4902 | }; | 4916 | }; |
| 4903 | errdefer gpa.free(sub_file_path); | 4917 | errdefer gpa.free(sub_file_path); |
| 4904 | | 4918 | |
| 4905 | var file = try cur_file.pkg.root_src_directory.handle.openFile(sub_file_path, .{}); | 4919 | return newEmbedFile(mod, cur_file.pkg, sub_file_path, resolved_path, &keep_resolved_path, gop); |
| | 4920 | } |
| | 4921 | |
| | 4922 | fn newEmbedFile( |
| | 4923 | mod: *Module, |
| | 4924 | pkg: *Package, |
| | 4925 | sub_file_path: []const u8, |
| | 4926 | resolved_path: []const u8, |
| | 4927 | keep_resolved_path: *bool, |
| | 4928 | gop: std.StringHashMapUnmanaged(*EmbedFile).GetOrPutResult, |
| | 4929 | ) !*EmbedFile { |
| | 4930 | const gpa = mod.gpa; |
| | 4931 | |
| | 4932 | const new_file = try gpa.create(EmbedFile); |
| | 4933 | errdefer gpa.destroy(new_file); |
| | 4934 | |
| | 4935 | var file = try pkg.root_src_directory.handle.openFile(sub_file_path, .{}); |
| 4906 | defer file.close(); | 4936 | defer file.close(); |
| 4907 | | 4937 | |
| 4908 | const actual_stat = try file.stat(); | 4938 | const actual_stat = try file.stat(); |
| ... | @@ -4915,10 +4945,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -4915,10 +4945,6 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4915 | const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0); | 4945 | const bytes = try file.readToEndAllocOptions(gpa, std.math.maxInt(u32), size_usize, 1, 0); |
| 4916 | errdefer gpa.free(bytes); | 4946 | errdefer gpa.free(bytes); |
| 4917 | | 4947 | |
| 4918 | log.debug("new embedFile. resolved_root_path={s}, resolved_path={s}, sub_file_path={s}, rel_file_path={s}", .{ | | |
| 4919 | resolved_root_path, resolved_path, sub_file_path, rel_file_path, | | |
| 4920 | }); | | |
| 4921 | | | |
| 4922 | if (mod.comp.whole_cache_manifest) |whole_cache_manifest| { | 4948 | if (mod.comp.whole_cache_manifest) |whole_cache_manifest| { |
| 4923 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); | 4949 | const copied_resolved_path = try gpa.dupe(u8, resolved_path); |
| 4924 | errdefer gpa.free(copied_resolved_path); | 4950 | errdefer gpa.free(copied_resolved_path); |
| ... | @@ -4927,13 +4953,13 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb | ... | @@ -4927,13 +4953,13 @@ pub fn embedFile(mod: *Module, cur_file: *File, rel_file_path: []const u8) !*Emb |
| 4927 | try whole_cache_manifest.addFilePostContents(copied_resolved_path, bytes, stat); | 4953 | try whole_cache_manifest.addFilePostContents(copied_resolved_path, bytes, stat); |
| 4928 | } | 4954 | } |
| 4929 | | 4955 | |
| 4930 | keep_resolved_path = true; // It's now owned by embed_table. | 4956 | keep_resolved_path.* = true; // It's now owned by embed_table. |
| 4931 | gop.value_ptr.* = new_file; | 4957 | gop.value_ptr.* = new_file; |
| 4932 | new_file.* = .{ | 4958 | new_file.* = .{ |
| 4933 | .sub_file_path = sub_file_path, | 4959 | .sub_file_path = sub_file_path, |
| 4934 | .bytes = bytes, | 4960 | .bytes = bytes, |
| 4935 | .stat = stat, | 4961 | .stat = stat, |
| 4936 | .pkg = cur_file.pkg, | 4962 | .pkg = pkg, |
| 4937 | .owner_decl = undefined, // Set by Sema immediately after this function returns. | 4963 | .owner_decl = undefined, // Set by Sema immediately after this function returns. |
| 4938 | }; | 4964 | }; |
| 4939 | return new_file; | 4965 | return new_file; |