linera_witty/runtime/wasmer/
function.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Implementations of [`InstanceWithFunction`] for Wasmer instances.
5
6use frunk::{hlist_pat, HList};
7use wasmer::{AsStoreRef, Extern, FromToNativeWasmType, NativeWasmTypeInto, TypedFunction};
8
9use super::{
10    parameters::WasmerParameters, results::WasmerResults, EntrypointInstance, ReentrantInstance,
11};
12use crate::{
13    memory_layout::FlatLayout, primitive_types::FlatType, InstanceWithFunction, Runtime,
14    RuntimeError,
15};
16
17/// Implements [`InstanceWithFunction`] for functions with the provided amount of parameters for
18/// the [`EntrypointInstance`] and [`ReentrantInstance`] types.
19macro_rules! impl_instance_with_function {
20    ($( $names:ident : $types:ident ),*) => {
21        impl_instance_with_function_for!(EntrypointInstance<UserData>, $( $names: $types ),*);
22        impl_instance_with_function_for!(ReentrantInstance<'_, UserData>, $( $names: $types ),*);
23    };
24}
25
26/// Implements [`InstanceWithFunction`] for functions with the provided amount of parameters for
27/// the provided `instance` type.
28macro_rules! impl_instance_with_function_for {
29    ($instance:ty, $( $names:ident : $types:ident ),*) => {
30        impl<$( $types, )* Results, UserData> InstanceWithFunction<HList![$( $types ),*], Results>
31            for $instance
32        where
33            $( $types: FlatType + FromToNativeWasmType + NativeWasmTypeInto, )*
34            Results: FlatLayout + WasmerResults,
35            UserData: 'static,
36        {
37            type Function = TypedFunction<
38                <HList![$( $types ),*] as WasmerParameters>::ImportParameters,
39                <Results as WasmerResults>::Results,
40            >;
41
42            fn function_from_export(
43                &mut self,
44                export: <Self::Runtime as Runtime>::Export,
45            ) -> Result<Option<Self::Function>, RuntimeError> {
46                Ok(match export {
47                    Extern::Function(function) => Some(function.typed(&self.as_store_ref())?),
48                    _ => None,
49                })
50            }
51
52            fn call(
53                &mut self,
54                function: &Self::Function,
55                hlist_pat![$( $names ),*]: HList![$( $types ),*],
56            ) -> Result<Results, RuntimeError> {
57                let results = function.call(&mut *self, $( $names ),*)?;
58
59                Ok(Results::from_wasmer(results))
60            }
61        }
62    };
63}
64
65repeat_macro!(impl_instance_with_function =>
66    a: A,
67    b: B,
68    c: C,
69    d: D,
70    e: E,
71    f: F,
72    g: G,
73    h: H,
74    i: I,
75    j: J,
76    k: K,
77    l: L,
78    m: M,
79    n: N,
80    o: O,
81    p: P,
82    q: Q
83);