Skip to main content

wasmtime_c_api/component/
func.rs

1use super::wasmtime_component_val_t;
2use crate::{WasmtimeStoreContextMut, wasmtime_component_func_type_t, wasmtime_error_t};
3use wasmtime::component::{Func, Val};
4
5#[unsafe(no_mangle)]
6pub unsafe extern "C" fn wasmtime_component_func_call(
7    func: &Func,
8    mut context: WasmtimeStoreContextMut<'_>,
9    args: *const wasmtime_component_val_t,
10    args_len: usize,
11    results: *mut wasmtime_component_val_t,
12    results_len: usize,
13) -> Option<Box<wasmtime_error_t>> {
14    let c_args = unsafe { crate::slice_from_raw_parts(args, args_len) };
15    let c_results = unsafe { crate::slice_from_raw_parts_mut(results, results_len) };
16
17    let mut results = vec![Val::Bool(false); results_len];
18    let result = c_args
19        .iter()
20        .map(Val::try_from)
21        .collect::<wasmtime::Result<Vec<_>>>()
22        .and_then(|args| func.call(&mut context, &args, &mut results));
23
24    crate::handle_result(result, |_| {
25        for (c_val, rust_val) in std::iter::zip(c_results, results) {
26            *c_val = wasmtime_component_val_t::from(&rust_val);
27        }
28    })
29}
30
31#[unsafe(no_mangle)]
32#[cfg(feature = "component-model-async")]
33pub unsafe extern "C" fn wasmtime_component_func_call_async<'a>(
34    func: &'a Func,
35    mut context: WasmtimeStoreContextMut<'a>,
36    args: *const wasmtime_component_val_t,
37    args_len: usize,
38    results: *mut wasmtime_component_val_t,
39    results_len: usize,
40    err_ret: &'a mut *mut wasmtime_error_t,
41) -> Box<crate::wasmtime_call_future_t<'a>> {
42    let c_args = unsafe { crate::slice_from_raw_parts(args, args_len) };
43    let c_results = unsafe { crate::slice_from_raw_parts_mut(results, results_len) };
44    let fut = Box::pin(async move {
45        let args = match c_args
46            .iter()
47            .map(Val::try_from)
48            .collect::<wasmtime::Result<Vec<_>>>()
49        {
50            Ok(args) => args,
51            Err(err) => {
52                *err_ret = Box::into_raw(Box::new(wasmtime_error_t::from(err)));
53                return;
54            }
55        };
56        let mut results = vec![Val::Bool(false); c_results.len()];
57
58        match func.call_async(&mut context, &args, &mut results).await {
59            Ok(()) => {
60                for (c_val, rust_val) in std::iter::zip(c_results.iter_mut(), results) {
61                    *c_val = wasmtime_component_val_t::from(&rust_val);
62                }
63            }
64            Err(err) => {
65                *err_ret = Box::into_raw(Box::new(wasmtime_error_t::from(err)));
66            }
67        }
68    });
69    Box::new(crate::wasmtime_call_future_t::new(fut))
70}
71
72#[deprecated(note = "no longer has any effect")]
73#[unsafe(no_mangle)]
74pub unsafe extern "C" fn wasmtime_component_func_post_return(
75    _func: &Func,
76    _context: WasmtimeStoreContextMut<'_>,
77) -> Option<Box<wasmtime_error_t>> {
78    None
79}
80
81#[unsafe(no_mangle)]
82pub extern "C" fn wasmtime_component_func_type(
83    func: &Func,
84    context: WasmtimeStoreContextMut<'_>,
85) -> Box<wasmtime_component_func_type_t> {
86    Box::new(func.ty(context).into())
87}