ReviewOS

home-lang/home

runtime: implement JSStreamSocket and stream_wrap binding parity

#446
Closed chris opened this 10 days ago ·
10 days ago

Tracked by #66. This issue covers the three byte-current Bun fixtures currently marked FAIL at packages/runtime/test/bun-corpus/expectations.txt:28-30:

  • test/js/node/test/parallel/test-stream-wrap.js
  • test/js/node/test/parallel/test-stream-wrap-drain.js
  • test/js/node/test/parallel/test-stream-wrap-encoding.js

Current generic gaps:

  • internalBinding("stream_wrap") is unavailable; only the public deprecated _stream_wrap placeholder exists.
  • internal/js_stream_socket is not registered.
  • Generic Duplex/net state lacks the write backpressure, drain, shutdown serialization, encoding, object-mode, and terminal behavior these Node fixtures exercise.

Implementation scope:

  • Add ShutdownWrap and WriteWrap request objects to a real stream_wrap internal binding.
  • Add Node-compatible internal/js_stream_socket, exporting JSStreamSocket and static .StreamWrap with a retained _handle.
  • Serialize shutdown behind pending writes, complete each request exactly once, and report negative cancellation after destroy.
  • Implement generic Duplex high-water-mark accounting, write callbacks, one-shot drain, pause/resume, setEncoding, and readableObjectMode checks.
  • Reject StringDecoder/object-mode input exactly once with ERR_STREAM_WRAP and the Node message.

Exact removal gate:

  • Run all three copied fixtures without their expectation lines and require zero failures/timeouts with every mustCall/expectsError obligation satisfied.
  • test-stream-wrap.js: shutdown callback exactly once with a negative status after destroy.
  • test-stream-wrap-drain.js: write callback, underlying drain, and ShutdownWrap completion exactly once, with shutdown ordered after the pending write.
  • test-stream-wrap-encoding.js: exactly two ERR_STREAM_WRAP errors for decoder and object-mode cases.
  • Run the combined three-file selector plus adjacent Home generic stream/net logical contracts.

Remove all three markers only after that exact gate is green. No fixture-name branches or synthetic pass paths.

10 days ago

Implemented and published in e6aacc5adfadc9465d5f4fc062edebe3d08f11cf on codex/runtime-port, authored and committed solely by Chris Breuer without coauthor trailers.

What landed:

  • Home now parses --expose-internals and gates direct Node-internal specifiers behind it. Without the flag, all five exposed specifiers fail resolution.
  • internal/test/binding exposes Node v26.3.0-compatible ShutdownWrap, WriteWrap, the four stream-base indices, and streamBaseState.
  • internal/js_stream_socket exports the callable JSStreamSocket class and static .StreamWrap, retains _handle._parentWrap, serializes shutdown after pending writes, reports cancellation after destroy, and delivers each shutdown completion once.
  • The same adapter source feeds both the generated internal-for-testing module and the runtime CommonJS loader, preventing generator/runtime drift.
  • A corrected full-stream audit exposed three additional direct aliases that the old unsupported-flag behavior had hidden. internal/streams/add-abort-signal, internal/async_context_frame, and internal/async_hooks now reuse their ABI-matched internal-module-registry implementations.

Exact verification:

  • All three unchanged target fixtures pass with their real --expose-internals flag and all mustCall / expectsError obligations active:
    • test-stream-wrap.js SHA-256 ddb14300d07f0442418577816e9a2b99502f857ec64827ff6d093ecd4959276d
    • test-stream-wrap-drain.js SHA-256 4a8c48bc117831dfb5e85ebf683200cb29455be5f320502575d564422db8b480
    • test-stream-wrap-encoding.js SHA-256 d25a88944970b83846ea6173af589245476a0c9f274e47af67af11b9abff4d6f
  • Strict seven-file lifecycle set: 7/7 with BUN_JSC_validateExceptionChecks=1 and BUN_DESTRUCT_VM_ON_EXIT=1.
  • Corrected complete stream matrix: 252/252 pass, all 252 source-identical to pin 4982b91e3702094330f3be3883354c52b8c01323; 48 flag-bearing files actually executed; 0 failures, 0 timeouts, 0 help-text substitutions, 0 skip markers.
  • Native regression passes normally, with exception checks, and with forced VM destruction.
  • Generator tests: 3/3, 117 assertions. Hardcoded-module units: 5/5.
  • Scoped home_rt: 1,829 passed / 19 skipped / 0 failed, 20/20 build steps. Skips are not counted as parity.
  • Native debug build and cached rebuild: 18/18.
  • Focused Pickier, Zig formatting, and whitespace checks pass.

Correction to earlier stream-wide reporting: before this work Home did not recognize --expose-internals; those invocations printed CLI help and exited 0, so the three stream-wrap files and four adjacent internal-module files were false positives in the earlier 252-file scan. The result above explicitly rejects help output and is the valid replacement.

The pinned Bun release binary itself lacks these two stream-wrap internal entry points, so this compatibility surface follows Node v26.3.0 semantics beyond the pin rather than claiming a passing Bun-binary differential control. The current expectations file has no remaining markers for the three target fixtures. Closing as completed.

Sign in to comment on this issue.