Skip to content

docs(ffi): document viewSource, read.intptr, void/usize/isize and the cc include option; call CFunction without new - #38386

Open
robobun wants to merge 1 commit into
mainfrom
farm/11c4c75e/ffi-docs-remainder
Open

docs(ffi): document viewSource, read.intptr, void/usize/isize and the cc include option; call CFunction without new#38386
robobun wants to merge 1 commit into
mainfrom
farm/11c4c75e/ffi-docs-remainder

Conversation

@robobun

@robobun robobun commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

Closes #31534. Supersedes #31535, which carried the same docs fixes plus runtime changes that have since landed or become moot (see below).

Problem

  • Incomplete API coverage and discrepancies in bun:ffi #31534 lists gaps between docs/runtime/ffi.mdx and what bun:ffi exports. bun:ffi: use the engine-native FFI when available #35246 rewrote the page and covered some of them: cc() is linked to its own page, int is in the FFIType table, and napi_env/napi_value now have a paragraph and are marked cc() only in the table.
  • Still wrong or missing on main:
    • void, usize, isize are absent from the FFIType table (docs/runtime/ffi.mdx and the copy in docs/runtime/c-compiler.mdx), while the Callbacks example on the same page uses "usize".
    • Both CFunction examples use new CFunction(...); CFunction is a plain function (src/js/bun/ffi.ts, function CFunction(options)), and packages/bun-types/ffi.d.ts declares it as one.
    • viewSource is not mentioned anywhere in docs/.
    • read.intptr is missing from the read table.
    • cc() accepts an include option (ffi.d.ts, ffi_body.rs reads options.include) that the cc reference on the C Compiler page does not list.

Fix

  • FFIType tables: add isize to the i64 row, usize to the u64 row, and a void row marked returns only, plus one sentence each on what that means (usize/isize return a bigint like u64/i64; void is the default return type and is rejected in args).
  • Drop new from both CFunction examples and say why in the sentence that introduces it.
  • Add a short viewSource section. Since bun:ffi: use the engine-native FFI when available #35246 only cc() compiles C, so the section describes what viewSource prints today: the per-symbol C wrapper that cc() compiles, one string per symbol, and a comment string for the callback form. This is deliberately different from the section in docs(ffi): cover cc, viewSource, Node-API types, and fix CFunction usage #31535, which described viewSource as showing the bindings dlopen compiles; that is no longer true.
  • Add read.intptr to the read table (header renamed from FFIType to Type, since intptr is a read helper and not an FFIType) with a sentence on how it differs from read.ptr.
  • C Compiler page: add include to the cc reference, next to define.
  • Every claim above was checked against the current bun:ffi (the FFI sources have not changed since the build used): "usize"/"isize" in dlopen, cc(), and JSCallback descriptors; returns: "void" and omitted returns; args: ["void"] throwing in dlopen, linkSymbols, CFunction, JSCallback, and cc(); CFunction(...) without new; read.intptr returning -5 where read.ptr returns 18446744073709552000 for the same bytes; the viewSource snippet as written (array of one C string, callback form returns a comment); the include snippet as written, with a cwd-relative directory, as an array and as a string, and failing without it.
  • Docs only; bun run prettier --check on both pages is clean.

Background

  • bun:ffi has two binding paths since bun:ffi: use the engine-native FFI when available #35246. dlopen, linkSymbols, CFunction, and JSCallback are implemented inside JavaScriptCore, which generates the argument marshalling itself. cc() still uses TinyCC: for each symbol it generates a small C wrapper (Function::print_source_code in src/runtime/ffi/ffi_body.rs) that unpacks the JS arguments, calls the user's function, and boxes the result, then compiles it. viewSource returns the output of that same printer, which is why the docs now describe it in terms of cc().
  • read.* are raw memory readers taking a pointer and byte offset. read.ptr and read.intptr both read 8 bytes into a JS number; ptr treats them as unsigned, intptr as a signed intptr_t (src/runtime/ffi/FFIObject.rs).
