Skip to main content

wasmtime_test_util/
component.rs

1use arbitrary::Arbitrary;
2use std::mem::MaybeUninit;
3use wasmtime::component::__internal::{
4    CanonicalAbiInfo, InstanceType, InterfaceType, LiftContext, LowerContext,
5};
6use wasmtime::component::{ComponentType, Lift, Lower};
7use wasmtime::{Config, Engine};
8use wasmtime_environ::prelude::*;
9
10pub fn config() -> Config {
11    drop(env_logger::try_init());
12
13    let mut config = Config::new();
14    config.wasm_component_model(true);
15
16    // When `WASMTIME_TEST_NO_HOG_MEMORY` is set it means we're in qemu. The
17    // component model tests create a disproportionate number of instances so
18    // try to cut down on virtual memory usage by avoiding 4G reservations.
19    if std::env::var("WASMTIME_TEST_NO_HOG_MEMORY").is_ok() {
20        config.memory_reservation(0);
21        config.memory_guard_size(0);
22    }
23    config
24}
25
26pub fn engine() -> Engine {
27    Engine::new(&config()).unwrap()
28}
29
30pub fn map_config() -> Config {
31    let mut config = config();
32    config.wasm_component_model_map(true);
33    config
34}
35
36pub fn map_engine() -> Engine {
37    Engine::new(&map_config()).unwrap()
38}
39
40pub fn async_engine() -> Engine {
41    Engine::default()
42}
43
44/// Newtype wrapper for `f32` whose `PartialEq` impl considers NaNs equal to each other.
45#[derive(Copy, Clone, Debug, Arbitrary)]
46pub struct Float32(pub f32);
47
48/// Newtype wrapper for `f64` whose `PartialEq` impl considers NaNs equal to each other.
49#[derive(Copy, Clone, Debug, Arbitrary)]
50pub struct Float64(pub f64);
51
52macro_rules! forward_impls {
53    ($($a:ty => $b:ty,)*) => ($(
54        unsafe impl ComponentType for $a {
55            type Lower = <$b as ComponentType>::Lower;
56
57            const ABI: CanonicalAbiInfo = <$b as ComponentType>::ABI;
58
59            #[inline]
60            fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> {
61                <$b as ComponentType>::typecheck(ty, types)
62            }
63        }
64
65        unsafe impl Lower for $a {
66            fn linear_lower_to_flat<U>(
67                &self,
68                cx: &mut LowerContext<'_, U>,
69                ty: InterfaceType,
70                dst: &mut MaybeUninit<Self::Lower>,
71            ) -> Result<()> {
72                <$b as Lower>::linear_lower_to_flat(&self.0, cx, ty, dst)
73            }
74
75            fn linear_lower_to_memory<U>(&self, cx: &mut LowerContext<'_, U>, ty: InterfaceType, offset: usize) -> Result<()> {
76                <$b as Lower>::linear_lower_to_memory(&self.0, cx, ty, offset)
77            }
78        }
79
80        unsafe impl Lift for $a {
81            fn linear_lift_from_flat(cx: &mut LiftContext<'_>, ty: InterfaceType, src: &Self::Lower) -> Result<Self> {
82                Ok(Self(<$b as Lift>::linear_lift_from_flat(cx, ty, src)?))
83            }
84
85            fn linear_lift_from_memory(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Self> {
86                Ok(Self(<$b as Lift>::linear_lift_from_memory(cx, ty, bytes)?))
87            }
88        }
89
90        impl PartialEq for $a {
91            fn eq(&self, other: &Self) -> bool {
92                self.0 == other.0 || (self.0.is_nan() && other.0.is_nan())
93            }
94        }
95    )*)
96}
97
98forward_impls! {
99    Float32 => f32,
100    Float64 => f64,
101}