1 use wasmtime::component::{Component, FutureAny, FutureReader, Linker, StreamAny, StreamReader};
2 use wasmtime::{Config, Engine, Result, Store};
3 
4 #[test]
5 fn simple_type_conversions() -> Result<()> {
6     let mut config = Config::new();
7     config.wasm_component_model_async(true);
8     let engine = Engine::new(&config)?;
9     let mut store = Store::new(&engine, ());
10 
11     let f = FutureReader::new(&mut store, async { wasmtime::error::Ok(10_u32) });
12     let f = f.try_into_future_any(&mut store).unwrap();
13     assert!(f.clone().try_into_future_reader::<()>().is_err());
14     assert!(f.clone().try_into_future_reader::<u64>().is_err());
15     let f = f.try_into_future_reader::<u32>().unwrap();
16     f.try_into_future_any(&mut store).unwrap().close(&mut store);
17 
18     let s = StreamReader::new(&mut store, vec![10_u32]);
19     let s = s.try_into_stream_any(&mut store).unwrap();
20     assert!(s.clone().try_into_stream_reader::<()>().is_err());
21     assert!(s.clone().try_into_stream_reader::<u64>().is_err());
22     let s = s.try_into_stream_reader::<u32>().unwrap();
23     s.try_into_stream_any(&mut store).unwrap().close(&mut store);
24 
25     Ok(())
26 }
27 
28 #[test]
29 #[cfg_attr(miri, ignore)]
30 fn simple_type_assertions() -> Result<()> {
31     let mut config = Config::new();
32     config.wasm_component_model_async(true);
33     let engine = Engine::new(&config)?;
34     let mut store = Store::new(&engine, ());
35 
36     let component = Component::new(
37         &engine,
38         r#"
39         (component
40             (type $f (future u32))
41             (type $s (stream u32))
42             (core func $mk-f (canon future.new $f))
43             (core func $mk-s (canon stream.new $s))
44 
45             (core module $m
46                 (import "" "mk-f" (func $mk-f (result i64)))
47                 (import "" "mk-s" (func $mk-s (result i64)))
48 
49                 (func (export "x") (param i32) (result i32) local.get 0)
50 
51                 (func (export "mk-f") (result i32)
52                     (i32.wrap_i64 (call $mk-f)))
53                 (func (export "mk-s") (result i32)
54                     (i32.wrap_i64 (call $mk-s)))
55             )
56             (core instance $i (instantiate $m
57                 (with "" (instance
58                     (export "mk-f" (func $mk-f))
59                     (export "mk-s" (func $mk-s))
60                 ))
61             ))
62             (func (export "f") (param "f" $f) (result $f)
63                 (canon lift (core func $i "x")))
64             (func (export "s") (param "s" $s) (result $s)
65                 (canon lift (core func $i "x")))
66             (func (export "mk-f") (result $f)
67                 (canon lift (core func $i "mk-f")))
68             (func (export "mk-s") (result $s)
69                 (canon lift (core func $i "mk-s")))
70         )
71         "#,
72     )?;
73 
74     let instance = Linker::new(&engine).instantiate(&mut store, &component)?;
75 
76     let f_t_t =
77         instance.get_typed_func::<(FutureReader<u32>,), (FutureReader<u32>,)>(&mut store, "f")?;
78     let f_t_a = instance.get_typed_func::<(FutureReader<u32>,), (FutureAny,)>(&mut store, "f")?;
79     let f_a_t = instance.get_typed_func::<(FutureAny,), (FutureReader<u32>,)>(&mut store, "f")?;
80     let f_a_a = instance.get_typed_func::<(FutureAny,), (FutureAny,)>(&mut store, "f")?;
81 
82     let s_t_t =
83         instance.get_typed_func::<(StreamReader<u32>,), (StreamReader<u32>,)>(&mut store, "s")?;
84     let s_t_a = instance.get_typed_func::<(StreamReader<u32>,), (StreamAny,)>(&mut store, "s")?;
85     let s_a_t = instance.get_typed_func::<(StreamAny,), (StreamReader<u32>,)>(&mut store, "s")?;
86     let s_a_a = instance.get_typed_func::<(StreamAny,), (StreamAny,)>(&mut store, "s")?;
87 
88     let mk_f_t = instance.get_typed_func::<(), (FutureReader<u32>,)>(&mut store, "mk-f")?;
89     let mk_f_a = instance.get_typed_func::<(), (FutureAny,)>(&mut store, "mk-f")?;
90     let mk_s_t = instance.get_typed_func::<(), (StreamReader<u32>,)>(&mut store, "mk-s")?;
91     let mk_s_a = instance.get_typed_func::<(), (StreamAny,)>(&mut store, "mk-s")?;
92 
93     assert!(instance.get_typed_func::<(), ()>(&mut store, "f").is_err());
94     assert!(
95         instance
96             .get_typed_func::<(u32,), (FutureReader<u32>,)>(&mut store, "f")
97             .is_err()
98     );
99     assert!(
100         instance
101             .get_typed_func::<(FutureReader<u32>,), (u32,)>(&mut store, "f")
102             .is_err()
103     );
104     assert!(
105         instance
106             .get_typed_func::<(FutureReader<()>,), (FutureReader<u32>,)>(&mut store, "f")
107             .is_err()
108     );
109     assert!(
110         instance
111             .get_typed_func::<(FutureReader<u64>,), (FutureReader<u32>,)>(&mut store, "f")
112             .is_err()
113     );
114 
115     assert!(instance.get_typed_func::<(), ()>(&mut store, "s").is_err());
116     assert!(
117         instance
118             .get_typed_func::<(u32,), (StreamReader<u32>,)>(&mut store, "s")
119             .is_err()
120     );
121     assert!(
122         instance
123             .get_typed_func::<(StreamReader<u32>,), (u32,)>(&mut store, "s")
124             .is_err()
125     );
126     assert!(
127         instance
128             .get_typed_func::<(StreamReader<()>,), (StreamReader<u32>,)>(&mut store, "s")
129             .is_err()
130     );
131     assert!(
132         instance
133             .get_typed_func::<(StreamReader<u64>,), (StreamReader<u32>,)>(&mut store, "s")
134             .is_err()
135     );
136 
137     let roundtrip = |store: &mut Store<()>, f: FutureReader<u32>| -> Result<()> {
138         let (f,) = f_t_t.call(&mut *store, (f,))?;
139         let (f,) = f_t_a.call(&mut *store, (f,))?;
140         let (f,) = f_a_a.call(&mut *store, (f,))?;
141         let (mut f,) = f_a_t.call(&mut *store, (f,))?;
142         f.close(&mut *store);
143         Ok(())
144     };
145 
146     let f = FutureReader::new(&mut store, async { wasmtime::error::Ok(10_u32) });
147     roundtrip(&mut store, f)?;
148 
149     let (f,) = mk_f_t.call(&mut store, ())?;
150     roundtrip(&mut store, f)?;
151 
152     let (f,) = mk_f_a.call(&mut store, ())?;
153     let f = f.try_into_future_reader::<u32>()?;
154     roundtrip(&mut store, f)?;
155 
156     let roundtrip = |store: &mut Store<()>, s: StreamReader<u32>| -> Result<()> {
157         let (s,) = s_t_t.call(&mut *store, (s,))?;
158         let (s,) = s_t_a.call(&mut *store, (s,))?;
159         let (s,) = s_a_a.call(&mut *store, (s,))?;
160         let (mut s,) = s_a_t.call(&mut *store, (s,))?;
161         s.close(&mut *store);
162         Ok(())
163     };
164 
165     let s = StreamReader::new(&mut store, vec![10_u32]);
166     roundtrip(&mut store, s)?;
167 
168     let (s,) = mk_s_t.call(&mut store, ())?;
169     roundtrip(&mut store, s)?;
170 
171     let (s,) = mk_s_a.call(&mut store, ())?;
172     let s = s.try_into_stream_reader::<u32>()?;
173     roundtrip(&mut store, s)?;
174 
175     Ok(())
176 }
177