ReviewOS

zig-utils/zig-js

ABI: implement generated native ArrayBuffer backing handles

#257
Closed chris opened this 9 days ago ·
9 days ago

Parent: #140 Tracked by: #134, #163, #164 Depends on: #256 for adjacent direct JS-value mapping semantics

Implement the three pinned opaque JSC::ArrayBuffer* exports together with the generated-binding producer that supplies their initial adopted reference. The pinned producer contract is IDLArrayBufferRef conversion to RefPtr<JSC::ArrayBuffer>, followed by ExternTraits<RefPtr<...>>::convertToExtern(...).leakRef(); the Zig/Rust consumer adopts that existing +1.

Acceptance

  • Pin and document the actual IDLArrayBufferRef → RefPtr → leakRef() producer path from the checked-in Home/Bun revisions; do not invent a JS-cell-pointer handle.
  • Provide a separately refcounted backing-store handle whose initial +1 is created by the generated-binding adapter and whose bytes can outlive the originating JS wrapper, realm, and VM as upstream JSC::ArrayBuffer can.
  • Implement JSC__ArrayBuffer__ref and JSC__ArrayBuffer__deref with thread-safe balanced ownership, overflow/underflow protection, and exactly-once backing/deallocator release at zero.
  • Implement JSC__ArrayBuffer__asBunArrayBuffer with the exact 40-byte output layout: current pointer, byte length in both length fields, empty encoded value, profile-selected ArrayBuffer tag, and exact shared/resizable flags.
  • Preserve shared/resizable backing semantics and ensure external/no-copy backing callbacks wait for the last JS or native owner.
  • Add a generated bindgen compile-link-runtime fixture that obtains the handle through the real conversion path, adopts/clones/drops it through required and optional/union fields, survives JS GC/context teardown, and verifies projection before final release.
  • Mark all three exports implemented in both inventories, preserve zero unclassified entries, and update the README/private ABI evidence.

Design constraint

Retaining an entire realm or fabricating a test-only producer is not completion. The opaque handle models the backing store and its transferred +1, not a JavaScript wrapper cell.

Evidence

Completed on main in runtime commit 1318a1e6 with documentation in dd48a529.

  • Pinned Home/Bun IDLArrayBufferRef -> RefPtr<JSC::ArrayBuffer> -> leakRef() source hashes are recorded in docs/abi/array-buffer-handle-contract.json.
  • The generated producer, atomic native ownership, exact 40-byte projection, shared/resizable semantics, teardown survival, and exactly-once external finalization are covered by focused runtime tests.
  • Full suite: 988/988 passed, zero skipped, zero failed, zero leaked.
  • Generated Home consumer: 274/274 symbols linked; runtime matrix passed.
  • Home inventory: 272/431 implemented, 159 pending, zero unclassified.
  • Bun core inventory: 264/421 implemented, 157 pending, zero unclassified.
  • Public/private export audit: 117 public functions complete and 280 classified private profile exports.
  • The committed 1,540-sample benchmark matrix remains current because this embedding-only path is outside its workloads.
9 days ago

Implemented and documented on main in 1318a1e6 and dd48a529. All acceptance gates are green: 988/988 full tests, 274/274 generated consumer symbols, exact pinned producer/layout contract, zero inventory drift, and zero unclassified entries.

Sign in to comment on this issue.