ReviewOS

home-lang/home

Bun parity: implement actual internal async-context frame semantics

#871
Open chris opened this 8 days ago ·
8 days ago

The pinned internal/async_context_frame module is now included in Home-owned generation, but its implementation is explicitly a facade: enabled is true while current() always returns undefined. The source itself documents that this differs from materialized frame semantics.

Complete this using Home's actual native async-context ownership rather than reporting a fabricated frame:

  • Expose current frame identity and lifetime while preserving AsyncLocalStorage propagation.
  • Implement the frame operations required by imported Node internals with real enter/exit/restore semantics.
  • Preserve behavior across nested contexts, promises, callbacks, workers and context teardown.
  • Validate unchanged originals that consume the internal frame interface, alongside existing async-local-storage and native lifecycle gates.

Full registry ownership is not feature-completion credit for this facade. Parent tracker: #66.

8 days ago

Complete pinned JS registry ownership checkpoint (2026-10-10): source 089c4b281 and verified evidence. Home owns 157/157 pinned JS registry modules, zero missing/extra identities, plus the separately verified test adapter. Generation now rejects omissions/extras/duplicate identities before output, with a future-identity drift regression. This batch adds five modules and native X509 implementation/constructor/prototype ownership. 10/11 selected implementation/header files match the pin; WASI's buffer-identity refresh fixes stale writes after replacing WebAssembly.Memory. The valid native regression verifies hello-world wasm, arguments/environment, unchanged previous memory and growth. Nine unchanged originals: 22 registered passes plus six process checks, zero failures/skips/TODOs, and nine native groups pass. Full ABI: 122 tests / 1,856 assertions, peak 494 MB; its binary predates the one-line WASI repair, so final-binary generation/grammar/inventory controls additionally pass two tests / 596 assertions. Repaired Debug 35/35, peak 5,646 MB under 8,192 MB; final originals 279 MB under 3,840 MB. 128 committed archives verify and nine reports restore; initial WASI failure remains without passing credit. Registry ownership is not full API/native parity: actual async-frame semantics remain #871, and broader WASI/debugger/HTML, other native/API gaps, complete suite and Release/ASAN/all-platform verification remain unfinished.

8 days ago

AsyncLocalStorage lifecycle checkpoint (2026-10-10): source a3f36dcd0 and verified evidence. run() restores the actual outer context snapshot even when callbacks disable storage or replace context; exit() preserves disabled status and other storage instances. Callback validation precedes state mutation. The previous binary crashes after disable within run and fails the first-disabled-run store-leak regression; the repaired baseline matches local Node lifecycle rows. 14 unchanged originals: 37 registered passes plus ten process checks, zero failures/skips, two upstream TODOs; ten native groups, final generation/inventory controls two tests / 596 assertions, Debug 35/35 pass. Build peak 5,645 MB under 8,192 MB, originals 185 MB under 3,840 MB. 108 committed archives verify and 14 reports restore. Node async-hooks mode passes the native control; its newer frame mode retains captured stores after disable, so that backend distinction is recorded without universal parity claims. Original assertions/fixtures/deadlines are unchanged. TODOs are not passing credit. Actual frame materialization remains #871; createHook/native API gaps, complete suite and Release/ASAN/all-platform verification remain unfinished.

8 days ago

Async exit continuation checkpoint (2026-10-10): source b3583cb7f and verified evidence. exit() now removes its own storage entry from the context captured during its callback, preserving other stores and restoring the outer context afterward. The previous verified binary fails a valid promise continuation assertion; the repaired binary and Node control pass promises, nextTick and timers. Native captured wrappers also always take the unwrapping path before callable-data lookup, even if tracking is disabled. 14 unchanged originals: 37 passes plus ten process checks, zero failures/skips, two upstream TODOs; eleven native groups, generation/inventory two tests / 596 assertions and Debug 35/35 pass. Build peak 5,642 MB under 8,192 MB, originals 175 MB under 3,840 MB. 196 committed archives verify and 14 reports restore. Assertions/fixtures/deadlines remain unchanged. The attempted Map-frame integration still terminates natively and is not shipped; its source/failure evidence is retained, and the wrapper guard is not claimed to resolve that termination. Actual frame materialization remains #871. TODOs, createHook/native API gaps, complete suite and Release/ASAN/all-platform scope remain unfinished.

8 days ago

The next native frame tranche is under validation. The local implementation materializes Map views of the engine-owned continuation data, preserves current/exchange identity, synchronizes AsyncLocalStorage mutations and accepts explicit Map contexts. It does not return a fabricated frame from a separate active-context variable.

The corrected control passes on both Node v24.18.0 and v26.10.0. The retained, previously published Home executable fails at the missing frame constructor. The local native rebuild passes all 56 steps, but the final control traps during worker-to-parent microtask draining in JSC::JSPromise::fulfillPromise. That worker case remains required; the failed run receives no passing credit. Debugger investigation and the full original/lifecycle batch are pending.

Separate fresh #893/#878 probes confirm that Node's native conversion scopes capture some callback exceptions that Home and installed Bun deliver. The exact Node source and all traces are retained; no exception swallowing was added to make those diagnostics agree. Full #66 acceptance remains open.

Sign in to comment on this issue.