linera_witty/runtime/wasmer/
parameters.rs

1// Copyright (c) Zefchain Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Representation of Wasmer function parameter types.
5
6use frunk::{hlist, hlist_pat, HList};
7use wasmer::FromToNativeWasmType;
8
9use crate::{memory_layout::FlatLayout, primitive_types::FlatType};
10
11/// Conversions between flat layouts and Wasmer parameter types.
12pub trait WasmerParameters: FlatLayout {
13    /// The type Wasmer uses to represent the parameters in a function imported from a guest.
14    type ImportParameters;
15
16    /// The type Wasmer uses to represent the parameters in a function exported from a host.
17    type ExportParameters;
18
19    /// Converts from this flat layout into Wasmer's representation for functions imported from a
20    /// guest.
21    fn into_wasmer(self) -> Self::ImportParameters;
22
23    /// Converts from Wasmer's representation for functions exported from the host into this flat
24    /// layout.
25    fn from_wasmer(parameters: Self::ExportParameters) -> Self;
26}
27
28impl WasmerParameters for HList![] {
29    type ImportParameters = ();
30    type ExportParameters = ();
31
32    fn into_wasmer(self) -> Self::ImportParameters {}
33
34    fn from_wasmer((): Self::ExportParameters) -> Self {
35        hlist![]
36    }
37}
38
39impl<Parameter> WasmerParameters for HList![Parameter]
40where
41    Parameter: FlatType + FromToNativeWasmType,
42{
43    type ImportParameters = Parameter;
44    type ExportParameters = (Parameter,);
45
46    fn into_wasmer(self) -> Self::ImportParameters {
47        let hlist_pat![parameter] = self;
48
49        parameter
50    }
51
52    fn from_wasmer((parameter,): Self::ExportParameters) -> Self {
53        hlist![parameter]
54    }
55}
56
57/// Helper macro to implement [`WasmerParameters`] for flat layouts up to the maximum limit.
58///
59/// The maximum number of parameters is defined by the [canonical
60/// ABI](https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md#flattening)
61/// as the `MAX_FLAT_PARAMS` constant. There is no equivalent constant defined in Witty. Instead,
62/// any attempt to use more than the limit should lead to a compiler error. Therefore, this macro
63/// only implements the trait up to the limit. The same is done in other parts of the code, like
64/// for example in
65/// [`FlatHostParameters`][`crate::imported_function_interface::FlatHostParameters`].
66macro_rules! parameters {
67    ($( $names:ident : $types:ident ),*) => {
68        impl<$( $types ),*> WasmerParameters for HList![$( $types ),*]
69        where
70            $( $types: FlatType + FromToNativeWasmType, )*
71        {
72            type ImportParameters = ($( $types, )*);
73            type ExportParameters = ($( $types, )*);
74
75            #[allow(clippy::unused_unit)]
76            fn into_wasmer(self) -> Self::ImportParameters {
77                let hlist_pat![$( $names ),*] = self;
78
79                ($( $names, )*)
80            }
81
82            fn from_wasmer(($( $names, )*): Self::ExportParameters) -> Self {
83                hlist![$( $names ),*]
84            }
85        }
86    };
87}
88
89repeat_macro!(parameters =>
90    a: A,
91    b: B |
92    c: C,
93    d: D,
94    e: E,
95    f: F,
96    g: G,
97    h: H,
98    i: I,
99    j: J,
100    k: K,
101    l: L,
102    m: M,
103    n: N,
104    o: O,
105    p: P,
106    q: Q
107);