Skip to content

Commit 0b2e2e5

Browse files
authored
Merge branch 'main' into mert/create-logger-api/node-core
2 parents f2d9074 + dd6a0b5 commit 0b2e2e5

56 files changed

Lines changed: 2454 additions & 319 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/dependabot.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ updates:
5252
semver-major-days: 5
5353
semver-minor-days: 5
5454
semver-patch-days: 5
55+
exclude:
56+
- '@node-core/doc-kit'
5557
commit-message:
5658
prefix: tools
5759
open-pull-requests-limit: 10

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -747,8 +747,6 @@ maintaining the Node.js project.
747747
**Sangchul Lee** <<[email protected]>> (he/him)
748748
* [atlowChemi](https://github.com/atlowChemi) -
749749
**Chemi Atlow** <<[email protected]>> (he/him)
750-
* [Ayase-252](https://github.com/Ayase-252) -
751-
**Qingyu Deng** <<[email protected]>>
752750
* [bjohansebas](https://github.com/bjohansebas) -
753751
**Sebastian Beltran** <<[email protected]>>
754752
* [bmuenzenmeyer](https://github.com/bmuenzenmeyer) -
@@ -773,8 +771,6 @@ maintaining the Node.js project.
773771
**Kevin Eady** <<[email protected]>> (he/him)
774772
* [marsonya](https://github.com/marsonya) -
775773
**Akhil Marsonya** <<[email protected]>> (he/him)
776-
* [meixg](https://github.com/meixg) -
777-
**Xuguang Mei** <<[email protected]>> (he/him)
778774
* [milesguicent](https://github.com/milesguicent) -
779775
**Miles Guicent** <<[email protected]>> (he/him)
780776
* [preveen-stack](https://github.com/preveen-stack) -

benchmark/ffi/getpid.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
'use strict';
2+
3+
const common = require('../common.js');
4+
const ffi = require('node:ffi');
5+
6+
const bench = common.createBenchmark(main, {
7+
n: [1e7],
8+
}, {
9+
flags: ['--experimental-ffi'],
10+
});
11+
12+
const { lib, functions } = ffi.dlopen(null, {
13+
uv_os_getpid: { result: 'i32', parameters: [] },
14+
});
15+
16+
const getpid = functions.uv_os_getpid;
17+
18+
function main({ n }) {
19+
bench.start();
20+
for (let i = 0; i < n; ++i)
21+
getpid();
22+
bench.end(n);
23+
24+
lib.close();
25+
}

common.gypi

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
'python%': 'python',
1616

1717
'node_shared%': 'false',
18+
'node_enable_experimentals%': 'false',
1819
'force_dynamic_crt%': 0,
1920
'node_use_v8_platform%': 'true',
2021
'node_use_bundled_v8%': 'true',
@@ -437,6 +438,9 @@
437438
}],
438439
# The defines bellow must include all things from the external_v8_defines
439440
# list in v8/BUILD.gn.
441+
['node_enable_experimentals == "true"', {
442+
'defines': ['EXPERIMENTALS_DEFAULT_VALUE=true'],
443+
}],
440444
['v8_enable_v8_checks == 1', {
441445
'defines': ['V8_ENABLE_CHECKS'],
442446
}],

configure.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,12 @@
797797
default=None,
798798
help='Enable the --trace-maps flag in V8 (use at your own risk)')
799799

800+
parser.add_argument('--enable-all-experimentals',
801+
action='store_true',
802+
dest='enable_all_experimentals',
803+
default=None,
804+
help='Enable all experimental features by default')
805+
800806
parser.add_argument('--experimental-enable-pointer-compression',
801807
action='store_true',
802808
dest='enable_pointer_compression',
@@ -1803,6 +1809,7 @@ def configure_node_cctest_sources(o):
18031809
def configure_node(o):
18041810
if options.dest_os == 'android':
18051811
o['variables']['OS'] = 'android'
1812+
o['variables']['node_enable_experimentals'] = b(options.enable_all_experimentals)
18061813
o['variables']['node_prefix'] = options.prefix
18071814
o['variables']['node_install_npm'] = b(not options.without_npm)
18081815
o['variables']['node_install_corepack'] = b(options.with_corepack)

doc/api/debugger.md

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,157 @@ steps to the next line. Type `help` to see what other commands are available.
9090
Pressing `enter` without typing a command will repeat the previous debugger
9191
command.
9292

93+
## Probe mode
94+
95+
<!-- YAML
96+
added:
97+
- REPLACEME
98+
-->
99+
100+
> Stability: 1 - Experimental
101+
102+
`node inspect` supports a non-interactive probe mode for inspecting runtime values
103+
in an application via the flag `--probe`. Probe mode launches the application,
104+
sets one or more source breakpoints, evaluates one expression whenever a
105+
matching breakpoint is hit, and prints one final report when the session ends
106+
(either on normal completion or timeout). This allows developers to perform
107+
printf-style debugging without having to modify the application code and
108+
clean up afterwards, and it supports structured output for tool use.
109+
110+
```console
111+
$ node inspect [--json] [--preview] [--timeout=<ms>] [--port=<port>] \
112+
--probe app.js:10 --expr 'x' \
113+
[--probe app.js:20 --expr 'y' ...] \
114+
[--] [<node-option> ...] <script.js> [args...]
115+
```
116+
117+
* `--probe <file>:<line>[:<col>]`: Source location to probe. Line and column number
118+
are 1-based.
119+
* `--timeout=<ms>`: A global wall-clock deadline for the entire probe session.
120+
The default is `30000`. This can be used to probe a long-running application
121+
that can be terminated externally.
122+
* `--json`: If used, prints a structured JSON report instead of the default text report.
123+
* `--preview`: If used, non-primitive values will include CDP property previews for
124+
object-like JSON probe values.
125+
* `--port=<port>`: Selects the local inspector port used for the `--inspect-brk`
126+
launch path. Probe mode defaults to `0`, which requests a random port.
127+
* `--` is optional unless the child needs its own Node.js flags.
128+
129+
Additional rules about the `--probe` and `--expr` arguments:
130+
131+
* `--probe <file>:<line>[:<col>]` and `--expr <expr>` are strict pairs. Each
132+
`--probe` must be followed immediately by exactly one `--expr`.
133+
* `--timeout`, `--json`, `--preview`, and `--port` are global probe options
134+
for the whole probe session. They may appear before or between probe pairs,
135+
but not between a `--probe` and its matching `--expr`.
136+
137+
If a single probe needs to evaluate more than one value,
138+
evaluate a structured value in `--expr`, for example `--expr "{ foo, bar }"`
139+
or `--expr "[foo, bar]"`, and use `--preview` to include property previews for
140+
any object-like values in the output.
141+
142+
Probe mode only prints the final probe report to stdout, and otherwise silences
143+
stdout/stderr from the child process. If the child exits with an error after the
144+
probe session starts, the final report records a terminal `error` event with the
145+
exit code and captured child stderr. Invalid arguments and fatal launch or
146+
connect failures may still print diagnostics to stderr without a final probe
147+
result.
148+
149+
Consider this script:
150+
151+
```js
152+
// cli.js
153+
let maxRSS = 0;
154+
for (let i = 0; i < 2; i++) {
155+
const { rss } = process.memoryUsage();
156+
maxRSS = Math.max(maxRSS, rss);
157+
}
158+
```
159+
160+
If `--json` is not used, the output is printed in a human-readable text format:
161+
162+
```console
163+
$ node inspect --probe cli.js:5 --expr 'rss' cli.js
164+
Hit 1 at cli.js:5
165+
rss = 54935552
166+
Hit 2 at cli.js:5
167+
rss = 55083008
168+
Completed
169+
```
170+
171+
Primitive results are printed directly, while objects and arrays use Chrome
172+
DevTools Protocol preview data when available. Other non-primitive values
173+
fall back to the Chrome DevTools Protocol `description` string.
174+
Expression failures are recorded as `[error] ...` lines and do not fail
175+
the overall session. If richer text formatting is needed, wrap the expression
176+
in `JSON.stringify(...)` or `util.inspect(...)`.
177+
178+
When `--json` is used, the output shape looks like this:
179+
180+
```console
181+
$ node inspect --json --probe cli.js:5 --expr 'rss' cli.js
182+
{"v":1,"probes":[{"expr":"rss","target":["cli.js",5]}],"results":[{"probe":0,"event":"hit","hit":1,"result":{"type":"number","value":55443456,"description":"55443456"}},{"probe":0,"event":"hit","hit":2,"result":{"type":"number","value":55574528,"description":"55574528"}},{"event":"completed"}]}
183+
```
184+
185+
```json
186+
{
187+
"v": 1, // Probe JSON schema version.
188+
"probes": [
189+
{
190+
"expr": "rss", // The expression paired with --probe.
191+
"target": ["cli.js", 5] // [file, line] or [file, line, col].
192+
}
193+
],
194+
"results": [
195+
{
196+
"probe": 0, // Index into probes[].
197+
"event": "hit", // Hit events are recorded in observation order.
198+
"hit": 1, // 1-based hit count for this probe.
199+
"result": {
200+
"type": "number",
201+
"value": 55443456,
202+
"description": "55443456"
203+
}
204+
// If the expression throws, "error" is present instead of "result".
205+
},
206+
{
207+
"probe": 0,
208+
"event": "hit",
209+
"hit": 2,
210+
"result": {
211+
"type": "number",
212+
"value": 55574528,
213+
"description": "55574528"
214+
}
215+
},
216+
{
217+
"event": "completed"
218+
// The final entry is always a terminal event, for example:
219+
// 1. { "event": "completed" }
220+
// 2. { "event": "miss", "pending": [0, 1] }
221+
// 3. {
222+
// "event": "timeout",
223+
// "pending": [0],
224+
// "error": {
225+
// "code": "probe_timeout",
226+
// "message": "Timed out after 30000ms waiting for probes: app.js:10"
227+
// }
228+
// }
229+
// 4. {
230+
// "event": "error",
231+
// "pending": [0],
232+
// "error": {
233+
// "code": "probe_target_exit",
234+
// "exitCode": 1,
235+
// "stderr": "[Error: boom]",
236+
// "message": "Target exited with code 1 before probes: app.js:10"
237+
// }
238+
// }
239+
}
240+
]
241+
}
242+
```
243+
93244
## Watchers
94245

95246
It is possible to watch expression and variable values while debugging. On

doc/api/dns.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,15 @@ changes:
277277
* `callback` {Function}
278278
* `err` {Error}
279279
* `address` {string} A string representation of an IPv4 or IPv6 address.
280+
Not provided when `options.all` is `true`.
280281
* `family` {integer} `4` or `6`, denoting the family of `address`, or `0` if
281282
the address is not an IPv4 or IPv6 address. `0` is a likely indicator of a
282283
bug in the name resolution service used by the operating system.
284+
Not provided when `options.all` is `true`.
285+
* `addresses` {Object\[]} An array of address objects when `options.all` is
286+
`true`. Each object has the following properties:
287+
* `address` {string} A string representation of an IPv4 or IPv6 address.
288+
* `family` {integer} `4` or `6`, denoting the family of `address`.
283289

284290
Resolves a host name (e.g. `'nodejs.org'`) into the first found A (IPv4) or
285291
AAAA (IPv6) record. All `option` properties are optional. If `options` is an

doc/api/errors.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,24 @@ added: v14.0.0
13321332
Used when a feature that is not available
13331333
to the current platform which is running Node.js is used.
13341334

1335+
<a id="ERR_FFI_CALL_FAILED"></a>
1336+
1337+
### `ERR_FFI_CALL_FAILED`
1338+
1339+
A low-level FFI call failed.
1340+
1341+
<a id="ERR_FFI_INVALID_POINTER"></a>
1342+
1343+
### `ERR_FFI_INVALID_POINTER`
1344+
1345+
An invalid pointer was passed to an FFI operation.
1346+
1347+
<a id="ERR_FFI_LIBRARY_CLOSED"></a>
1348+
1349+
### `ERR_FFI_LIBRARY_CLOSED`
1350+
1351+
An operation was attempted on an FFI dynamic library after it was closed.
1352+
13351353
<a id="ERR_FS_CP_DIR_TO_NON_DIR"></a>
13361354

13371355
### `ERR_FS_CP_DIR_TO_NON_DIR`

doc/api/ffi.md

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,15 @@ const path = `libsqlite3.${suffix}`;
165165
added: REPLACEME
166166
-->
167167

168-
* `path` {string} Path to a dynamic library.
168+
* `path` {string|null} Path to a dynamic library, or `null` to resolve symbols
169+
from the current process image.
169170
* `definitions` {Object} Symbol definitions to resolve immediately.
170171
* Returns: {Object}
171172

172173
Loads a dynamic library and resolves the requested function definitions.
173174

175+
On Windows passing `null` is not supported.
176+
174177
When `definitions` is omitted, `functions` is returned as an empty object until
175178
symbols are resolved explicitly.
176179

@@ -237,10 +240,13 @@ Represents a loaded dynamic library.
237240

238241
### `new DynamicLibrary(path)`
239242

240-
* `path` {string} Path to a dynamic library.
243+
* `path` {string|null} Path to a dynamic library, or `null` to resolve symbols
244+
from the current process image.
241245

242246
Loads the dynamic library without resolving any functions eagerly.
243247

248+
On Windows passing `null` is not supported.
249+
244250
```cjs
245251
const { DynamicLibrary } = require('node:ffi');
246252

@@ -603,6 +609,55 @@ available storage. This function does not allocate memory on its own.
603609

604610
`buffer` must be a Node.js `Buffer`.
605611

612+
## `ffi.exportArrayBuffer(arrayBuffer, pointer, length)`
613+
614+
<!-- YAML
615+
added: REPLACEME
616+
-->
617+
618+
* `arrayBuffer` {ArrayBuffer}
619+
* `pointer` {bigint}
620+
* `length` {number}
621+
622+
Copies bytes from an `ArrayBuffer` into native memory.
623+
624+
`length` must be at least `arrayBuffer.byteLength`.
625+
626+
`pointer` must refer to writable native memory with at least `length` bytes of
627+
available storage. This function does not allocate memory on its own.
628+
629+
## `ffi.exportArrayBufferView(arrayBufferView, pointer, length)`
630+
631+
<!-- YAML
632+
added: REPLACEME
633+
-->
634+
635+
* `arrayBufferView` {ArrayBufferView}
636+
* `pointer` {bigint}
637+
* `length` {number}
638+
639+
Copies bytes from an `ArrayBufferView` into native memory.
640+
641+
`length` must be at least `arrayBufferView.byteLength`.
642+
643+
`pointer` must refer to writable native memory with at least `length` bytes of
644+
available storage. This function does not allocate memory on its own.
645+
646+
## `ffi.getRawPointer(source)`
647+
648+
<!-- YAML
649+
added: REPLACEME
650+
-->
651+
652+
* `source` {Buffer|ArrayBuffer|ArrayBufferView}
653+
* Returns: {bigint}
654+
655+
Returns the raw memory address of JavaScript-managed byte storage.
656+
657+
This is unsafe and dangerous. The returned pointer can become invalid if the
658+
underlying memory is detached, resized, transferred, or otherwise invalidated.
659+
Using stale pointers can cause memory corruption or process crashes.
660+
606661
## Safety notes
607662

608663
The `node:ffi` module does not track pointer validity, memory ownership, or

doc/api/n-api.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6569,11 +6569,13 @@ NAPI_EXTERN napi_status napi_get_uv_event_loop(node_api_basic_env env,
65696569
* `[in] env`: The environment that the API is invoked under.
65706570
* `[out] loop`: The current libuv loop instance.
65716571

6572-
Note: While libuv has been relatively stable over time, it does
6573-
not provide an ABI stability guarantee. Use of this function should be avoided.
6574-
Its use may result in an addon that does not work across Node.js versions.
6575-
[asynchronous-thread-safe-function-calls](https://nodejs.org/docs/latest/api/n-api.html#asynchronous-thread-safe-function-calls)
6576-
are an alternative for many use cases.
6572+
Note: While libuv only [guarantees ABI stability](https://github.com/libuv/libuv?tab=readme-ov-file#versioning)
6573+
in a major version, its use may result in an addon that does not work across
6574+
Node.js major versions.
6575+
6576+
[ThreadSafeFunction](#asynchronous-thread-safe-function-calls)
6577+
is an ABI-stable alternative for many use cases to calling into the
6578+
JavaScript thread from another thread.
65776579

65786580
## Asynchronous thread-safe function calls
65796581

0 commit comments

Comments
 (0)