What happened to the rest of #31535
  • cc() reading symbol definitions from options[key] instead of options.symbols[key]: fixed on main (src/js/bun/ffi.ts, cc()).
  • napi_env/napi_value JS coercion wrappers and the numeric FFIType reverse-lookup keys: the JS coercion layer (ffiWrappers) they patched was removed in bun:ffi: use the engine-native FFI when available #35246, and the N-API types are now rejected outside cc(), so there is nothing left to fix.
  • size_t alias in the JS FFIType object and ffi.d.ts, and the new CFunction in the ffi.d.ts JSDoc example: not part of Incomplete API coverage and discrepancies in bun:ffi #31534 (the runtime already accepts the "size_t" string natively). Left out to keep this PR docs only; the ffi.d.ts gaps (isize/usize and several accepted string aliases missing from the type maps, plus that JSDoc example) are being handled separately.
  • The cc JSDoc example tweak (${hello()}): unnecessary now that cstring returns are plain strings.
  • bun:ffi: infer exact signatures from symbol definitions, fix cc argument/return conversions #32075, which carried the same runtime fixes, was closed without merging.

…lude; drop new from CFunction

The remaining items from #31534 that the ffi.mdx rewrite in #35246 did
not cover:

- FFIType tables (ffi.mdx and c-compiler.mdx): add the void row and the
  usize/isize aliases of u64/i64; note that void is returns-only.
- CFunction is a factory, so both examples call it without new.
- Add a short viewSource section describing what it prints now that only
  cc() generates C.
- Add read.intptr to the read table.
- c-compiler.mdx: document the include option of cc().
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@robobun, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 30 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ca1937ea-d476-43c2-9f10-067d28b101ad

📥 Commits

Reviewing files that changed from the base of the PR and between a0921e1 and fdd0414.

📒 Files selected for processing (2)
  • docs/runtime/c-compiler.mdx
  • docs/runtime/ffi.mdx

Comment @coderabbitai help to get the list of available commands.

@robobun

robobun commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator Author

Status: docs only, ready for review.

@claude claude Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM — docs-only additions to the FFI pages that match the current implementation.

What was reviewed:

  • usize/isizeUint64T/Int64T and void as an ABI type confirmed in src/runtime/ffi/abi_type.rs.
  • CFunction is declared function CFunction(options) in src/js/bun/ffi.ts, so dropping new is correct.
  • read.intptr exists in FFIObject.rs and ffi.d.ts; viewSource is exported from src/js/bun/ffi.ts.
  • cc() reads options.include in src/runtime/ffi/ffi_body.rs and passes each entry to add_sys_include_path.
Extended reasoning...

Overview

Docs-only change to two pages: docs/runtime/ffi.mdx and docs/runtime/c-compiler.mdx. Adds isize/usize/void rows to the FFIType tables, drops new from the two CFunction examples (with a sentence explaining why), adds a short viewSource section, adds read.intptr to the read table with a note distinguishing it from read.ptr, and adds the include option to the cc() reference on the C Compiler page. No runtime, type-declaration, or test changes.

Security risks

None. Documentation only; no code paths are touched.

Level of scrutiny

Low. Docs pages for an experimental module. The relevant question is whether the new prose matches the implementation, and each claim was spot-checked against source: abi_type.rs maps "usize"Uint64T and "isize"Int64T and defines Void; src/js/bun/ffi.ts defines function CFunction(options) (not a class) and exports viewSource; FFIObject.rs and ffi.d.ts both define read.intptr; ffi_body.rs reads options.include and feeds it to TinyCC's include path list. The PR description records that each behavioral claim was also verified by running it, and the wording is consistent with what the source shows.

Other factors

No CODEOWNERS entry covers docs/. No prior human review comments to address. The tables remain aligned and the prose follows the existing voice of the page. bun run prettier --check was reported clean by the author. The bug-hunting pass found nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incomplete API coverage and discrepancies in bun:ffi

1 participant