From 1c9baec54821b63da72065196fa53f0f031568e8 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Tue, 18 Aug 2026 09:20:52 +0300 Subject: [PATCH 1/9] test: keep WPT backend checks alive Signed-off-by: Filip Skokan PR-URL: https://github.com/nodejs/node/pull/65320 Reviewed-By: Antoine du Hamel Reviewed-By: Aviv Keller Reviewed-By: Luigi Pinca --- test/parallel/test-common-wpt-backends.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/parallel/test-common-wpt-backends.js b/test/parallel/test-common-wpt-backends.js index f201adde64e1..10aa619bc8d5 100644 --- a/test/parallel/test-common-wpt-backends.js +++ b/test/parallel/test-common-wpt-backends.js @@ -73,7 +73,15 @@ async function collect(backend, throws) { }, }); - await handle.finished; + const watchdog = setTimeout( + common.mustNotCall(`The ${backend} WPT backend did not finish`), + common.platformTimeout(10_000), + ); + try { + await handle.finished; + } finally { + clearTimeout(watchdog); + } return events; } From cf30b2e2c710a75c625dd82f8e575a9e39d7b1c8 Mon Sep 17 00:00:00 2001 From: Edy Silva Date: Tue, 18 Aug 2026 03:21:03 -0300 Subject: [PATCH 2/9] sqlite: reuse cached column names in statement all() and get() Signed-off-by: geeksilva97 PR-URL: https://github.com/nodejs/node/pull/65276 Reviewed-By: Colin Ihrig Reviewed-By: Matteo Collina Reviewed-By: Trivikram Kamat --- src/node_sqlite.cc | 83 ++++++++++++++++------------------------------ src/node_sqlite.h | 14 ++------ 2 files changed, 31 insertions(+), 66 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index d0da887062bd..5a0522ba4240 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -3182,10 +3182,11 @@ Maybe ExtractRowValues(Environment* env, } MaybeLocal StatementExecutionHelper::All(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool return_arrays, - bool use_big_ints) { + StatementSync* statement) { + DatabaseSync* db = statement->db_.get(); + sqlite3_stmt* stmt = statement->statement_.get(); + const bool return_arrays = statement->return_arrays_; + const bool use_big_ints = statement->use_big_ints_; Isolate* isolate = env->isolate(); EscapableHandleScope scope(isolate); int r; @@ -3211,13 +3212,10 @@ MaybeLocal StatementExecutionHelper::All(Environment* env, rows.emplace_back(row_array); } else { if (row_keys.size() == 0) { - row_keys.reserve(num_cols); - for (int i = 0; i < num_cols; ++i) { - Local key; - if (!ColumnNameToName(env, stmt, i).ToLocal(&key)) { - return MaybeLocal(); - } - row_keys.emplace_back(key); + // Reuses the statement's internalized column names instead of + // re-interning them on every call. + if (!statement->GetCachedColumnNames(&row_keys)) { + return MaybeLocal(); } } DCHECK_EQ(row_keys.size(), row_values.size()); @@ -3232,9 +3230,10 @@ MaybeLocal StatementExecutionHelper::All(Environment* env, } MaybeLocal StatementExecutionHelper::Run(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool use_big_ints) { + StatementSync* statement) { + DatabaseSync* db = statement->db_.get(); + sqlite3_stmt* stmt = statement->statement_.get(); + const bool use_big_ints = statement->use_big_ints_; Isolate* isolate = env->isolate(); EscapableHandleScope scope(isolate); // Declared before the reset below so that it outlives it: sqlite3_reset() @@ -3319,10 +3318,11 @@ BaseObjectPtr StatementExecutionHelper::Iterate( } MaybeLocal StatementExecutionHelper::Get(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool return_arrays, - bool use_big_ints) { + StatementSync* statement) { + DatabaseSync* db = statement->db_.get(); + sqlite3_stmt* stmt = statement->statement_.get(); + const bool return_arrays = statement->return_arrays_; + const bool use_big_ints = statement->use_big_ints_; Isolate* isolate = env->isolate(); EscapableHandleScope scope(isolate); // Declared before the reset below so that it outlives it: sqlite3_reset() @@ -3360,13 +3360,10 @@ MaybeLocal StatementExecutionHelper::Get(Environment* env, result = Array::New(isolate, row_values.data(), row_values.size()); } else { LocalVector keys(isolate); - keys.reserve(num_cols); - for (int i = 0; i < num_cols; ++i) { - Local key; - if (!ColumnNameToName(env, stmt, i).ToLocal(&key)) { - return MaybeLocal(); - } - keys.emplace_back(key); + // Reuses the statement's internalized column names instead of + // re-interning them on every call. + if (!statement->GetCachedColumnNames(&keys)) { + return MaybeLocal(); } DCHECK_EQ(keys.size(), row_values.size()); @@ -3399,12 +3396,7 @@ void StatementSync::All(const FunctionCallbackInfo& args) { if (needs_reset) sqlite3_reset(stmt->statement_.get()); }); Local result; - if (StatementExecutionHelper::All(env, - stmt->db_.get(), - stmt->statement_.get(), - stmt->return_arrays_, - stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::All(env, stmt).ToLocal(&result)) { RESET_AND_CHECK( isolate, stmt->db_.get(), stmt->statement_.get(), needs_reset, void()); args.GetReturnValue().Set(result); @@ -3452,12 +3444,7 @@ void StatementSync::Get(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Get(env, - stmt->db_.get(), - stmt->statement_.get(), - stmt->return_arrays_, - stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::Get(env, stmt).ToLocal(&result)) { args.GetReturnValue().Set(result); } } @@ -3478,9 +3465,7 @@ void StatementSync::Run(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Run( - env, stmt->db_.get(), stmt->statement_.get(), stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::Run(env, stmt).ToLocal(&result)) { args.GetReturnValue().Set(result); } } @@ -3821,9 +3806,7 @@ void SQLTagStore::Run(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Run( - env, stmt->db_.get(), stmt->statement_.get(), stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::Run(env, stmt.get()).ToLocal(&result)) { args.GetReturnValue().Set(result); } } @@ -3881,12 +3864,7 @@ void SQLTagStore::Get(const FunctionCallbackInfo& args) { } Local result; - if (StatementExecutionHelper::Get(env, - stmt->db_.get(), - stmt->statement_.get(), - stmt->return_arrays_, - stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::Get(env, stmt.get()).ToLocal(&result)) { args.GetReturnValue().Set(result); } } @@ -3918,12 +3896,7 @@ void SQLTagStore::All(const FunctionCallbackInfo& args) { if (needs_reset) sqlite3_reset(stmt->statement_.get()); }); Local result; - if (StatementExecutionHelper::All(env, - stmt->db_.get(), - stmt->statement_.get(), - stmt->return_arrays_, - stmt->use_big_ints_) - .ToLocal(&result)) { + if (StatementExecutionHelper::All(env, stmt.get()).ToLocal(&result)) { RESET_AND_CHECK( isolate, stmt->db_.get(), stmt->statement_.get(), needs_reset, void()); args.GetReturnValue().Set(result); diff --git a/src/node_sqlite.h b/src/node_sqlite.h index 475a759e75e8..705cefb1811b 100644 --- a/src/node_sqlite.h +++ b/src/node_sqlite.h @@ -178,14 +178,9 @@ using StatementPtr = DeleteFnPtr; class StatementExecutionHelper { public: static v8::MaybeLocal All(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool return_arrays, - bool use_big_ints); + StatementSync* statement); static v8::MaybeLocal Run(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool use_big_ints); + StatementSync* statement); static BaseObjectPtr Iterate( Environment* env, BaseObjectPtr stmt); static v8::MaybeLocal ColumnToValue(Environment* env, @@ -196,10 +191,7 @@ class StatementExecutionHelper { sqlite3_stmt* stmt, const int column); static v8::MaybeLocal Get(Environment* env, - DatabaseSync* db, - sqlite3_stmt* stmt, - bool return_arrays, - bool use_big_ints); + StatementSync* statement); }; class DatabaseSync; From ba8cdc25941dcad68dabe866dea39ae041083842 Mon Sep 17 00:00:00 2001 From: Yuya Inoue <65857152+inoway46@users.noreply.github.com> Date: Tue, 18 Aug 2026 16:04:36 +0900 Subject: [PATCH 3/9] doc: add missing return types in buffer.md Add return types for Blob methods and legacy Base64 helpers so doc-kit does not render them as `void`. Refs: nodejs/doc-kit#953 Signed-off-by: inoway46 PR-URL: https://github.com/nodejs/node/pull/65308 Refs: https://github.com/nodejs/doc-kit/issues/953 Reviewed-By: Luigi Pinca Reviewed-By: Trivikram Kamat --- doc/api/buffer.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/api/buffer.md b/doc/api/buffer.md index 05d8113ace68..7d4a70a37877 100644 --- a/doc/api/buffer.md +++ b/doc/api/buffer.md @@ -536,6 +536,8 @@ added: - v20.16.0 --> +* Returns: {Promise} + The `blob.bytes()` method returns the byte of the `Blob` object as a `Promise`. ```js @@ -566,6 +568,7 @@ added: * `start` {number} The starting index. * `end` {number} The ending index. * `type` {string} The content-type for the new `Blob` +* Returns: {Blob} Creates and returns a new `Blob` containing a subset of this `Blob` objects data. The original `Blob` is not altered. @@ -5278,6 +5281,7 @@ added: > Stability: 3 - Legacy. Use `Buffer.from(data, 'base64')` instead. * `data` {any} The Base64-encoded input string. +* Returns: {string} Decodes a string of Base64-encoded data into bytes, and encodes those bytes into a string using Latin-1 (ISO-8859-1). @@ -5308,6 +5312,7 @@ added: > Stability: 3 - Legacy. Use `buf.toString('base64')` instead. * `data` {any} An ASCII (Latin1) string. +* Returns: {string} Decodes a string into bytes using Latin-1 (ISO-8859), and encodes those bytes into a string using Base64. From 205ef76ba3df6a8f3f4dfa09f8582e850c0af9ea Mon Sep 17 00:00:00 2001 From: Chaseton Collins <43923165+chasetonco@users.noreply.github.com> Date: Tue, 18 Aug 2026 03:04:46 -0400 Subject: [PATCH 4/9] doc: add missing return types in fs.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three entries in the fs documentation described their return value only in prose, or not at all, so doc-kit could not parse a return type and fell back to `void`: * `filehandle[Symbol.asyncDispose]()` and `dir[Symbol.asyncDispose]()` both return a promise, matching the existing `Returns: {Promise}` annotations on other async dispose methods. * `new fs.Utf8Stream([options])` is a constructor and returns an instance of the class. Verified at runtime and by rendering the page locally with doc-kit. Refs: https://github.com/nodejs/doc-kit/issues/953 Signed-off-by: Chxxeton <43923165+Chxxeton@users.noreply.github.com> PR-URL: https://github.com/nodejs/node/pull/65307 Reviewed-By: James M Snell Reviewed-By: Luigi Pinca Reviewed-By: Aviv Keller Reviewed-By: Ulises Gascón --- doc/api/fs.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/api/fs.md b/doc/api/fs.md index f95b1d85abec..7c10d68c38f6 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1191,6 +1191,8 @@ changes: description: No longer experimental. --> +* Returns: {Promise} + Calls `filehandle.close()` and returns a promise that fulfills when the filehandle is closed. @@ -7351,6 +7353,8 @@ changes: description: No longer experimental. --> +* Returns: {Promise} + Calls `dir.close()` if the directory handle is open, and returns a promise that fulfills when disposal is complete. @@ -8416,6 +8420,7 @@ of bytes written is passed as the first argument to the event handler. * `writeBufferLen` {number} * `remainingBufferLen`: {number} * `sync`: {boolean} Perform writes synchronously. +* Returns: {fs.Utf8Stream} #### `utf8Stream.append` From 5242e13e1946d48049d9d09dffecec771463fcc0 Mon Sep 17 00:00:00 2001 From: Seongeun Lee Date: Tue, 18 Aug 2026 16:04:55 +0900 Subject: [PATCH 5/9] doc: document per-architecture fast FFI argument limits The prior text covered only two of the seven supported architectures and conflated x86-64 SysV with the stricter Win64 emitter. Signed-off-by: leah-1ee PR-URL: https://github.com/nodejs/node/pull/65207 Reviewed-By: Paolo Insogna --- doc/api/ffi.md | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/doc/api/ffi.md b/doc/api/ffi.md index 158aadffa3e3..54de34da7a18 100644 --- a/doc/api/ffi.md +++ b/doc/api/ffi.md @@ -126,13 +126,26 @@ raw pointer `bigint` values. For pointer-like parameters, `null`, `undefined`, strings, `Buffer`, typed array, `DataView`, and `ArrayBuffer` values are converted on the JavaScript side before calling the optimized native wrapper. -Optimized Fast FFI calls support at most 8 function arguments, but the exact -limit depends on the architecture and on the argument types, because each -argument must fit in the registers used by the platform trampoline. Integer -and pointer arguments are limited to 7 on AArch64 and to 6 on x86-64, while -floating-point arguments can use up to 8 on both. Functions that exceed these -limits, including any function with more than 8 arguments, use the generic FFI -call path instead. +Optimized Fast FFI calls fall back to the generic FFI call path when a +function's arguments or return type do not fit the platform-specific fast +trampoline. Fast FFI calls support at most 8 total arguments, and the +register and argument limits differ per architecture: + +| Architecture | Max integer/pointer args | Max floating-point args | Buffer-shaped args | Buffer-shaped + FP together | Narrow (8/16-bit) return | +| -------------------------- | ----------------------------------------- | ----------------------- | ------------------ | --------------------------- | ------------------------ | +| AArch64 | 7 (6 when a buffer-shaped arg is present) | 8 | Supported | Not supported | Supported | +| x86-64, Linux/macOS (SysV) | 6 (4 when a buffer-shaped arg is present) | 8 | Supported | Not supported | Supported | +| x86-64, Windows (Win64) | 3 (total arguments also capped at 3) | 3 | Not supported | N/A | Supported | +| s390x | 4 | 4 | Not supported | N/A | Not supported | +| PPC64LE | 7 | 8 | Not supported | N/A | Not supported | +| LoongArch64 | 7 | 8 | Not supported | N/A | Not supported | +| RISC-V (64-bit) | 7 | 8 | Not supported | N/A | Not supported | + +PPC64BE has no fast-call trampoline and always uses the generic call path. +"Buffer-shaped args" means `Buffer`, typed array, `DataView`, or `ArrayBuffer` +values passed as pointer-like arguments. Functions whose argument or return +types exceed the limits for the current platform use the generic FFI call +path instead. ## Signature objects From 16c06b896c2b07aaf00a6636d3f5c5073fa437f2 Mon Sep 17 00:00:00 2001 From: Erik Demaine Date: Tue, 18 Aug 2026 03:05:05 -0400 Subject: [PATCH 6/9] doc: document setRawMode write access on Windows Fixes: https://github.com/nodejs/node/issues/63852 Signed-off-by: Erik Demaine PR-URL: https://github.com/nodejs/node/pull/63856 Reviewed-By: Stefan Stojanovic Reviewed-By: Trivikram Kamat --- doc/api/tty.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/api/tty.md b/doc/api/tty.md index 03f86cd66052..cbfb3cc78377 100644 --- a/doc/api/tty.md +++ b/doc/api/tty.md @@ -86,6 +86,11 @@ characters. Ctrl+C will no longer cause a `SIGINT` when in this mode. This mode does not affect terminal output processing, such as newline translation on Unix terminals. +On Windows, `setRawMode()` requires write permission to the console input +buffer. When opening `"\\\\.\\CONIN$"` with the [`fs.open()`][] family of APIs +(for passing into `new tty.ReadStream()`), be sure to use a read/write flag +such as `'r+'`. + ## Class: `tty.WriteStream`