Skip to content

[pull] main from nodejs:main - #1236

Merged
pull[bot] merged 3 commits into
adamlaska:mainfrom
nodejs:main
Aug 18, 2026
Merged

[pull] main from nodejs:main#1236
pull[bot] merged 3 commits into
adamlaska:mainfrom
nodejs:main

Conversation

@pull

@pull pull Bot commented Aug 18, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

soreavis and others added 3 commits August 18, 2026 15:15
The file type of a directory entry returned by fs.readdir() or
fs.opendir() is the type reported by the operating system's directory
listing. Node.js falls back to lstat() only when the reported type is
unknown, and some file systems may report a type that differs from what
lstat() would return. Document this in the fs.Dirent class introduction,
with fs.lstat() as the accurate alternative.

Fixes: #30646
Signed-off-by: Julian Soreavis <julian.soreavis@gmail.com>
PR-URL: #64532
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Jason Zhang <xzha4350@gmail.com>
StringDecoder used v8::String::NewFromUtf8() for UTF-8, while
Buffer#toString() goes through StringBytes::Encode(), which has
simdutf-backed ASCII, Latin-1 and UTF-16 paths and only falls back
to NewFromUtf8() for input that contains invalid sequences. Route
the decoder through the same function, so streams with
setEncoding('utf8') and readline decode at the same speed as
Buffer#toString(). U+FFFD replacement is unchanged because invalid
input still ends up in NewFromUtf8(), and the ERR_STRING_TOO_LONG
check is kept explicit so over-long input fails as before.

benchmark/string_decoder/string-decoder.js (encoding=utf8) and a
readline-over-pipe workload improve by 2-3x for chunks >= 1 KiB;
64 KiB newline-delimited JSON round trips over child stdio improve
by ~30% on the reading side alone.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: #65324
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Daniel Lemire <daniel@lemire.me>
Reviewed-By: James M Snell <jasnell@gmail.com>
StringBytes::Write() already used simdutf to encode one-byte strings
as UTF-8 but sent every two-byte (UTF-16) string through
v8::String::WriteUtf8V2(), which is several times slower. That path
is behind Buffer.from(string), buf.write(), fs.write*() with string
data and every string written to a libuv stream, and JSON.stringify()
output is a two-byte string as soon as any value in the payload is
outside Latin-1.

Encode two-byte strings with simdutf as well whenever their UTF-8 form
is guaranteed to fit in the target: well-formed input is converted
directly, and input with unpaired surrogates is converted from a copy
passed through simdutf::to_well_formed_utf16(), which replaces each
unpaired surrogate with U+FFFD exactly like kReplaceInvalidUtf8 (this
mirrors what TextEncoder already does). Writes that have to truncate
at a character boundary keep using WriteUtf8V2(), so their output is
byte-for-byte unchanged, and so do strings of up to 32 code units, for
which V8 is already as fast (the same threshold TextEncoder uses).

buf.write() of a 2 KiB two-byte string improves ~5x (astral-heavy and
lone-surrogate strings ~3.5x and ~5x), Buffer.from() of a 64 KiB JSON
string ~2.7x; one-byte strings are unaffected.

Signed-off-by: Shelley Vohr <shelley.vohr@gmail.com>
PR-URL: #65324
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Daniel Lemire <daniel@lemire.me>
Reviewed-By: James M Snell <jasnell@gmail.com>
@pull pull Bot locked and limited conversation to collaborators Aug 18, 2026
@pull pull Bot added the ⤵️ pull label Aug 18, 2026
@pull
pull Bot merged commit 55e4ca3 into adamlaska:main Aug 18, 2026
0 of 4 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants