jrandolf opened PR #14875 from jrandolf:wasi-named-imports-coverage to bytecodealliance:main:
This fills the gaps in WASI named-import (
implements) support from #14858, one commit per step:
trappable_error_typeconversions get the id. Withnamed_imports,bindgen!passed the host-chosen id to every generated method except theconvert_*conversions. Convertingwasi:io/streams'stream-errorhas to push anerrorresource into the table for that id, so the conversions now take it too. The existing named conversions in wasmtime-wasi and wasmtime-wasi-http are updated to match.- Labelled
wasi:io.wasi:io/{error,poll,streams}imported under a label now link. There are newInterface::{IoError, IoPoll, IoStreams}variants. The test is WAT, because a labelledwasi:cli/stdoutthat uses types from labelledwasi:ioimports can't be written in WIT. It checks that output goes to the labelled context's stdout.- Sync API.
wasmtime_wasi::p2::add_named_to_linker_sync(plus_with_options) andwasmtime_wasi_http::p2::add_named_to_linker_sync. I didn't find a technical reason these were left out. The sync named-import tests that were placeholders now run.- wasi-keyvalue, wasi-config, wasi-tls (p2 and p3) and wasi-nn get named-import support following the same pattern as #14275: a
*NamedViewtrait, anInterfaceenum andadd_named_to_linker. Each has a test showing two labels get separate contexts; the tls and nn tests use mocks, so they need no network or ML backend.A few notes:
- keyvalue, config and nn now depend on
wasmtime-wasias a regular dependency (it was a dev-dependency) so they can share itsNamedId.Cargo.lockdoesn't change, but I'd appreciate a second opinion on whether that's the right way to share it.wasi:clocks/timezoneisn't covered: wasmtime-wasi doesn't implement it at all, labelled or not.- #14873 changes the signature of the
add_named_to_linkerlookup. Whichever of these lands second will need to port the new functions here, which is mechanical.Closes #14858
jrandolf updated PR #14875.
jrandolf updated PR #14875.
jrandolf edited PR #14875:
This fills the gaps in WASI named-import (
implements) support from #14858, one commit per step:
trappable_error_typeconversions get the id. Withnamed_imports,bindgen!passed the host-chosen id to every generated method except theconvert_*conversions. Convertingwasi:io/streams'stream-errorhas to push anerrorresource into the table for that id, so the conversions now take it too. The existing named conversions in wasmtime-wasi and wasmtime-wasi-http are updated to match.- Labelled
wasi:io.wasi:io/{error,poll,streams}imported under a label now link. There are newInterface::{IoError, IoPoll, IoStreams}variants. The test is WAT, because a labelledwasi:cli/stdoutthat uses types from labelledwasi:ioimports can't be written in WIT. It checks that output goes to the labelled context's stdout.- Sync API.
wasmtime_wasi::p2::add_named_to_linker_sync(plus_with_options) andwasmtime_wasi_http::p2::add_named_to_linker_sync. I didn't find a technical reason these were left out. Thewasi:iotest above also runs with the sync bindings.- wasi-keyvalue, wasi-config, wasi-tls (p2 and p3) and wasi-nn get named-import support following the same pattern as #14275: a
*NamedViewtrait, anInterfaceenum andadd_named_to_linker. Each has one test showing that two labels get separate contexts (p2 and p3 for tls); the tls and nn tests use mocks, so they need no network or ML backend. The tls tests run once instead of once per TLS provider, since they don't use one.A few notes:
- keyvalue, config and nn now depend on
wasmtime-wasias a regular dependency (it was a dev-dependency) so they can share itsNamedId.Cargo.lockdoesn't change, but I'd appreciate a second opinion on whether that's the right way to share it.wasi:clocks/timezoneisn't covered: wasmtime-wasi doesn't implement it at all, labelled or not.- #14873 changes the signature of the
add_named_to_linkerlookup. Whichever of these lands second will need to port the new functions here, which is mechanical.Closes #14858
jrandolf updated PR #14875.
jrandolf edited PR #14875:
This fills the gaps in WASI named-import (
implements) support from #14858, one commit per step:
bindgen!passes the named-import id totrappable_error_typeconversions too, since convertingwasi:io/streams'stream-errorneeds it.- Labelled
wasi:io/{error,poll,streams}imports now link.- WASIp2 gets
add_named_to_linker_syncin wasmtime-wasi and wasmtime-wasi-http.- wasi-keyvalue, wasi-config, wasi-tls (p2 and p3) and wasi-nn get named-import support.
keyvalue, config and nn now depend on
wasmtime-wasito share itsNamedId, which roughly doubles their dependency trees. I'd appreciate a second opinion on whether that's the right way to share it.wasi:clocks/timezoneisn't covered, since wasmtime-wasi doesn't implement it at all.Closes #14858
<details>
<summary>LLM summary of the changes</summary>1.
trappable_error_typeconversions get the id (wit-bindgen)With
named_imports,bindgen!passed the host-chosen id to every generated method except theconvert_*methods fortrappable_error_type. Convertingwasi:io/streams'stream-errorpushes anerrorresource into the table, which with named imports is found through the id. The generated code now clones the id for the call when the function has a trappable error and passes it to the conversion, in the sync, store and async cases, and the generatedconvert_*trait methods take it as their first argument.This changes the signature of
convert_*for embedders implementing named-import traits withtrappable_error_type. The existing named conversions in wasmtime-wasi and wasmtime-wasi-http are updated; they don't need the id and ignore it.2. Labelled
wasi:io(wasi/src/p2)
wasi:io/{error,poll,streams}are added to thenamed_importsof the async bindings, with the sameasync/trappable/tracingrules aswasmtime-wasi-iouses. The resource types are the same as for unlabelled imports.InterfacegetsIoError,IoPollandIoStreams, andadd_named_to_linker_asyncadds them.wasi:iohas no state besides the resource table, so each method looks up the table of the context for the id and calls thewasmtime-wasi-ioimplementation. As documented for named WASI contexts, a stream created through one label and used through another only works if their contexts share aResourceTable.3. Synchronous named imports (
wasi/src/p2,wasi-http/src/p2)
- The sync bindings alias most interfaces to the async ones, which only have synchronous functions. The remaining ones get
named_imports:wasi:io/{poll,streams},wasi:filesystem/types, andwasi:sockets/{tcp,udp,udp-create-socket,ip-name-lookup}.add_named_nonblocking_to_linkeradds the interfaces shared by both variants.add_named_to_linker_with_options_{async,sync}add the rest from the async or sync bindings, which is the same split as the unlabelledadd_to_linker_*functions.- The sync implementations look up the context for the id and call the existing sync implementations.
- wasmtime-wasi-http gets
add_named_to_linker_syncandadd_named_to_linker_with_options_sync.4. keyvalue, config, tls and nn
Each crate follows the pattern of wasmtime-wasi's named imports (#14275):
- a
*NamedViewtrait (WasiKeyValueNamedView,WasiConfigNamedView,WasiTlsNamedView,WasiNnNamedView) mapping aNamedIdto that crate's context;- an
Interfaceenum;add_named_to_linker, inp2andp3for wasi-tls.The implementations look up the context for the id and call the existing implementations. In wasi-tls p3,
send,receiveandconnectuseAccess/Accessor, whose getters are plain function pointers that can't close over aNamedId. Their bodies move into free functions that are generic over the getter, unchanged except thatstore.get()becomesgetter(store.data_mut()), andResultProducerstores a generic getter.Dependencies
keyvalue, config and nn now have
wasmtime-wasias a regular dependency instead of a dev-dependency, forNamedId(ausizenewtype) andWasiCtxNamedView(a one-field wrapper). It's used without default features, but its non-optional dependencies such as tokio still come along. Their normal dependency trees grow from 77 to 151 crates (config), 81 to 151 (keyvalue) and 102 to 166 (nn).Cargo.lockdoesn't change.Interaction with #14873
#14873 changes the signature of the
add_named_to_linkerlookup. Whichever of the two lands second needs to port the new functions here, which is mechanical.Tests
wasi/tests/all/p2: a labelledwasi:cli/stdoutthat uses types from labelledwasi:ioimports, checking that output goes to the labelled context's stdout. It's written in WAT because WIT can't express it, and it runs with both the async and sync bindings.- keyvalue, config, tls (p2 and p3) and nn: one test each, showing that two labels get separate contexts. The tls and nn tests use mocks, so they need no network or ML backend. The tls tests run once instead of once per TLS provider, since they don't use one.
component-macro/tests/codegen.rs: the existing named-imports conversion is updated to take the id.</details>
Last updated: Oct 31 2026 at 23:03 UTC