Wasmtime: Relaxing static lifetime of Func::wrap arguments

Created on 24 Aug 2020  路  8Comments  路  Source: bytecodealliance/wasmtime

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 to Caller and then later accessed?

Most helpful comment

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 a Store 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.

All 8 comments

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

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

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 a Store 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.

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.

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

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.

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

daubaris picture daubaris  路  3Comments

ckaran picture ckaran  路  5Comments

moderation picture moderation  路  4Comments

julian-seward1 picture julian-seward1  路  6Comments

vedantroy picture vedantroy  路  6Comments