linera_witty/runtime/wasmtime/
function.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Implementations of [`InstanceWithFunction`] for Wasmtime instances.
5
6use wasmtime::{AsContext, AsContextMut, Extern, TypedFunc};
7
8use super::{
9    parameters::WasmtimeParameters, results::WasmtimeResults, EntrypointInstance, ReentrantInstance,
10};
11use crate::{memory_layout::FlatLayout, InstanceWithFunction, Runtime, RuntimeError};
12
13/// Implements [`InstanceWithFunction`] for the Wasmtime [`Instance`] implementations.
14macro_rules! impl_instance_with_function {
15    ($instance:ty) => {
16        impl<Parameters, Results, UserData> InstanceWithFunction<Parameters, Results> for $instance
17        where
18            Parameters: FlatLayout + WasmtimeParameters,
19            Results: FlatLayout + WasmtimeResults,
20        {
21            type Function = TypedFunc<
22                <Parameters as WasmtimeParameters>::Parameters,
23                <Results as WasmtimeResults>::Results,
24            >;
25
26            fn function_from_export(
27                &mut self,
28                export: <Self::Runtime as Runtime>::Export,
29            ) -> Result<Option<Self::Function>, RuntimeError> {
30                Ok(match export {
31                    Extern::Func(function) => Some(
32                        function
33                            .typed(self.as_context())
34                            .map_err(RuntimeError::Wasmtime)?,
35                    ),
36                    _ => None,
37                })
38            }
39
40            fn call(
41                &mut self,
42                function: &Self::Function,
43                parameters: Parameters,
44            ) -> Result<Results, RuntimeError> {
45                let results = function
46                    .call(self.as_context_mut(), parameters.into_wasmtime())
47                    .map_err(RuntimeError::Wasmtime)?;
48
49                Ok(Results::from_wasmtime(results))
50            }
51        }
52    };
53}
54
55impl_instance_with_function!(EntrypointInstance<UserData>);
56impl_instance_with_function!(ReentrantInstance<'_, UserData>);