-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add win32 path.toNamespacedPath and align rest of node:path with Node #8469
Conversation
❌ @jdalton 4 files with test failures on bun-darwin-aarch64:
|
❌ @jdalton 5 files with test failures on linux-x64:
|
❌ @jdalton 4 files with test failures on linux-x64-baseline:
|
❌ @jdalton 4 files with test failures on bun-darwin-x64:
|
❌🪟 @jdalton, there are 11 test regressions on Windows x86_64
|
2a52ec0
to
529197d
Compare
529197d
to
546932d
Compare
546932d
to
c30180a
Compare
c30180a
to
394730b
Compare
f84b876
to
dd3112e
Compare
* windows: fix module.paths getter causing a crash * use the buffer that was there before
dd3112e
to
e3ca9de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the approach of copying node 1:1 is great i think, though i did not verify all code was ported over properly. might be worth double checking if tests are failing, as i did spot one single place where something was misported.
regards to performance, i see:
- the obvious complexity of what
node:path
does. this is unavoidable and i think it isn't actually going to be that huge of a deal. path normalization has to happen, and this will be a big win in accuracy (bun is not accurate in many regards) - the environment variable lookup in
resolve
is problematic i think. i really wish it didnt have to happen, see comments at that point in the review - the allocation stategy is alright but i think the
getBufAlloc
function seems very problematic.i simply think we should just not support paths longer than the max. though i may be wrong in the need for this.i am incorrect
after this pr, it would also be nice to reintroduce bun.String.map, a function did not ever commit: it lets us actually apply the generic versions of these functions to the javascript strings. some advances by dylan and georgijs in our string code make this a more useful api now (at the time i couldnt actually use the function or anything)
also, maybe we rename the Impl
functions to have T
as the suffix, as that was the pattern taken by the other code doing a similar pattern of generic string manipulation
src/bun.js/node/types.zig
Outdated
|
||
pub fn create(globalObject: *JSC.JSGlobalObject, isWindows: bool) callconv(.C) JSC.JSValue { | ||
return shim.cppFn("create", .{ globalObject, isWindows }); | ||
/// Taken from Zig 0.11.0 zig/src/resinator/rc.zig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wish this was in the standard library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can be with a PR to zig! It's used internally to them already.
0bac691
to
5e4a05c
Compare
} | ||
|
||
const results = await Promise.allSettled(pending); | ||
for (let i = 0; i < iterCount; i++) { | ||
expect(results[i].status).toBe("rejected"); | ||
expect(results[i].reason!.code).toBe("ENOENT"); | ||
expect(results[i].reason!.path).toBe(join(notfound, i)); | ||
expect(results[i].reason!.path).toBe(join(notfound, `${i}`)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ Ensure path.join
gets string values.
// | ||
// While Node's error message is: | ||
// The "pathObject" argument must be of type object. Received nullå | ||
message: `"pathObject" property must be of type object, got ${typeof pathObject}`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👆 TODO for error message compliance. Node provides a bit more-helpful messages around data types.
@@ -1,900 +1,62 @@ | |||
const { file } = import.meta; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed to test/js/node/path/browserify.test.js
// const spawnResult = child.spawnSync(process.argv[0], [relativeFixture, currentDriveLetter]); | ||
// const resolvedPath = spawnResult.stdout.toString().trim(); | ||
// assert.strictEqual(resolvedPath.toLowerCase(), process.cwd().toLowerCase()); | ||
// } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ TODO for once our spawnSync().stdout
result works on Windows.
8dcafa5
to
767b62b
Compare
|
||
inline fn MaybeSlice(comptime T: type) type { | ||
return Maybe([]const T, Syscall.Error); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MaybeBuf
and MaybeSlice
use Syscall.Error
for now.
}; | ||
const pathZStr = path_ptr.getZigString(globalObject); | ||
const len = pathZStr.len; | ||
if (len == 0) return toUTF8JSString(globalObject, CHAR_STR_DOT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ We don't even allocate if len
is0
, exiting early
); | ||
const allocator = stack_fallback.get(); | ||
|
||
const pathZSlice = pathZStr.toSlice(allocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming pathZSlice
to distinguish between the ZigString.Slice
and the standard buffer slice. Since we will be doing pathZSlice.slice()
later and reading it from a glance can be a head scratcher.
else | ||
toJSString(globalObject, normalizePosix(pathZSlice.slice(), buf)); | ||
} | ||
var buf: PathBuffer = undefined; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ We only use the allocator
when needed else we use the cheap stack var buf: PathBuffer = undefined;
767b62b
to
f4e4fe9
Compare
if (len == 0) { | ||
// Skip work for empty entries | ||
paths[i] = ""; | ||
} else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ Skip work for empty paths (defer allocator.free(paths)
is still happy)
src/bun.js/node/types.zig
Outdated
); | ||
const allocator = stack_fallback.get(); | ||
|
||
const pathZSlice = path_ptr.toSlice(globalObject, allocator); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ The only place we jump straight to pathZSlice
instead of going to pathZStr
.
@@ -2431,6 +4930,9 @@ pub const Path = struct { | |||
@export(Path.resolve, .{ | |||
.name = Export[9].symbol_name, | |||
}); | |||
@export(Path.toNamespacedPath, .{ | |||
.name = Export[10].symbol_name, | |||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
☝️ toNamespacePath wiring
f4e4fe9
to
769c79a
Compare
@@ -173,7 +173,7 @@ pub const RefCount = @import("./ref_count.zig").RefCount; | |||
|
|||
pub const MAX_PATH_BYTES: usize = if (Environment.isWasm) 1024 else std.fs.MAX_PATH_BYTES; | |||
pub const PathBuffer = [MAX_PATH_BYTES]u8; | |||
pub const WPathBuffer = [MAX_PATH_BYTES / 2]u16; | |||
pub const WPathBuffer = [windows.PATH_MAX_WIDE]u16; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch
769c79a
to
8e272e5
Compare
d54f2cc
to
46ec84d
Compare
46ec84d
to
fc31407
Compare
* Fix some related to paths and string encoding * Fix relative paths with glob * Fix scan tests * Fix glob scan test * [autofix.ci] apply automated fixes * Fix leak test * clean up post merge * [autofix.ci] apply automated fixes * clean up glob getcwd * remove old struct * fix open on posix * feat: Add win32 path.toNamespacedPath and align rest of node:path with Node (#8469) * restore zls file change * [autofix.ci] apply automated fixes * switch to using fs.top_level_dir in glob --------- Co-authored-by: Jarred Sumner <[email protected]> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Georgijs Vilums <[email protected]> Co-authored-by: Georgijs Vilums <[email protected]> Co-authored-by: John-David Dalton <[email protected]> Co-authored-by: Georgijs <[email protected]>
What does this PR do?
Add win32
path.toNamespacedPath
and align rest ofnode:path
with Node.node:path
22+ methods to Zig 🎉node:path
unit tests (80node:path
tests now) 🗒️test\\js\\node\\path\\*
This is a very close port of Node's methods. I like this approach as it avoids gotchas that creep in with reworking code. Even things like how JavaScript allows
-1
forString#slice
plays its part in Node's implementation.After this lands I'll do a follow-up PR to move these into
resolve_path.zig
.