wasmer_wasix/syscalls/wasix/
closure_allocate.rs

1use crate::syscalls::*;
2
3/// Allocate a new slot in the __indirect_function_table for a closure
4///
5/// Until the slot is prepared with [`closure_prepare`], it is undefined behavior to call the function at the given index.
6///
7/// The slot should be freed with [`closure_free`] when it is no longer needed.
8#[instrument(level = "trace", skip_all, ret)]
9pub fn closure_allocate<M: MemorySize>(
10    mut ctx: FunctionEnvMut<'_, WasiEnv>,
11    closure: WasmPtr<u32, M>,
12) -> Result<Errno, WasiError> {
13    WasiEnv::do_pending_operations(&mut ctx)?;
14
15    let (env, mut store) = ctx.data_and_store_mut();
16    let Some(linker) = env.inner().linker().cloned() else {
17        error!("Closures only work for dynamic modules.");
18        return Ok(Errno::Notsup);
19    };
20
21    let function_id = match linker.allocate_closure_index(&mut ctx) {
22        Ok(f) => f,
23        Err(e) => {
24            // Should never happen
25            error!("Failed to allocate closure index: {e}");
26            return Ok(Errno::Fault);
27        }
28    };
29
30    let (env, mut store) = ctx.data_and_store_mut();
31    let memory = unsafe { env.memory_view(&store) };
32    closure.write(&memory, function_id);
33    return Ok(Errno::Success);
34}