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