1 use arbitrary::Arbitrary;
2 use std::mem::MaybeUninit;
3 use wasmtime::component::__internal::{
4     CanonicalAbiInfo, InstanceType, InterfaceType, LiftContext, LowerContext,
5 };
6 use wasmtime::component::{ComponentType, Lift, Lower};
7 use wasmtime::{Config, Engine};
8 use wasmtime_environ::prelude::*;
9 
10 pub 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 
26 pub fn engine() -> Engine {
27     Engine::new(&config()).unwrap()
28 }
29 
30 pub fn async_engine() -> Engine {
31     Engine::default()
32 }
33 
34 /// Newtype wrapper for `f32` whose `PartialEq` impl considers NaNs equal to each other.
35 #[derive(Copy, Clone, Debug, Arbitrary)]
36 pub struct Float32(pub f32);
37 
38 /// Newtype wrapper for `f64` whose `PartialEq` impl considers NaNs equal to each other.
39 #[derive(Copy, Clone, Debug, Arbitrary)]
40 pub struct Float64(pub f64);
41 
42 macro_rules! forward_impls {
43     ($($a:ty => $b:ty,)*) => ($(
44         unsafe impl ComponentType for $a {
45             type Lower = <$b as ComponentType>::Lower;
46 
47             const ABI: CanonicalAbiInfo = <$b as ComponentType>::ABI;
48 
49             #[inline]
50             fn typecheck(ty: &InterfaceType, types: &InstanceType<'_>) -> Result<()> {
51                 <$b as ComponentType>::typecheck(ty, types)
52             }
53         }
54 
55         unsafe impl Lower for $a {
56             fn linear_lower_to_flat<U>(
57                 &self,
58                 cx: &mut LowerContext<'_, U>,
59                 ty: InterfaceType,
60                 dst: &mut MaybeUninit<Self::Lower>,
61             ) -> Result<()> {
62                 <$b as Lower>::linear_lower_to_flat(&self.0, cx, ty, dst)
63             }
64 
65             fn linear_lower_to_memory<U>(&self, cx: &mut LowerContext<'_, U>, ty: InterfaceType, offset: usize) -> Result<()> {
66                 <$b as Lower>::linear_lower_to_memory(&self.0, cx, ty, offset)
67             }
68         }
69 
70         unsafe impl Lift for $a {
71             fn linear_lift_from_flat(cx: &mut LiftContext<'_>, ty: InterfaceType, src: &Self::Lower) -> Result<Self> {
72                 Ok(Self(<$b as Lift>::linear_lift_from_flat(cx, ty, src)?))
73             }
74 
75             fn linear_lift_from_memory(cx: &mut LiftContext<'_>, ty: InterfaceType, bytes: &[u8]) -> Result<Self> {
76                 Ok(Self(<$b as Lift>::linear_lift_from_memory(cx, ty, bytes)?))
77             }
78         }
79 
80         impl PartialEq for $a {
81             fn eq(&self, other: &Self) -> bool {
82                 self.0 == other.0 || (self.0.is_nan() && other.0.is_nan())
83             }
84         }
85     )*)
86 }
87 
88 forward_impls! {
89     Float32 => f32,
90     Float64 => f64,
91 }
92