fix(core): pass transient FFI buffers directly - #1394
Merged
Merged
Conversation
simonklee
approved these changes
Aug 20, 2026
carsteneu
added a commit
to carsteneu/opentui
that referenced
this pull request
Aug 20, 2026
…deps, embedded terminal, FFI buffer types - zig.ts: kept wave5 staged binding (opentuiSymbolDefs 411 = 395 ours + 16 embeddedTerminal), adopted upstream descriptor changes (ptr->buffer anomalyco#1394, destroyRenderer +flushInput) - console.ts: refcount activate() combined with upstream OTUI_USE_CONSOLE env gate - package.json/.gitignore/.oxfmtrc: upstream native-package layout + our wave3 gates - renderer.console-startup.test: both our refcount tests and upstream env-gate test
carsteneu
pushed a commit
to carsteneu/opentui
that referenced
this pull request
Aug 20, 2026
## Summary - use `buffer` ABI parameters and pass typed-array owners directly for transient synchronous Bun FFI calls - lower portable `buffer` parameters to Node's stable `pointer` path while still passing owner objects directly - keep `ptr` only for nullable, mixed native-pointer, raw `ArrayBuffer`, callback, and retained-memory cases - stabilize retained text-memory views through `.buffer` before resolving their native address - preserve raw-pointer compatibility while allowing direct buffers in supersample, packed-buffer, matrix, and grayscale APIs - document the Bun 1.3.14 and Bun 1.4+ ownership rules in `AGENTS.md` ## Why A Bun `FastTypedArray` may store its data inline. Calling `ptr(view)` captures that address, but a later first access to `view.buffer` can move the data into separate `ArrayBuffer` storage and leave the native address stale. Passing the owner directly lets the FFI backend borrow the current storage for synchronous calls and allows Bun's `buffer` fast path to keep the owner visible to the JIT. This keeps nullable and true native-pointer parameters on `ptr`, where `buffer` cannot represent the ABI, while avoiding pre-resolved addresses for transient memory. Retained pointers explicitly materialize stable backing storage before `ptr(view)` and keep the view alive for the native lifetime. Node 26.4's Linux optimized `buffer` trampoline delivered a null pointer to a multi-argument audio call in CI. OpenTUI therefore maps its portable `buffer` descriptor to Node `pointer`, whose documented owner-borrowing path passes the same views correctly. Bun continues to receive the `buffer` descriptor. Related Bun investigation: oven-sh/bun#32054 and oven-sh/bun#32055. ## Testing - `bunx bun@1.3.14 test src/tests/ffi-borrowed-pointer-callsites.test.ts` (23 passed) - `bun test src/tests/ffi-borrowed-pointer-callsites.test.ts` on Bun 1.4 canary (23 passed) - `bun run test:js` (5,397 passed, 23 skipped) - `bun run test:js:node` with Node 26.4.0 (4,665 passed, 6 skipped) - `bun run test:dist` - `bun run build:lib` - `bun run fmt:check` - `bun run lint`
carsteneu
added a commit
to carsteneu/opentui
that referenced
this pull request
Aug 20, 2026
…deps, embedded terminal, FFI buffer types - zig.ts: kept wave5 staged binding (opentuiSymbolDefs 411 = 395 ours + 16 embeddedTerminal), adopted upstream descriptor changes (ptr->buffer anomalyco#1394, destroyRenderer +flushInput) - console.ts: refcount activate() combined with upstream OTUI_USE_CONSOLE env gate - package.json/.gitignore/.oxfmtrc: upstream native-package layout + our wave3 gates - renderer.console-startup.test: both our refcount tests and upstream env-gate test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
bufferABI parameters and pass typed-array owners directly for transient synchronous Bun FFI callsbufferparameters to Node's stablepointerpath while still passing owner objects directlyptronly for nullable, mixed native-pointer, rawArrayBuffer, callback, and retained-memory cases.bufferbefore resolving their native addressAGENTS.mdWhy
A Bun
FastTypedArraymay store its data inline. Callingptr(view)captures that address, but a later first access toview.buffercan move the data into separateArrayBufferstorage and leave the native address stale. Passing the owner directly lets the FFI backend borrow the current storage for synchronous calls and allows Bun'sbufferfast path to keep the owner visible to the JIT.This keeps nullable and true native-pointer parameters on
ptr, wherebuffercannot represent the ABI, while avoiding pre-resolved addresses for transient memory. Retained pointers explicitly materialize stable backing storage beforeptr(view)and keep the view alive for the native lifetime.Node 26.4's Linux optimized
buffertrampoline delivered a null pointer to a multi-argument audio call in CI. OpenTUI therefore maps its portablebufferdescriptor to Nodepointer, whose documented owner-borrowing path passes the same views correctly. Bun continues to receive thebufferdescriptor.Related Bun investigation: oven-sh/bun#32054 and oven-sh/bun#32055.
Testing
bunx bun@1.3.14 test src/tests/ffi-borrowed-pointer-callsites.test.ts(23 passed)bun test src/tests/ffi-borrowed-pointer-callsites.test.tson Bun 1.4 canary (23 passed)bun run test:js(5,397 passed, 23 skipped)bun run test:js:nodewith Node 26.4.0 (4,665 passed, 6 skipped)bun run test:distbun run build:libbun run fmt:checkbun run lint