alexcrichton opened PR #11238 from alexcrichton:accessor-apis to bytecodealliance:main:
After discussion with Joel we've concluded that while
&mut Accessor<T, D>was originally added to model host functions it is also appropriate to use it to model embedder-rooted invocations of items such as wasm as well. Effectively the conclusion we reached was that*::call_concurrentshould be taking&Accessor, notStoreContextMut. This has a number of benefits to it over the previous iteration:
This makes exports behave more like imports where
Accessormeans "you're in the concurrent world".This makes exports have an
async fnsignature which is easier to read and understand.This automatically enforces the guarantee that the returned future is only polled within the main event loop because the future is always considered to close over the
&Accessorprovided meaning it statically cannot live outside of the event loop.This paves the way forward to future refactorings to avoid storing so much state within a
Store<T>and instead try to store state directly in futures themselves. This should make cancellation more natural and eventually also remove'staticbounds on params/results. Furthermore this should make it easier to avoid spawning tasks internally by storing state in futures instead of spawned tasks.In doing this one of the main questions we were faced with was what to do about
&mut Accessor<T, D>, namely themutpart. With a mutable accessor it would be only possible to call one function concurrently. One option considered was to add combinators likeAccessor::joinandAccessor::racebut in the end we decided to avoid going that direction and instead switch to&Accessor<T, D>everywhere, freely enabling aliasing of the accessor. This has the downside thatAccessor::withis now a relatively dangerous function in that it can panic, but idiomatic usage of it is not expected to panic as the distinction between theasyncand sync boundary ofAccessorvsStoreContextMutis expected to naturally make the recursive panic condition ofwithrare to come up in practice.Concrete changes in this commit are:
Accessor::withnow requires&self.Accessor::spawnnow requires&self.- Host functions are now given
&Accessor, not&mut Accessor.{Typed,}Func::call_concurrentis now anasync fnwhich takes an&Accessorinstead ofStoreContextMut.- Guest bindings generation for concurrent invocations now looks exactly like async bindings generation except for replacing
StoreContextMutwithAccessor.Note that this commit does not yet update the internal implementations of these functions to benefit from the new abilities that taking
&Accessorimplies. Instead that's deferred to a future update as necessary. Instead this is only updating the public API of thewasmtimecrate to enable these refactorings in the future.Also note that this does not yet update all functions to take
&Accessor. Notably futures and streams still need to be updated.cc #11224
<!--
Please make sure you include the following information:
If this work has been discussed elsewhere, please include a link to that
conversation. If it was discussed in an issue, just mention "issue #...".Explain why this change is needed. If the details are in an issue already,
this can be brief.Our development process is documented in the Wasmtime book:
https://docs.wasmtime.dev/contributing-development-process.htmlPlease ensure all communication follows the code of conduct:
https://github.com/bytecodealliance/wasmtime/blob/main/CODE_OF_CONDUCT.md
-->
alexcrichton requested dicej for a review on PR #11238.
alexcrichton requested wasmtime-core-reviewers for a review on PR #11238.
alexcrichton commented on PR #11238:
One other update:
Instance::run_withis updated to now takeAyncFnOnceinstead ofFnOnce() -> Box<...>
dicej created PR review comment:
Could collapse the
ifexpression here into("async", "_async", ".await", self.generator.opts.concurrent_exports)
dicej submitted PR review.
alexcrichton updated PR #11238.
alexcrichton has enabled auto merge for PR #11238.
alexcrichton merged PR #11238.
Last updated: Dec 06 2025 at 06:05 UTC