peterhuene opened PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
alexcrichton submitted PR Review.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Since
Store
is generally behindRc
and such I think we'll want to change this andremove_context
to&self
instead of&mut self
.
alexcrichton created PR Review Comment:
I think we may not end up needing
IntoEngineFunc
as a separate trait here? It's mentioned below that this trait will also be implemented forFn(Caller, &[Val], &mut [Val]) -> Result<Trap> +
staticbut I don't think we can do that because we can't infer the type signature from the closure. If that's the only reason, though, then this could have two methods, one taking
IntoFuncand the other being the mirror of
Func::new` which takes a signature and a function?
alexcrichton created PR Review Comment:
FWIW this doesn't look like it necessarily needs to be a function on
Wasi
, it could presumably just bestore.set_context(WasiCtx::default())
?
alexcrichton edited PR Review Comment.
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
In use cases for API virtualization, the store doesn't seem like the right entity to attach contextual information to. Using the store here effectively makes all instances of an API share data.
The Wasmtime ABI passes the callee vmcontext to regular wasm functions; would it make sense to use a similar mechanism for engine functions, and store the state in something like the
host_state
field inInstance
, instead of in the store?
sunfishcode submitted PR Review.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
I'm not sure that instances are the best places to store data because they're generally designed at the wasm-spec-level to get decomposed into a bag of functions/globals/etc and those get passed around individually. The "calling instance" seems like it's sometimes a little ambiguous or just generally not available.
For virtualization, though, can you detail how something like this wouldn't work well? Wasm-based virtualization wouldn't be affected at all since it's not storing data directly in the
Store
, and host-based virtualization presumably wouldn't be using the exact same type of context to virtualize? (and if it is it could always use a newttype)
fitzgen submitted PR Review.
fitzgen created PR Review Comment:
:+1: it would be really nice to avoid another
IntoFunc
style trait.
- They aren't great from a user point of view since they are basically "special" sealed traits and you have to figure out what shape of things are expected.
- This seems, as Alex mentions, basically identical to the existing trait. Would be great to share a single trait if possible.
fitzgen submitted PR Review.
fitzgen submitted PR Review.
fitzgen created PR Review Comment:
/// This will replace any existing `WasiCtx` associated with the `Store`. /// /// The old `WasiCtx`, if any, is returned. pub fn set_context(store: &Store, context: WasiCtx) -> Option<WasiCtx>;
Although, will this overwrite any context that already exists on the store? Not just a
WasiCtx
?This is why it would be nice if we used ephemerons for associating context instead. (Something we can always add later, if it makes sense; nothing to block this stuff on I don't think.)
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
The existing
IntoFunc
method is inherently tied toStore
, which is why it isn't being used in this context.I'm not a fan of more boilerplate code, but I'm open to somehow extending
IntoFunc
for this use case.Regarding
Fn(Caller, &[Val], &mut [Val])
, you're absolutely right that we can't infer the Wasm type of the function with that so another method will be necessary.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Agreed. I'll remove the
&mut
.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
The thinking behind this is that
Wasi
will likely want to wrap theWasiCtx
in aRefCell
and it is the only one that knows exactly what it expects the context type to be in the host functions.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
It would just replace the
WasiCtx
as a map of typeid -> context value will be used ala Lucet'sset_embed_ctx
.
peterhuene edited PR Review Comment.
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
peterhuene edited PR Review Comment.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Ah right that's a good point, but I think we can add new functions as necessary to that trait since it's not intended to be implemented externally. We might have roughtly the same amount of boilerplate internally but I think we should be able to get away witth one trait.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Ah ok that's a good point yeah, seems reasonable!
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
For more context, I originally proposed (in a privately reviewed draft) that the context be set on the instance, so I'm not opposed to that.
I think I was unclear in the intention of
set_context
allowing multiple values of different types, which is what Lucet does today withinsert_embed_ctx
. As such, "insert" would probably be a better name as "set" has a singular connotation; I'll make that change.If we do store it on the instance, we'll obviously need to modify the
wasmtime_runtime::Instance
to store the values and thenCaller
needs to be modified to perhaps return awasmtime::Instance
to get the values from?That said, if we keep it on the
Store
, it's true that all instances using theWasi
host functions added at the engine-level will share the sameWasiCxt
context. But that still does not preclude users from being able to callWasi::add_to_linker
to link in WASI with a different context for a specific instantiation.
peterhuene edited PR Review Comment.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Agreed. I'll update the draft with extensions for
IntoFunc
.
peterhuene edited PR Review Comment.
peterhuene edited PR Review Comment.
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Oh I also think that this is going to need
Send
andSync
bounds to keepEngine
bothSend
andSync
(and that'd also highlight that as an engine-global thing the function may get invoked concurrently)
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Similar to above this'll probably need
+ Send + Sync
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
Most definitely will. shakes fist at Markdown not compiling his code
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
To be sure, I mean the callee vmctx arg, and not the caller one. The caller is indeed ambiguous and will ideally go away once interface types obviates exporting "memory". The callee, however, is pretty fundamental. Wasm functions need their instances.
The use case I'm thinking of is: an API which has some state associated with it. If two parts of an application each want to use that API, independently of the other, they should be able to have independent copies of the state. Ideally, we want host APIs to act as much like wasm APIs as possible, so that we can easily switch between host and polyfill implementations.
That said, if we keep it on the Store, it's true that all instances using the Wasi host functions added at the engine-level will share the same WasiCxt context. But that still does not preclude users from being able to call Wasi::add_to_linker to link in WASI with a different context for a specific instantiation using the same store.
It's good that you can do multiple contexts; what I'm asking is, should this be the default way of doing things, and perhaps even the only way? Right now, there's not a lot attached to the store, and the state that is there is well understood, which is a useful property when we think about suspending/resuming/checkpoint-restart/migration/etc. if instances.
Here's a potentially crazy idea: each imported function has a
VMCallerCheckedAnyfunc
, which includes a*mut VMContext
. But after instantiation and linking are done, one instantace doesn't ever look at the*mut VMContext
for another instance. It just just blindly passes the context argument when calling an import. So, what if we generalized this pointer, and said it's no longer just a*mut VMContext
, but an arbitrary "context" state pointer? For wasm modules, it'd still be the sameVMContext
pointer, but for host modules, it could be a pointer into whatever type the host wanted? Then we wouldn't even have to figure out how to fit this intoInstance
.
alexcrichton submitted PR Review.
alexcrichton created PR Review Comment:
Oh sorry I misunderstood about callee/caller. I'm curious though how you're thinking that the callee's state is initialized? For per-function state you can always simply capture state via the Rust closure, but the main problem with that is then the state is per-engine rather than per-instance/store. Where would per instance/store state get attached in what you're thinking @sunfishcode? (currently it's
set_context
for what this currently proposes I believe)
sunfishcode submitted PR Review.
sunfishcode created PR Review Comment:
Ok yeah, that is tricky. I'll have to think about this some more.
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
peterhuene has marked PR #9 as ready for review.
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
peterhuene submitted PR Review.
peterhuene created PR Review Comment:
@sunfishcode Do you have any suggestions as to an alternative approach? I'd like to resolve this prior to motion to finalize.
peterhuene updated PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions at theEngine
-level.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions at the
Engine
-level, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
peterhuene edited PR #9 from engine-host-functions
to main
:
This RFC proposes to extend the Wasmtime API to allow users to define host
functions in aConfig
that can be shared between multiple engines and
therefore stores.Today,
Func
is used to define host functions, but it is tied to aStore
.
If users desire short-lived stores to ensure short-lived instances, host
functions need to be redefined upon every module instantiation.By defining host functions with a
Config
, instances can be created
without having to redefine the host functions; this will make for faster module
instantiations in scenarios where a module is repeatedly instantiated.
Last updated: Dec 23 2024 at 12:05 UTC