fp_bindgen_support/wasmer2_host/async/
mod.rs

1use super::{
2    io::{from_fat_ptr, to_wasm_ptr},
3    runtime::RuntimeInstanceData,
4};
5use crate::common::{
6    mem::FatPtr,
7    r#async::{AsyncValue, FUTURE_STATUS_PENDING, FUTURE_STATUS_READY},
8};
9use std::{mem::size_of, task::Waker};
10
11pub mod future;
12
13/// Create an empty FutureValue in the linear memory and return a FatPtr to it.
14pub fn create_future_value(env: &RuntimeInstanceData) -> FatPtr {
15    let memory = unsafe { env.memory.get_unchecked() };
16
17    let size = size_of::<AsyncValue>(); //TODO: Is this *actually* safe? Might be a different size in wasm land...
18    let ptr = env.malloc(size as u32);
19
20    let (async_ptr, async_len) = to_wasm_ptr(ptr);
21    let values = async_ptr.deref(memory, 0, async_len).unwrap();
22
23    values[0].set(FUTURE_STATUS_PENDING);
24    values[1].set(0);
25    values[2].set(0);
26
27    ptr
28}
29
30/// Note: In this case we are only interested in the pointer itself, we do not
31/// want to deserialize it (which would actually free it as well).
32/// This function also doesn't call another function since everything is
33/// contained in the env object.
34pub fn resolve_async_value(env: &RuntimeInstanceData, async_value_ptr: FatPtr, result_ptr: FatPtr) {
35    // First assign the result ptr and mark the async value as ready:
36    let memory = unsafe { env.memory.get_unchecked() };
37    let (async_ptr, async_len) = to_wasm_ptr(async_value_ptr);
38    let (result_ptr, result_len) = from_fat_ptr(result_ptr);
39    let values = async_ptr.deref(memory, 0, async_len).unwrap();
40
41    values[0].set(FUTURE_STATUS_READY);
42    values[1].set(result_ptr);
43    values[2].set(result_len);
44
45    env.wakers
46        .lock()
47        .unwrap()
48        .remove(&async_value_ptr)
49        .as_ref()
50        .map(Waker::wake_by_ref);
51}