@@ -30,8 +30,18 @@ const ffi = require('node:ffi');
3030This module is only available under the ` node: ` scheme in builds with FFI
3131support and is gated by the ` --experimental-ffi ` flag.
3232
33- When using the [ Permission Model] [ ] , FFI APIs are restricted unless the
34- [ ` --allow-ffi ` ] [ ] flag is provided.
33+ Bundled libffi support currently targets:
34+
35+ * macOS on ` arm64 ` and ` x64 `
36+ * Windows on ` arm64 ` and ` x64 `
37+ * FreeBSD on ` arm ` , ` arm64 ` , and ` x64 `
38+ * Linux on ` arm ` , ` arm64 ` , and ` x64 `
39+
40+ Other targets require building Node.js against a shared libffi with
41+ ` --shared-ffi ` . The unofficial GN build does not support ` node:ffi ` .
42+
43+ When using the [ Permission Model] ( permissions.md#permission-model ) , FFI APIs are
44+ restricted unless the [ ` --allow-ffi ` ] ( cli.md#--allow-ffi ) flag is provided.
3545
3646## Overview
3747
@@ -69,6 +79,16 @@ Supported type names:
6979Pointer-like types (` pointer ` , ` string ` , ` buffer ` , ` arraybuffer ` , and
7080` function ` ) are all passed through the native layer as pointers.
7181
82+ When ` Buffer ` , ` ArrayBuffer ` , or typed array values are passed as pointer-like
83+ arguments, Node.js borrows a raw pointer to their backing memory for the
84+ duration of the native call. The caller must ensure that backing store remains
85+ valid and stable for the entire call.
86+
87+ It is unsupported and dangerous to resize, transfer, detach, or otherwise
88+ invalidate that backing store while the native call is active, including
89+ through reentrant JavaScript such as FFI callbacks. Doing so may crash the
90+ process, produce incorrect output, or corrupt memory.
91+
7292The ` char ` type follows the platform C ABI. On platforms where plain C ` char `
7393is signed it behaves like ` i8 ` ; otherwise it behaves like ` u8 ` .
7494
@@ -220,6 +240,10 @@ behavior, is not allowed, and is dangerous: it can crash the process, produce
220240incorrect output, or corrupt memory. Native code must stop using callback
221241addresses before the library is closed or before the callback is unregistered.
222242
243+ Calling ` library.close() ` from one of the library's active callbacks is
244+ unsupported and dangerous. The callback must return before the library is
245+ closed.
246+
223247### ` library.getFunction(name, signature) `
224248
225249* ` name ` {string}
@@ -301,13 +325,23 @@ Callbacks are subject to the following restrictions:
301325* They must not throw exceptions.
302326* They must not return promises.
303327* They must return a value compatible with the declared result type.
328+ * They must not call ` library.close() ` on their owning library while running.
329+ * They must not unregister themselves while running.
330+
331+ Closing the owning library or unregistering the currently executing callback
332+ from inside the callback is unsupported and dangerous. Doing so may crash the
333+ process, produce incorrect output, or corrupt memory.
304334
305335### ` library.unregisterCallback(pointer) `
306336
307337* ` pointer ` {bigint}
308338
309339Releases a callback previously created with ` library.registerCallback() ` .
310340
341+ Calling ` library.unregisterCallback(pointer) ` for a callback that is currently
342+ executing is unsupported and dangerous. The callback must return before it is
343+ unregistered.
344+
311345After ` library.unregisterCallback(pointer) ` returns, invoking that callback
312346pointer from native code has undefined behavior, is not allowed, and is
313347dangerous: it can crash the process, produce incorrect output, or corrupt
@@ -476,7 +510,8 @@ When `copy` is `false`, the returned `ArrayBuffer` references the original
476510native memory directly.
477511
478512The same lifetime and bounds requirements described for
479- [ ` ffi.toBuffer() ` ] [ ] apply here. With ` copy: false ` , the
513+ [ ` ffi.toBuffer(pointer, length[, copy]) ` ] ( #ffitobufferpointer-length-copy ) apply
514+ here. With ` copy: false ` , the
480515returned ` ArrayBuffer ` is a zero-copy view of foreign memory and is only safe
481516while that memory remains allocated, unchanged in layout, and valid for the
482517entire exposed range.
@@ -492,10 +527,12 @@ added: REPLACEME
492527* ` length ` {number}
493528* ` encoding ` {string} ** Default:** ` 'utf8' ` .
494529
495- Copies a JavaScript string into native memory and appends a trailing NUL byte
496- when space is available .
530+ Copies a JavaScript string into native memory and appends a trailing NUL
531+ terminator .
497532
498- If ` length ` is too small, the string is truncated to fit.
533+ ` length ` must be large enough to hold the full encoded string plus the trailing
534+ NUL terminator. For UTF-16 and UCS-2 encodings, the trailing terminator uses
535+ two zero bytes.
499536
500537` pointer ` must refer to writable native memory with at least ` length ` bytes of
501538available storage. This function does not allocate memory on its own.
@@ -514,8 +551,7 @@ added: REPLACEME
514551
515552Copies bytes from a ` Buffer ` into native memory.
516553
517- If ` length ` is smaller than ` buffer.length ` , only the first ` length ` bytes are
518- copied.
554+ ` length ` must be at least ` buffer.length ` .
519555
520556` pointer ` must refer to writable native memory with at least ` length ` bytes of
521557available storage. This function does not allocate memory on its own.
@@ -542,7 +578,3 @@ In particular:
542578
543579As a general rule, prefer copied values unless zero-copy access is required,
544580and keep callback and pointer lifetimes explicit on the native side.
545-
546- [ Permission Model ] : permissions.md#permission-model
547- [ `--allow-ffi` ] : cli.md#--allow-ffi
548- [ `ffi.toBuffer()` ] : #ffitobufferpointer-length-copy
0 commit comments