aboutsummaryrefslogtreecommitdiff
path: root/src/resolver
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/resolver/dir_info.zig4
-rw-r--r--src/resolver/package_json.zig90
-rw-r--r--src/resolver/resolver.zig243
3 files changed, 188 insertions, 149 deletions
diff --git a/src/resolver/dir_info.zig b/src/resolver/dir_info.zig
index 3ae75d0e7..66d589cfa 100644
--- a/src/resolver/dir_info.zig
+++ b/src/resolver/dir_info.zig
@@ -85,7 +85,7 @@ pub fn getEntries(dirinfo: *const DirInfo) ?*Fs.FileSystem.DirEntry {
var entries_ptr = Fs.FileSystem.instance.fs.entries.atIndex(dirinfo.entries) orelse return null;
switch (entries_ptr.*) {
.entries => {
- return &entries_ptr.entries;
+ return entries_ptr.entries;
},
.err => {
return null;
@@ -97,7 +97,7 @@ pub fn getEntriesConst(dirinfo: *const DirInfo) ?*const Fs.FileSystem.DirEntry {
const entries_ptr = Fs.FileSystem.instance.fs.entries.atIndex(dirinfo.entries) orelse return null;
switch (entries_ptr.*) {
.entries => {
- return &entries_ptr.entries;
+ return entries_ptr.entries;
},
.err => {
return null;
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig
index 4b55faa88..ce9695008 100644
--- a/src/resolver/package_json.zig
+++ b/src/resolver/package_json.zig
@@ -22,8 +22,8 @@ const js_lexer = bun.js_lexer;
const resolve_path = @import("./resolve_path.zig");
// Assume they're not going to have hundreds of main fields or browser map
// so use an array-backed hash table instead of bucketed
-const MainFieldMap = bun.StringArrayHashMap(string);
-pub const BrowserMap = bun.StringArrayHashMap(string);
+const MainFieldMap = bun.StringMap;
+pub const BrowserMap = bun.StringMap;
pub const MacroImportReplacementMap = bun.StringArrayHashMap(string);
pub const MacroMap = bun.StringArrayHashMapUnmanaged(MacroImportReplacementMap);
@@ -588,7 +588,12 @@ pub const PackageJSON = struct {
const package_json_path_ = r.fs.abs(&parts);
const package_json_path = r.fs.dirname_store.append(@TypeOf(package_json_path_), package_json_path_) catch unreachable;
- const entry = r.caches.fs.readFile(
+ // DirInfo cache is reused globally
+ // So we cannot free these
+ const allocator = bun.fs_allocator;
+
+ const entry = r.caches.fs.readFileWithAllocator(
+ allocator,
r.fs,
package_json_path,
dirname_fd,
@@ -596,12 +601,18 @@ pub const PackageJSON = struct {
null,
) catch |err| {
if (err != error.IsDir) {
- r.log.addErrorFmt(null, logger.Loc.Empty, r.allocator, "Cannot read file \"{s}\": {s}", .{ r.prettyPath(fs.Path.init(input_path)), @errorName(err) }) catch unreachable;
+ r.log.addErrorFmt(null, logger.Loc.Empty, allocator, "Cannot read file \"{s}\": {s}", .{ r.prettyPath(fs.Path.init(input_path)), @errorName(err) }) catch unreachable;
}
return null;
};
+ defer {
+ if (entry.fd != 0) {
+ _ = bun.JSC.Node.Syscall.close(entry.fd);
+ }
+ }
+
if (r.debug_logs) |*debug| {
debug.addNoteFmt("The file \"{s}\" exists", .{package_json_path});
}
@@ -611,21 +622,28 @@ pub const PackageJSON = struct {
var json_source = logger.Source.initPathString(key_path.text, entry.contents);
json_source.path.pretty = r.prettyPath(json_source.path);
- const json: js_ast.Expr = (r.caches.json.parseJSON(r.log, json_source, r.allocator) catch |err| {
+ const json: js_ast.Expr = (r.caches.json.parseJSON(r.log, json_source, allocator) catch |err| {
if (Environment.isDebug) {
Output.printError("{s}: JSON parse error: {s}", .{ package_json_path, @errorName(err) });
}
return null;
} orelse return null);
+ if (json.data != .e_object) {
+ // Invalid package.json in node_modules is noisy.
+ // Let's just ignore it.
+ allocator.free(entry.contents);
+ return null;
+ }
+
var package_json = PackageJSON{
.name = "",
.version = "",
.hash = 0xDEADBEEF,
.source = json_source,
.module_type = .unknown,
- .browser_map = BrowserMap.init(r.allocator),
- .main_fields = MainFieldMap.init(r.allocator),
+ .browser_map = BrowserMap.init(allocator, false),
+ .main_fields = MainFieldMap.init(allocator, false),
};
// Note: we tried rewriting this to be fewer loops over all the properties (asProperty loops over each)
@@ -634,17 +652,17 @@ pub const PackageJSON = struct {
// Feels like a codegen issue.
// or that looping over every property doesn't really matter because most package.jsons are < 20 properties
if (json.asProperty("version")) |version_json| {
- if (version_json.expr.asString(r.allocator)) |version_str| {
+ if (version_json.expr.asString(allocator)) |version_str| {
if (version_str.len > 0) {
- package_json.version = r.allocator.dupe(u8, version_str) catch unreachable;
+ package_json.version = allocator.dupe(u8, version_str) catch unreachable;
}
}
}
if (json.asProperty("name")) |version_json| {
- if (version_json.expr.asString(r.allocator)) |version_str| {
+ if (version_json.expr.asString(allocator)) |version_str| {
if (version_str.len > 0) {
- package_json.name = r.allocator.dupe(u8, version_str) catch unreachable;
+ package_json.name = allocator.dupe(u8, version_str) catch unreachable;
}
}
}
@@ -653,7 +671,7 @@ pub const PackageJSON = struct {
// We do not need to parse all this stuff.
if (comptime !include_scripts) {
if (json.asProperty("type")) |type_json| {
- if (type_json.expr.asString(r.allocator)) |type_str| {
+ if (type_json.expr.asString(allocator)) |type_str| {
switch (options.ModuleType.List.get(type_str) orelse options.ModuleType.unknown) {
.cjs => {
package_json.module_type = .cjs;
@@ -665,7 +683,7 @@ pub const PackageJSON = struct {
r.log.addRangeWarningFmt(
&json_source,
json_source.rangeOfString(type_json.loc),
- r.allocator,
+ allocator,
"\"{s}\" is not a valid value for \"type\" field (must be either \"commonjs\" or \"module\")",
.{type_str},
) catch unreachable;
@@ -681,9 +699,9 @@ pub const PackageJSON = struct {
if (json.asProperty(main)) |main_json| {
const expr: js_ast.Expr = main_json.expr;
- if ((expr.asString(r.allocator))) |str| {
+ if ((expr.asString(allocator))) |str| {
if (str.len > 0) {
- package_json.main_fields.put(main, r.allocator.dupe(u8, str) catch unreachable) catch unreachable;
+ package_json.main_fields.put(main, str) catch unreachable;
}
}
}
@@ -709,7 +727,7 @@ pub const PackageJSON = struct {
// Remap all files in the browser field
for (obj.properties.slice()) |*prop| {
- var _key_str = (prop.key orelse continue).asString(r.allocator) orelse continue;
+ var _key_str = (prop.key orelse continue).asString(allocator) orelse continue;
const value: js_ast.Expr = prop.value orelse continue;
// Normalize the path so we can compare against it without getting
@@ -721,12 +739,12 @@ pub const PackageJSON = struct {
// import of "foo", but that's actually not a bug. Or arguably it's a
// bug in Browserify but we have to replicate this bug because packages
// do this in the wild.
- const key = r.allocator.dupe(u8, r.fs.normalize(_key_str)) catch unreachable;
+ const key = allocator.dupe(u8, r.fs.normalize(_key_str)) catch unreachable;
switch (value.data) {
.e_string => |str| {
// If this is a string, it's a replacement package
- package_json.browser_map.put(key, str.string(r.allocator) catch unreachable) catch unreachable;
+ package_json.browser_map.put(key, str.string(allocator) catch unreachable) catch unreachable;
},
.e_boolean => |boolean| {
if (!boolean.value) {
@@ -745,13 +763,13 @@ pub const PackageJSON = struct {
}
if (json.asProperty("exports")) |exports_prop| {
- if (ExportsMap.parse(r.allocator, &json_source, r.log, exports_prop.expr, exports_prop.loc)) |exports_map| {
+ if (ExportsMap.parse(bun.default_allocator, &json_source, r.log, exports_prop.expr, exports_prop.loc)) |exports_map| {
package_json.exports = exports_map;
}
}
if (json.asProperty("imports")) |imports_prop| {
- if (ExportsMap.parse(r.allocator, &json_source, r.log, imports_prop.expr, imports_prop.loc)) |imports_map| {
+ if (ExportsMap.parse(bun.default_allocator, &json_source, r.log, imports_prop.expr, imports_prop.loc)) |imports_map| {
package_json.imports = imports_map;
}
}
@@ -764,9 +782,9 @@ pub const PackageJSON = struct {
var array = array_;
// TODO: switch to only storing hashes
var map = SideEffectsMap{};
- map.ensureTotalCapacity(r.allocator, array.array.items.len) catch unreachable;
+ map.ensureTotalCapacity(allocator, array.array.items.len) catch unreachable;
while (array.next()) |item| {
- if (item.asString(r.allocator)) |name| {
+ if (item.asString(allocator)) |name| {
// TODO: support RegExp using JavaScriptCore <> C++ bindings
if (strings.containsChar(name, '*')) {
// https://sourcegraph.com/search?q=context:global+file:package.json+sideEffects%22:+%5B&patternType=standard&sm=1&groupBy=repo
@@ -780,7 +798,7 @@ pub const PackageJSON = struct {
item.loc,
"wildcard sideEffects are not supported yet, which means this package will be deoptimized",
) catch unreachable;
- map.deinit(r.allocator);
+ map.deinit(allocator);
package_json.side_effects = .{ .unspecified = {} };
break :outer;
@@ -815,7 +833,7 @@ pub const PackageJSON = struct {
if (tag == .npm) {
const sliced = Semver.SlicedString.init(package_json.version, package_json.version);
- if (Dependency.parseWithTag(r.allocator, String.init(package_json.name, package_json.name), package_json.version, .npm, &sliced, r.log)) |dependency_version| {
+ if (Dependency.parseWithTag(allocator, String.init(package_json.name, package_json.name), package_json.version, .npm, &sliced, r.log)) |dependency_version| {
if (dependency_version.value.npm.version.isExact()) {
if (pm.lockfile.resolve(package_json.name, dependency_version)) |resolved| {
package_json.package_manager_package_id = resolved;
@@ -915,7 +933,7 @@ pub const PackageJSON = struct {
.b_buf = json_source.contents,
};
package_json.dependencies.map.ensureTotalCapacityContext(
- r.allocator,
+ allocator,
total_dependency_count,
ctx,
) catch unreachable;
@@ -926,14 +944,14 @@ pub const PackageJSON = struct {
var group_obj = group_json.data.e_object;
for (group_obj.properties.slice()) |*prop| {
const name_prop = prop.key orelse continue;
- const name_str = name_prop.asString(r.allocator) orelse continue;
+ const name_str = name_prop.asString(allocator) orelse continue;
const name = String.init(name_str, name_str);
const version_value = prop.value orelse continue;
- const version_str = version_value.asString(r.allocator) orelse continue;
+ const version_str = version_value.asString(allocator) orelse continue;
const sliced_str = Semver.SlicedString.init(version_str, version_str);
if (Dependency.parse(
- r.allocator,
+ allocator,
name,
version_str,
&sliced_str,
@@ -968,26 +986,26 @@ pub const PackageJSON = struct {
var count: usize = 0;
for (scripts_obj.properties.slice()) |prop| {
- const key = prop.key.?.asString(r.allocator) orelse continue;
- const value = prop.value.?.asString(r.allocator) orelse continue;
+ const key = prop.key.?.asString(allocator) orelse continue;
+ const value = prop.value.?.asString(allocator) orelse continue;
count += @as(usize, @boolToInt(key.len > 0 and value.len > 0));
}
if (count == 0) break :read_scripts;
- var scripts = ScriptsMap.init(r.allocator);
+ var scripts = ScriptsMap.init(allocator);
scripts.ensureUnusedCapacity(count) catch break :read_scripts;
for (scripts_obj.properties.slice()) |prop| {
- const key = prop.key.?.asString(r.allocator) orelse continue;
- const value = prop.value.?.asString(r.allocator) orelse continue;
+ const key = prop.key.?.asString(allocator) orelse continue;
+ const value = prop.value.?.asString(allocator) orelse continue;
if (!(key.len > 0 and value.len > 0)) continue;
scripts.putAssumeCapacity(key, value);
}
- package_json.scripts = r.allocator.create(ScriptsMap) catch unreachable;
+ package_json.scripts = allocator.create(ScriptsMap) catch unreachable;
package_json.scripts.?.* = scripts;
}
}
@@ -1048,7 +1066,7 @@ pub const ExportsMap = struct {
.e_string => |str| {
return Entry{
.data = .{
- .string = str.string(this.allocator) catch unreachable,
+ .string = str.slice(this.allocator),
},
.first_token = this.source.rangeOfString(expr.loc),
};
@@ -1079,7 +1097,7 @@ pub const ExportsMap = struct {
first_token.loc = expr.loc;
first_token.len = 1;
for (e_obj.properties.slice(), 0..) |prop, i| {
- const key: string = prop.key.?.data.e_string.string(this.allocator) catch unreachable;
+ const key: string = prop.key.?.data.e_string.slice(this.allocator);
const key_range: logger.Range = this.source.rangeOfString(prop.key.?.loc);
// If exports is an Object with both a key starting with "." and a key
diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig
index 4845de213..0e9bd3a22 100644
--- a/src/resolver/resolver.zig
+++ b/src/resolver/resolver.zig
@@ -60,13 +60,46 @@ pub const SideEffectsData = struct {
is_side_effects_array_in_json: bool = false,
};
-pub const TemporaryBuffer = struct {
- pub threadlocal var ExtensionPathBuf: [512]u8 = undefined;
- pub threadlocal var TSConfigMatchStarBuf: [512]u8 = undefined;
- pub threadlocal var TSConfigMatchPathBuf: [512]u8 = undefined;
- pub threadlocal var TSConfigMatchFullBuf: [bun.MAX_PATH_BYTES]u8 = undefined;
- pub threadlocal var TSConfigMatchFullBuf2: [bun.MAX_PATH_BYTES]u8 = undefined;
-};
+/// A temporary threadlocal buffer with a lifetime more than the current
+/// function call.
+const bufs = struct {
+ // Experimenting with making this one struct instead of a bunch of different
+ // threadlocal vars yielded no performance improvement on macOS when
+ // bundling 10 copies of Three.js. It may be worthwhile for more complicated
+ // packages but we lack a decent module resolution benchmark right now.
+ // Potentially revisit after https://github.com/oven-sh/bun/issues/2716
+ threadlocal var extension_path: [512]u8 = undefined;
+ threadlocal var tsconfig_match_full_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var tsconfig_match_full_buf2: [bun.MAX_PATH_BYTES]u8 = undefined;
+
+ threadlocal var esm_subpath: [512]u8 = undefined;
+ threadlocal var esm_absolute_package_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var esm_absolute_package_path_joined: [bun.MAX_PATH_BYTES]u8 = undefined;
+
+ threadlocal var dir_entry_paths_to_resolve: [256]DirEntryResolveQueueItem = undefined;
+ threadlocal var open_dirs: [256]std.fs.IterableDir = undefined;
+ threadlocal var resolve_without_remapping: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var index: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var dir_info_uncached_filename: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var node_bin_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var dir_info_uncached_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var tsconfig_base_url: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var relative_abs_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var load_as_file_or_directory_via_tsconfig_base_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var node_modules_check: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var field_abs_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var tsconfig_path_abs: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var check_browser_map: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var remap_path: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var load_as_file: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var remap_path_trailing_slash: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var path_in_global_disk_cache: [bun.MAX_PATH_BYTES]u8 = undefined;
+ threadlocal var abs_to_rel: [bun.MAX_PATH_BYTES]u8 = undefined;
+
+ pub inline fn bufs(comptime field: std.meta.DeclEnum(@This())) *@TypeOf(@field(@This(), @tagName(field))) {
+ return &@field(@This(), @tagName(field));
+ }
+}.bufs;
pub const PathPair = struct {
primary: Path,
@@ -262,26 +295,6 @@ pub const DirEntryResolveQueueItem = struct {
fd: StoredFileDescriptorType = 0,
};
-threadlocal var _dir_entry_paths_to_resolve: [256]DirEntryResolveQueueItem = undefined;
-threadlocal var _open_dirs: [256]std.fs.IterableDir = undefined;
-threadlocal var resolve_without_remapping_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var index_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var dir_info_uncached_filename_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var node_bin_path: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var dir_info_uncached_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var tsconfig_base_url_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var relative_abs_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var load_as_file_or_directory_via_tsconfig_base_path: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var node_modules_check_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var field_abs_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var tsconfig_path_abs_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var check_browser_map_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var remap_path_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var load_as_file_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var remap_path_trailing_slash: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var tsconfig_paths_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-threadlocal var path_in_global_disk_cache_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-
pub const DebugLogs = struct {
what: string = "",
indent: MutableString,
@@ -547,7 +560,7 @@ pub const Resolver = struct {
return ThisResolver{
.allocator = allocator,
- .dir_cache = DirInfo.HashMap.init(allocator),
+ .dir_cache = DirInfo.HashMap.init(bun.default_allocator),
.mutex = &resolver_Mutex,
.caches = CacheSet.init(allocator),
.opts = opts,
@@ -1093,7 +1106,7 @@ pub const Resolver = struct {
if (check_relative) {
const parts = [_]string{ source_dir, import_path };
- const abs_path = r.fs.absBuf(&parts, &relative_abs_path_buf);
+ const abs_path = r.fs.absBuf(&parts, bufs(.relative_abs_path));
if (r.opts.external.abs_paths.count() > 0 and r.opts.external.abs_paths.contains(abs_path)) {
// If the string literal in the source text is an absolute path and has
@@ -1438,9 +1451,6 @@ pub const Resolver = struct {
r.dir_cache.remove(path);
}
- threadlocal var esm_subpath_buf: [512]u8 = undefined;
- threadlocal var esm_absolute_package_path: [bun.MAX_PATH_BYTES]u8 = undefined;
- threadlocal var esm_absolute_package_path_joined: [bun.MAX_PATH_BYTES]u8 = undefined;
pub fn loadNodeModules(
r: *ThisResolver,
import_path: string,
@@ -1475,7 +1485,7 @@ pub const Resolver = struct {
if (tsconfig.hasBaseURL()) {
const base = tsconfig.base_url;
const paths = [_]string{ base, import_path };
- const abs = r.fs.absBuf(&paths, &load_as_file_or_directory_via_tsconfig_base_path);
+ const abs = r.fs.absBuf(&paths, bufs(.load_as_file_or_directory_via_tsconfig_base_path));
if (r.loadAsFileOrDirectory(abs, kind)) |res| {
return .{ .success = res };
@@ -1493,7 +1503,7 @@ pub const Resolver = struct {
return r.loadPackageImports(import_path, dir_info_package_json.?, kind, global_cache);
}
- const esm_ = ESModule.Package.parse(import_path, &esm_subpath_buf);
+ const esm_ = ESModule.Package.parse(import_path, bufs(.esm_subpath));
var source_dir_info = dir_info;
var any_node_modules_folder = false;
@@ -1506,7 +1516,7 @@ pub const Resolver = struct {
if (dir_info.hasNodeModules()) {
any_node_modules_folder = true;
var _paths = [_]string{ dir_info.abs_path, "node_modules", import_path };
- const abs_path = r.fs.absBuf(&_paths, &node_modules_check_buf);
+ const abs_path = r.fs.absBuf(&_paths, bufs(.node_modules_check));
if (r.debug_logs) |*debug| {
debug.addNoteFmt("Checking for a package in the directory \"{s}\"", .{abs_path});
}
@@ -1514,7 +1524,7 @@ pub const Resolver = struct {
if (esm_) |esm| {
const abs_package_path = brk: {
var parts = [_]string{ dir_info.abs_path, "node_modules", esm.name };
- break :brk r.fs.absBuf(&parts, &esm_absolute_package_path);
+ break :brk r.fs.absBuf(&parts, bufs(.esm_absolute_package_path));
};
if (r.dirInfoCached(abs_package_path) catch null) |pkg_dir_info| {
@@ -1717,7 +1727,7 @@ pub const Resolver = struct {
}
};
- const dir_path_for_resolution = manager.pathForResolution(resolved_package_id, resolution, &path_in_global_disk_cache_buf) catch |err| {
+ const dir_path_for_resolution = manager.pathForResolution(resolved_package_id, resolution, bufs(.path_in_global_disk_cache)) catch |err| {
// if it's missing, we need to install it
if (err == error.FileNotFound) {
switch (manager.getPreinstallState(resolved_package_id, manager.lockfile)) {
@@ -1854,7 +1864,7 @@ pub const Resolver = struct {
}
var _paths = [_]string{ pkg_dir_info.abs_path, esm.subpath };
- const abs_path = r.fs.absBuf(&_paths, &node_modules_check_buf);
+ const abs_path = r.fs.absBuf(&_paths, bufs(.node_modules_check));
if (r.debug_logs) |*debug| {
debug.addNoteFmt("Checking for a package in the directory \"{s}\"", .{abs_path});
}
@@ -1911,21 +1921,24 @@ pub const Resolver = struct {
}
if (needs_iter) {
- const allocator = r.fs.allocator;
- dir_entries_option = rfs.entries.put(&cached_dir_entry_result, .{
- .entries = Fs.FileSystem.DirEntry.init(
- Fs.FileSystem.DirnameStore.instance.append(string, dir_path) catch unreachable,
- ),
- }) catch unreachable;
+ const allocator = bun.fs_allocator;
+ var dir_entries_ptr = allocator.create(Fs.FileSystem.DirEntry) catch unreachable;
+ dir_entries_ptr.* = Fs.FileSystem.DirEntry.init(
+ Fs.FileSystem.DirnameStore.instance.append(string, dir_path) catch unreachable,
+ );
if (FeatureFlags.store_file_descriptors) {
Fs.FileSystem.setMaxFd(open_dir.dir.fd);
- dir_entries_option.entries.fd = open_dir.dir.fd;
+ dir_entries_ptr.fd = open_dir.dir.fd;
}
var dir_iterator = open_dir.iterate();
while (dir_iterator.next() catch null) |_value| {
- dir_entries_option.entries.addEntry(_value, allocator, void, {}) catch unreachable;
+ dir_entries_ptr.addEntry(_value, allocator, void, {}) catch unreachable;
}
+
+ dir_entries_option = rfs.entries.put(&cached_dir_entry_result, .{
+ .entries = dir_entries_ptr,
+ }) catch unreachable;
}
// We must initialize it as empty so that the result index is correct.
@@ -2068,7 +2081,7 @@ pub const Resolver = struct {
abs_package_path,
strings.withoutLeadingSlash(esm_resolution.path),
};
- break :brk r.fs.absBuf(&parts, &esm_absolute_package_path_joined);
+ break :brk r.fs.absBuf(&parts, bufs(.esm_absolute_package_path_joined));
};
var missing_suffix: string = undefined;
@@ -2094,9 +2107,9 @@ pub const Resolver = struct {
// Try to have a friendly error message if people forget the extension
if (ends_with_star) {
- bun.copy(u8, &load_as_file_buf, base);
+ bun.copy(u8, bufs(.load_as_file), base);
for (extension_order) |ext| {
- var file_name = load_as_file_buf[0 .. base.len + ext.len];
+ var file_name = bufs(.load_as_file)[0 .. base.len + ext.len];
bun.copy(u8, file_name[base.len..], ext);
if (entries.get(file_name) != null) {
if (r.debug_logs) |*debug| {
@@ -2121,9 +2134,9 @@ pub const Resolver = struct {
if (r.dirInfoCached(abs_esm_path) catch null) |dir_info| {
if (dir_info.getEntries()) |dir_entries| {
const index = "index";
- bun.copy(u8, &load_as_file_buf, index);
+ bun.copy(u8, bufs(.load_as_file), index);
for (extension_order) |ext| {
- var file_name = load_as_file_buf[0 .. index.len + ext.len];
+ var file_name = bufs(.load_as_file)[0 .. index.len + ext.len];
bun.copy(u8, file_name[index.len..], ext);
const index_query = dir_entries.get(file_name);
if (index_query != null and index_query.?.entry.kind(&r.fs.fs) == .file) {
@@ -2191,7 +2204,7 @@ pub const Resolver = struct {
return r.loadNodeModules(import_path, kind, source_dir_info, global_cache, false);
} else {
const paths = [_]string{ source_dir_info.abs_path, import_path };
- var resolved = r.fs.absBuf(&paths, &resolve_without_remapping_buf);
+ var resolved = r.fs.absBuf(&paths, bufs(.resolve_without_remapping));
if (r.loadAsFileOrDirectory(resolved, kind)) |result| {
return .{ .success = result };
}
@@ -2226,14 +2239,14 @@ pub const Resolver = struct {
// this might leak
if (!std.fs.path.isAbsolute(result.base_url)) {
const paths = [_]string{ file_dir, result.base_url };
- result.base_url = r.fs.dirname_store.append(string, r.fs.absBuf(&paths, &tsconfig_base_url_buf)) catch unreachable;
+ result.base_url = r.fs.dirname_store.append(string, r.fs.absBuf(&paths, bufs(.tsconfig_base_url))) catch unreachable;
}
}
if (result.paths.count() > 0 and (result.base_url_for_paths.len == 0 or !std.fs.path.isAbsolute(result.base_url_for_paths))) {
// this might leak
const paths = [_]string{ file_dir, result.base_url };
- result.base_url_for_paths = r.fs.dirname_store.append(string, r.fs.absBuf(&paths, &tsconfig_base_url_buf)) catch unreachable;
+ result.base_url_for_paths = r.fs.dirname_store.append(string, r.fs.absBuf(&paths, bufs(.tsconfig_base_url))) catch unreachable;
}
return result;
@@ -2279,7 +2292,7 @@ pub const Resolver = struct {
) orelse return null;
}
- var _pkg = try r.allocator.create(PackageJSON);
+ var _pkg = try bun.default_allocator.create(PackageJSON);
_pkg.* = pkg;
return _pkg;
}
@@ -2325,11 +2338,13 @@ pub const Resolver = struct {
return r.dir_cache.atIndex(top_result.index);
}
+ var dir_info_uncached_path_buf = bufs(.dir_info_uncached_path);
+
var i: i32 = 1;
- bun.copy(u8, &dir_info_uncached_path_buf, _path);
+ bun.copy(u8, dir_info_uncached_path_buf, _path);
var path = dir_info_uncached_path_buf[0.._path.len];
- _dir_entry_paths_to_resolve[0] = (DirEntryResolveQueueItem{ .result = top_result, .unsafe_path = path, .safe_path = "" });
+ bufs(.dir_entry_paths_to_resolve)[0] = (DirEntryResolveQueueItem{ .result = top_result, .unsafe_path = path, .safe_path = "" });
var top = Dirname.dirname(path);
var top_parent: allocators.Result = allocators.Result{
@@ -2354,15 +2369,15 @@ pub const Resolver = struct {
top_parent = result;
break;
}
- _dir_entry_paths_to_resolve[@intCast(usize, i)] = DirEntryResolveQueueItem{
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)] = DirEntryResolveQueueItem{
.unsafe_path = top,
.result = result,
.fd = 0,
};
if (rfs.entries.get(top)) |top_entry| {
- _dir_entry_paths_to_resolve[@intCast(usize, i)].safe_path = top_entry.entries.dir;
- _dir_entry_paths_to_resolve[@intCast(usize, i)].fd = top_entry.entries.fd;
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)].safe_path = top_entry.entries.dir;
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)].fd = top_entry.entries.fd;
}
i += 1;
}
@@ -2372,21 +2387,21 @@ pub const Resolver = struct {
if (result.status != .unknown) {
top_parent = result;
} else {
- _dir_entry_paths_to_resolve[@intCast(usize, i)] = DirEntryResolveQueueItem{
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)] = DirEntryResolveQueueItem{
.unsafe_path = root_path,
.result = result,
.fd = 0,
};
if (rfs.entries.get(top)) |top_entry| {
- _dir_entry_paths_to_resolve[@intCast(usize, i)].safe_path = top_entry.entries.dir;
- _dir_entry_paths_to_resolve[@intCast(usize, i)].fd = top_entry.entries.fd;
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)].safe_path = top_entry.entries.dir;
+ bufs(.dir_entry_paths_to_resolve)[@intCast(usize, i)].fd = top_entry.entries.fd;
}
i += 1;
}
}
- var queue_slice: []DirEntryResolveQueueItem = _dir_entry_paths_to_resolve[0..@intCast(usize, i)];
+ var queue_slice: []DirEntryResolveQueueItem = bufs(.dir_entry_paths_to_resolve)[0..@intCast(usize, i)];
if (Environment.allow_assert) std.debug.assert(queue_slice.len > 0);
var open_dir_count: usize = 0;
@@ -2395,7 +2410,7 @@ pub const Resolver = struct {
// Anything
if (open_dir_count > 0 and r.fs.fs.needToCloseFiles()) {
- var open_dirs: []std.fs.IterableDir = _open_dirs[0..open_dir_count];
+ var open_dirs: []std.fs.IterableDir = bufs(.open_dirs)[0..open_dir_count];
for (open_dirs) |*open_dir| {
open_dir.dir.close();
}
@@ -2487,7 +2502,7 @@ pub const Resolver = struct {
if (queue_top.fd == 0) {
Fs.FileSystem.setMaxFd(open_dir.dir.fd);
// these objects mostly just wrap the file descriptor, so it's fine to keep it.
- _open_dirs[open_dir_count] = open_dir;
+ bufs(.open_dirs)[open_dir_count] = open_dir;
open_dir_count += 1;
}
@@ -2529,19 +2544,21 @@ pub const Resolver = struct {
}
if (needs_iter) {
- const allocator = r.fs.allocator;
- dir_entries_option = try rfs.entries.put(&cached_dir_entry_result, .{
- .entries = Fs.FileSystem.DirEntry.init(dir_path),
- });
-
+ const allocator = bun.fs_allocator;
+ var entries_ptr = allocator.create(Fs.FileSystem.DirEntry) catch unreachable;
+ entries_ptr.* = Fs.FileSystem.DirEntry.init(dir_path);
if (FeatureFlags.store_file_descriptors) {
Fs.FileSystem.setMaxFd(open_dir.dir.fd);
- dir_entries_option.entries.fd = open_dir.dir.fd;
+ entries_ptr.fd = open_dir.dir.fd;
}
var dir_iterator = open_dir.iterate();
while (try dir_iterator.next()) |_value| {
- dir_entries_option.entries.addEntry(_value, allocator, void, {}) catch unreachable;
+ entries_ptr.addEntry(_value, allocator, void, {}) catch unreachable;
}
+
+ dir_entries_option = try rfs.entries.put(&cached_dir_entry_result, .{
+ .entries = entries_ptr,
+ });
}
// We must initialize it as empty so that the result index is correct.
@@ -2610,7 +2627,7 @@ pub const Resolver = struct {
if (!std.fs.path.isAbsolute(absolute_original_path)) {
const parts = [_]string{ abs_base_url, original_path };
- absolute_original_path = r.fs.absBuf(&parts, &tsconfig_path_abs_buf);
+ absolute_original_path = r.fs.absBuf(&parts, bufs(.tsconfig_path_abs));
}
if (r.loadAsFileOrDirectory(absolute_original_path, kind)) |res| {
@@ -2672,14 +2689,14 @@ pub const Resolver = struct {
// 1. Normalize the base path
// so that "/Users/foo/project/", "../components/*" => "/Users/foo/components/""
- var prefix = r.fs.absBuf(&prefix_parts, &TemporaryBuffer.TSConfigMatchFullBuf2);
+ var prefix = r.fs.absBuf(&prefix_parts, bufs(.tsconfig_match_full_buf2));
// 2. Join the new base path with the matched result
// so that "/Users/foo/components/", "/foo/bar" => /Users/foo/components/foo/bar
var parts = [_]string{ prefix, std.mem.trimLeft(u8, matched_text, "/"), std.mem.trimLeft(u8, longest_match.suffix, "/") };
var absolute_original_path = r.fs.absBuf(
&parts,
- &TemporaryBuffer.TSConfigMatchFullBuf,
+ bufs(.tsconfig_match_full_buf),
);
if (r.loadAsFileOrDirectory(absolute_original_path, kind)) |res| {
@@ -2741,8 +2758,6 @@ pub const Resolver = struct {
extension_order: []const string,
map: BrowserMap,
- pub threadlocal var abs_to_rel_buf: [bun.MAX_PATH_BYTES]u8 = undefined;
-
pub const Kind = enum { PackagePath, AbsolutePath };
pub fn checkPath(
@@ -2759,12 +2774,14 @@ pub const Resolver = struct {
return true;
}
- bun.copy(u8, &TemporaryBuffer.ExtensionPathBuf, cleaned);
+ var ext_buf = bufs(.extension_path);
+
+ bun.copy(u8, ext_buf, cleaned);
// If that failed, try adding implicit extensions
for (this.extension_order) |ext| {
- bun.copy(u8, TemporaryBuffer.ExtensionPathBuf[cleaned.len..], ext);
- const new_path = TemporaryBuffer.ExtensionPathBuf[0 .. cleaned.len + ext.len];
+ bun.copy(u8, ext_buf[cleaned.len..], ext);
+ const new_path = ext_buf[0 .. cleaned.len + ext.len];
// if (r.debug_logs) |*debug| {
// debug.addNoteFmt("Checking for \"{s}\" ", .{new_path});
// }
@@ -2781,7 +2798,7 @@ pub const Resolver = struct {
var index_path: string = "";
{
var parts = [_]string{ std.mem.trimRight(u8, path_to_check, std.fs.path.sep_str), std.fs.path.sep_str ++ "index" };
- index_path = ResolvePath.joinStringBuf(&tsconfig_base_url_buf, &parts, .auto);
+ index_path = ResolvePath.joinStringBuf(bufs(.tsconfig_base_url), &parts, .auto);
}
if (map.get(index_path)) |_remapped| {
@@ -2790,11 +2807,11 @@ pub const Resolver = struct {
return true;
}
- bun.copy(u8, &TemporaryBuffer.ExtensionPathBuf, index_path);
+ bun.copy(u8, ext_buf, index_path);
for (this.extension_order) |ext| {
- bun.copy(u8, TemporaryBuffer.ExtensionPathBuf[index_path.len..], ext);
- const new_path = TemporaryBuffer.ExtensionPathBuf[0 .. index_path.len + ext.len];
+ bun.copy(u8, ext_buf[index_path.len..], ext);
+ const new_path = ext_buf[0 .. index_path.len + ext.len];
// if (r.debug_logs) |*debug| {
// debug.addNoteFmt("Checking for \"{s}\" ", .{new_path});
// }
@@ -2839,7 +2856,7 @@ pub const Resolver = struct {
}
// Normalize the path so we can compare against it without getting confused by "./"
- var cleaned = r.fs.normalizeBuf(&check_browser_map_buf, input_path);
+ var cleaned = r.fs.normalizeBuf(bufs(.check_browser_map), input_path);
if (cleaned.len == 1 and cleaned[0] == '.') {
// No bundler supports remapping ".", so we don't either
@@ -2860,11 +2877,12 @@ pub const Resolver = struct {
// First try the import path as a package path
if (isPackagePath(checker.input_path)) {
+ var abs_to_rel = bufs(.abs_to_rel);
switch (comptime kind) {
.AbsolutePath => {
- BrowserMapPath.abs_to_rel_buf[0..2].* = "./".*;
- bun.copy(u8, BrowserMapPath.abs_to_rel_buf[2..], checker.input_path);
- if (checker.checkPath(BrowserMapPath.abs_to_rel_buf[0 .. checker.input_path.len + 2])) {
+ abs_to_rel[0..2].* = "./".*;
+ bun.copy(u8, abs_to_rel[2..], checker.input_path);
+ if (checker.checkPath(abs_to_rel[0 .. checker.input_path.len + 2])) {
return checker.remapped;
}
},
@@ -2882,10 +2900,10 @@ pub const Resolver = struct {
};
if (isInSamePackage) {
- BrowserMapPath.abs_to_rel_buf[0..2].* = "./".*;
- bun.copy(u8, BrowserMapPath.abs_to_rel_buf[2..], checker.input_path);
+ abs_to_rel[0..2].* = "./".*;
+ bun.copy(u8, abs_to_rel[2..], checker.input_path);
- if (checker.checkPath(BrowserMapPath.abs_to_rel_buf[0 .. checker.input_path.len + 2])) {
+ if (checker.checkPath(abs_to_rel[0 .. checker.input_path.len + 2])) {
return checker.remapped;
}
}
@@ -2939,7 +2957,7 @@ pub const Resolver = struct {
}
}
const _paths = [_]string{ path, field_rel_path };
- const field_abs_path = r.fs.absBuf(&_paths, &field_abs_path_buf);
+ const field_abs_path = r.fs.absBuf(&_paths, bufs(.field_abs_path));
// Is this a file?
if (r.loadAsFile(field_abs_path, extension_order)) |result| {
@@ -2972,7 +2990,9 @@ pub const Resolver = struct {
var rfs = &r.fs.fs;
// Try the "index" file with extensions
for (extension_order) |ext| {
- var base = TemporaryBuffer.ExtensionPathBuf[0 .. "index".len + ext.len];
+ var ext_buf = bufs(.extension_path);
+
+ var base = ext_buf[0 .. "index".len + ext.len];
base[0.."index".len].* = "index".*;
bun.copy(u8, base["index".len..], ext);
@@ -2982,7 +3002,7 @@ pub const Resolver = struct {
const out_buf = brk: {
if (lookup.entry.abs_path.isEmpty()) {
const parts = [_]string{ dir_info.abs_path, base };
- const out_buf_ = r.fs.absBuf(&parts, &index_buf);
+ const out_buf_ = r.fs.absBuf(&parts, bufs(.index));
lookup.entry.abs_path =
PathString.init(r.fs.dirname_store.append(@TypeOf(out_buf_), out_buf_) catch unreachable);
}
@@ -3024,10 +3044,11 @@ pub const Resolver = struct {
// In order for our path handling logic to be correct, it must end with a trailing slash.
var path = path_;
if (!strings.endsWithChar(path_, std.fs.path.sep)) {
- bun.copy(u8, &remap_path_trailing_slash, path);
- remap_path_trailing_slash[path.len] = std.fs.path.sep;
- remap_path_trailing_slash[path.len + 1] = 0;
- path = remap_path_trailing_slash[0 .. path.len + 1];
+ var path_buf = bufs(.remap_path_trailing_slash);
+ bun.copy(u8, path_buf, path);
+ path_buf[path.len] = std.fs.path.sep;
+ path_buf[path.len + 1] = 0;
+ path = path_buf[0 .. path.len + 1];
}
if (r.care_about_browser_field) {
@@ -3044,7 +3065,7 @@ pub const Resolver = struct {
// Is the path disabled?
if (remap.len == 0) {
const paths = [_]string{ path, field_rel_path };
- const new_path = r.fs.absBuf(&paths, &remap_path_buf);
+ const new_path = r.fs.absBuf(&paths, bufs(.remap_path));
var _path = Path.init(new_path);
_path.is_disabled = true;
return MatchResult{
@@ -3056,7 +3077,7 @@ pub const Resolver = struct {
}
const new_paths = [_]string{ path, remap };
- const remapped_abs = r.fs.absBuf(&new_paths, &remap_path_buf);
+ const remapped_abs = r.fs.absBuf(&new_paths, bufs(.remap_path));
// Is this a file
if (r.loadAsFile(remapped_abs, extension_order)) |file_result| {
@@ -3283,7 +3304,7 @@ pub const Resolver = struct {
const abs_path = brk: {
if (query.entry.abs_path.isEmpty()) {
const abs_path_parts = [_]string{ query.entry.dir, query.entry.base() };
- query.entry.abs_path = PathString.init(r.fs.dirname_store.append(string, r.fs.absBuf(&abs_path_parts, &load_as_file_buf)) catch unreachable);
+ query.entry.abs_path = PathString.init(r.fs.dirname_store.append(string, r.fs.absBuf(&abs_path_parts, bufs(.load_as_file))) catch unreachable);
}
break :brk query.entry.abs_path.slice();
@@ -3299,9 +3320,9 @@ pub const Resolver = struct {
}
// Try the path with extensions
- bun.copy(u8, &load_as_file_buf, path);
+ bun.copy(u8, bufs(.load_as_file), path);
for (extension_order) |ext| {
- var buffer = load_as_file_buf[0 .. path.len + ext.len];
+ var buffer = bufs(.load_as_file)[0 .. path.len + ext.len];
bun.copy(u8, buffer[path.len..], ext);
const file_name = buffer[path.len - base.len .. buffer.len];
@@ -3352,7 +3373,7 @@ pub const Resolver = struct {
const ext = base[last_dot..base.len];
if (strings.eqlComptime(ext, ".js") or strings.eqlComptime(ext, ".jsx")) {
const segment = base[0..last_dot];
- var tail = load_as_file_buf[path.len - base.len ..];
+ var tail = bufs(.load_as_file)[path.len - base.len ..];
bun.copy(u8, tail, segment);
const exts = .{ ".ts", ".tsx" };
@@ -3460,7 +3481,7 @@ pub const Resolver = struct {
const this_dir = std.fs.Dir{ .fd = fd };
var file = this_dir.openDirZ("node_modules/.bin", .{}, true) catch break :append_bin_dir;
defer file.close();
- var bin_path = bun.getFdPath(file.fd, &node_bin_path) catch break :append_bin_dir;
+ var bin_path = bun.getFdPath(file.fd, bufs(.node_bin_path)) catch break :append_bin_dir;
bin_folders_lock.lock();
defer bin_folders_lock.unlock();
@@ -3485,7 +3506,7 @@ pub const Resolver = struct {
const this_dir = std.fs.Dir{ .fd = fd };
var file = this_dir.openDirZ(".bin", .{}, false) catch break :append_bin_dir;
defer file.close();
- var bin_path = bun.getFdPath(file.fd, &node_bin_path) catch break :append_bin_dir;
+ var bin_path = bun.getFdPath(file.fd, bufs(.node_bin_path)) catch break :append_bin_dir;
bin_folders_lock.lock();
defer bin_folders_lock.unlock();
@@ -3540,7 +3561,7 @@ pub const Resolver = struct {
} else if (parent.?.abs_real_path.len > 0) {
// this might leak a little i'm not sure
const parts = [_]string{ parent.?.abs_real_path, base };
- symlink = r.fs.dirname_store.append(string, r.fs.absBuf(&parts, &dir_info_uncached_filename_buf)) catch unreachable;
+ symlink = r.fs.dirname_store.append(string, r.fs.absBuf(&parts, bufs(.dir_info_uncached_filename))) catch unreachable;
if (r.debug_logs) |*logs| {
logs.addNote(std.fmt.allocPrint(r.allocator, "Resolved symlink \"{s}\" to \"{s}\"", .{ path, symlink }) catch unreachable);
@@ -3592,7 +3613,7 @@ pub const Resolver = struct {
if (entry.kind(rfs) == .file) {
const parts = [_]string{ path, "tsconfig.json" };
- tsconfig_path = r.fs.absBuf(&parts, &dir_info_uncached_filename_buf);
+ tsconfig_path = r.fs.absBuf(&parts, bufs(.dir_info_uncached_filename));
}
}
if (tsconfig_path == null) {
@@ -3600,7 +3621,7 @@ pub const Resolver = struct {
const entry = lookup.entry;
if (entry.kind(rfs) == .file) {
const parts = [_]string{ path, "jsconfig.json" };
- tsconfig_path = r.fs.absBuf(&parts, &dir_info_uncached_filename_buf);
+ tsconfig_path = r.fs.absBuf(&parts, bufs(.dir_info_uncached_filename));
}
}
}
@@ -3629,7 +3650,7 @@ pub const Resolver = struct {
while (current.extends.len > 0) {
var ts_dir_name = Dirname.dirname(current.abs_path);
// not sure why this needs cwd but we'll just pass in the dir of the tsconfig...
- var abs_path = ResolvePath.joinAbsStringBuf(ts_dir_name, &tsconfig_path_abs_buf, &[_]string{ ts_dir_name, current.extends }, .auto);
+ var abs_path = ResolvePath.joinAbsStringBuf(ts_dir_name, bufs(.tsconfig_path_abs), &[_]string{ ts_dir_name, current.extends }, .auto);
var parent_config_maybe = try r.parseTSConfig(abs_path, 0);
if (parent_config_maybe) |parent_config| {
try parent_configs.append(parent_config);