fix(wasm): wasi:sockets TCP cannot bind — finish-connect and accept return too many values - #611
Closed
xepozz wants to merge 2 commits into
Closed
fix(wasm): wasi:sockets TCP cannot bind — finish-connect and accept return too many values#611xepozz wants to merge 2 commits into
xepozz wants to merge 2 commits into
Conversation
added 2 commits
August 30, 2026 20:12
The canonical ABI folds a host method into one result, and the binder accepts either an exact arity match or a (payload, error) pair. finish-connect returned three values and accept four, so neither could ever bind: a guest importing them failed with 'result count mismatch: expected 1, got 3'. Those two methods are the only source of the socket's input and output streams, so wasi:sockets TCP was unusable end to end for every guest. Both now return a record plus the error, the shape the address getters already use.
Loads a Go-authored WASI Preview 2 component that imports finish-connect and fails if any sockets method cannot bind. Before the record change this failed with 'result count mismatch: expected 1, got 3'.
Contributor
|
Superseded by #543. The canonical-ABI tuple fix and a committed stock Rust WASI sockets binding fixture are included there. |
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.
The
wasi:socketsTCP host cannot be bound by any guest. Two methods return their payload as several bare values, which the canonical-ABI lowering has no way to accept, so every component that imports them fails to load.The failure
A WASI Preview 2 component importing
wasi:sockets/tcpfails at host binding:acceptreportsexpected 1, got 4. Reproduced with a Rustwasm32-wasip2component and, independently, with a Go-authored one — the guest cannot influence this.Why it can never bind
CanonRegistry.processLowercaps the lowered results at one (lower.Results = []wit.Type{result}), which is what the canonical ABI requires: a result that does not fit one flat value comes back through a retptr.LowerWrapper.ValidateHandlerthen accepts exactly two arities — an exact match, or the(payload, error)pair it can fold throughfoldResultValue:The two methods match neither:
This is not a partial outage.
NewTCPInputStreamResourceis reached only from those two methods, so there is no other route to a socket's input and output streams: a guest can create a socket and start a connection, but can never read or write. UDP and DNS are unaffected.The change
Both methods now return a record plus the error — the shape the address getters in the same file already use (
MethodTCPSocketLocalAddressreturns(*IPSocketAddress, *NetworkError)), so the fold applies and the payload lifts as a record:Four call sites in
tcp_test.gofollow the new shape. No behaviour changes beyond the return shape, and no dependency is touched.Test
boot/components/runtime/wasm/sockets_bind_test.goloads a real component that importsfinish-connectand fails if any sockets method cannot bind. It is gated onWASM_SOCKETS_PROBEpointing at such a component, and skips otherwise, because the repository carries no component fixture — happy to add one if you would prefer the test to stand alone.Against the component I built it fails on
mainwithexpected 1, got 3and passes here.Note on the WIT shape
ip-socket-addressis implemented as a record (IPSocketAddress{Address string; Port uint16}) rather than thevariant { ipv4, ipv6 }the published WASI interface declares, so a guest has to declare it the same way to bind. That is out of scope here, but worth knowing if the intent is to accept stockwasi:socketsguests.