bkolobara opened Issue #2159:
Hi! I'm trying to use Wasmtime inside a generator. I would like to provide a host function to suspend the execution by yielding from the generator. This is my current attempt:
let _ = Generator::new(move |yielder| { let suspend = Func::wrap(&store, move |param: i32| { yielder.suspend(); }); let instance = Instance::new(&store, &module, &[suspend.into()]).unwrap(); }
I had now multiple attempts of passing
yielder
inside the closure, but nothing worked. I always get a lifetime related error:= note: expected `gen::Generator<'_, _>` found `gen::Generator<'_, _>` = note: but, the lifetime must be valid for the static lifetime...
It's not clear to me why the passed in closure needs to be static. Can this requirement be relaxed? Or is there maybe a better way of approaching this?
Could
yielder
be attached toCaller
and then later accessed?
bjorn3 commented on Issue #2159:
The
'static
bound comes from https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/func.rs#L1554 and https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/func.rs#L1586.
bjorn3 edited a comment on Issue #2159:
The
'static
bound comes from https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/func.rs#L1554 and https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/func.rs#L1586
bjorn3 commented on Issue #2159:
This bound is necessary because
Func
has a static lifetime itself, as it doesn't have any lifetime parameters: https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/func.rs#L144-L148
bjorn3 commented on Issue #2159:
Which in turn is necessary because
Instance
itself doesn't have a lifetime parameter: https://github.com/bytecodealliance/wasmtime/blob/c7cd70fcec3eee66c9d7b5aa6fb4580d5a802218/crates/wasmtime/src/instance.rs#L99-L103
alexcrichton commented on Issue #2159:
Due to the memory management of wasm objects right now (e.g. instances and stores) everything must live for the
'static
lifetime and you can't have stack-borrowed data. Fixing this would require some sort of lifetime on aStore
and everything connected to it which would be a very significant investment, and one that I'm not entirely sure is possible.It's worth noting though that a form of stack switching like you're trying to use is something we're interested in providing first-class support for. There's a few wasm proposals in flight but we'd like to have something at least for async in the meantime as well. Basically just to say that this is likely to be supported in some fashion in the future.
bkolobara commented on Issue #2159:
Thank you for the feedback! I will probably just cast it to a pointer and back to "cheat" the lifetime. The function will be only called while inside the closure, so it should be safe.
It's worth noting though that a form of stack switching like you're trying to use is something we're interested in providing first-class support for. There's a few wasm proposals in flight but we'd like to have something at least for async in the meantime as well. Basically just to say that this is likely to be supported in _some_ fashion in the future.
I'm really interested in this. Are there maybe some issues open where I could follow the development of this or some places where the discussion was started? I could not find any active proposals regarding it.
pchickey commented on Issue #2159:
Andreas Rossberg has presented at several CG meetings in the past year about approaches to stack switching based on delimited continuations. It does not appear that there is any formal proposal work in https://github.com/WebAssembly/proposals at this time, but the work is something the Bytecode Alliance is very interested in implementing.
pchickey edited a comment on Issue #2159:
Andreas Rossberg has presented at several CG meetings in the past year about approaches to stack switching based on delimited continuations. It does not appear that there is any formal proposal work in https://github.com/WebAssembly/proposals at this time, but the work is something the Bytecode Alliance is very interested in implementing.
Lucet already has some limited support for stack switching (it is not as general or powerful as Andreas's proposal) and this PR uses it to enable async computations which suspend the wasm stack. We will need to implement something similar in Wasmtime as part of our plans to merge the features of the two runtimes. https://github.com/bytecodealliance/lucet/pull/551
peterhuene commented on Issue #2159:
I've also toyed with using a generator (from the
generator
crate) to "async-ify" a host function. It also needed to cast away the lifetime of the closure's argument.I am looking forward to first-class support for this in Wamtime.
peterhuene edited a comment on Issue #2159:
I've also toyed with using a generator (from the
generator
crate) to "async-ify" a host function. It also needed to cast away the lifetime of the closure's argument.I am looking forward to first-class support for this in Wasmtime.
bkolobara commented on Issue #2159:
Thank you everyone for the discussion. The restrictions are much clearer to me now. I will close this issue as I don't think there is any straightforward way right now to reduce the lifetime from
'static
.
bkolobara closed Issue #2159:
Hi! I'm trying to use Wasmtime inside a generator. I would like to provide a host function to suspend the execution by yielding from the generator. This is my current attempt:
let _ = Generator::new(move |yielder| { let suspend = Func::wrap(&store, move |param: i32| { yielder.suspend(); }); let instance = Instance::new(&store, &module, &[suspend.into()]).unwrap(); }
I had now multiple attempts of passing
yielder
inside the closure, but nothing worked. I always get a lifetime related error:= note: expected `gen::Generator<'_, _>` found `gen::Generator<'_, _>` = note: but, the lifetime must be valid for the static lifetime...
It's not clear to me why the passed in closure needs to be static. Can this requirement be relaxed? Or is there maybe a better way of approaching this?
Could
yielder
be attached toCaller
and then later accessed?
Last updated: Dec 23 2024 at 12:05 UTC