1*cc8d04f4SAlex Crichton #![cfg(not(miri))] // not testing unsafe code
2*cc8d04f4SAlex Crichton 
3*cc8d04f4SAlex Crichton use wasmtime::*;
4*cc8d04f4SAlex Crichton 
async_store() -> Store<()>5*cc8d04f4SAlex Crichton fn async_store() -> Store<()> {
6*cc8d04f4SAlex Crichton     let engine = Engine::default();
7*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
8*cc8d04f4SAlex Crichton     Func::wrap_async(&mut store, |_, ()| Box::new(async {}));
9*cc8d04f4SAlex Crichton     return store;
10*cc8d04f4SAlex Crichton }
11*cc8d04f4SAlex Crichton 
12*cc8d04f4SAlex Crichton struct MyAsyncLimiter;
13*cc8d04f4SAlex Crichton 
14*cc8d04f4SAlex Crichton #[async_trait::async_trait]
15*cc8d04f4SAlex Crichton impl ResourceLimiterAsync for MyAsyncLimiter {
memory_growing( &mut self, _current: usize, _desired: usize, _maximum: Option<usize>, ) -> Result<bool>16*cc8d04f4SAlex Crichton     async fn memory_growing(
17*cc8d04f4SAlex Crichton         &mut self,
18*cc8d04f4SAlex Crichton         _current: usize,
19*cc8d04f4SAlex Crichton         _desired: usize,
20*cc8d04f4SAlex Crichton         _maximum: Option<usize>,
21*cc8d04f4SAlex Crichton     ) -> Result<bool> {
22*cc8d04f4SAlex Crichton         Ok(true)
23*cc8d04f4SAlex Crichton     }
24*cc8d04f4SAlex Crichton 
table_growing( &mut self, _current: usize, _desired: usize, _maximum: Option<usize>, ) -> Result<bool>25*cc8d04f4SAlex Crichton     async fn table_growing(
26*cc8d04f4SAlex Crichton         &mut self,
27*cc8d04f4SAlex Crichton         _current: usize,
28*cc8d04f4SAlex Crichton         _desired: usize,
29*cc8d04f4SAlex Crichton         _maximum: Option<usize>,
30*cc8d04f4SAlex Crichton     ) -> Result<bool> {
31*cc8d04f4SAlex Crichton         Ok(true)
32*cc8d04f4SAlex Crichton     }
33*cc8d04f4SAlex Crichton }
34*cc8d04f4SAlex Crichton 
async_limiter_store() -> Store<MyAsyncLimiter>35*cc8d04f4SAlex Crichton fn async_limiter_store() -> Store<MyAsyncLimiter> {
36*cc8d04f4SAlex Crichton     let engine = Engine::default();
37*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, MyAsyncLimiter);
38*cc8d04f4SAlex Crichton     store.limiter_async(|x| x);
39*cc8d04f4SAlex Crichton     return store;
40*cc8d04f4SAlex Crichton }
41*cc8d04f4SAlex Crichton 
assert_requires_async<T>(store: &mut Store<T>)42*cc8d04f4SAlex Crichton fn assert_requires_async<T>(store: &mut Store<T>) {
43*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), "(module)").unwrap();
44*cc8d04f4SAlex Crichton     assert!(Instance::new(&mut *store, &module, &[]).is_err());
45*cc8d04f4SAlex Crichton }
46*cc8d04f4SAlex Crichton 
47*cc8d04f4SAlex Crichton #[test]
require_async_after_func_wrap()48*cc8d04f4SAlex Crichton fn require_async_after_func_wrap() {
49*cc8d04f4SAlex Crichton     let engine = Engine::default();
50*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
51*cc8d04f4SAlex Crichton     Func::wrap_async(&mut store, |_, ()| Box::new(async {}));
52*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
53*cc8d04f4SAlex Crichton }
54*cc8d04f4SAlex Crichton 
55*cc8d04f4SAlex Crichton #[test]
require_async_after_func_new()56*cc8d04f4SAlex Crichton fn require_async_after_func_new() {
57*cc8d04f4SAlex Crichton     let engine = Engine::default();
58*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
59*cc8d04f4SAlex Crichton     let ty = FuncType::new(store.engine(), [], []);
60*cc8d04f4SAlex Crichton     Func::new_async(&mut store, ty, |_, _, _| Box::new(async { Ok(()) }));
61*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
62*cc8d04f4SAlex Crichton }
63*cc8d04f4SAlex Crichton 
64*cc8d04f4SAlex Crichton #[tokio::test]
require_async_after_linker_with_func_wrap() -> Result<()>65*cc8d04f4SAlex Crichton async fn require_async_after_linker_with_func_wrap() -> Result<()> {
66*cc8d04f4SAlex Crichton     let engine = Engine::default();
67*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
68*cc8d04f4SAlex Crichton     let mut linker = Linker::new(store.engine());
69*cc8d04f4SAlex Crichton     linker.func_wrap_async("", "", |_, ()| Box::new(async {}))?;
70*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), r#"(module (import "" "" (func)))"#)?;
71*cc8d04f4SAlex Crichton     linker.instantiate_async(&mut store, &module).await?;
72*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
73*cc8d04f4SAlex Crichton     Ok(())
74*cc8d04f4SAlex Crichton }
75*cc8d04f4SAlex Crichton 
76*cc8d04f4SAlex Crichton #[tokio::test]
require_async_after_linker_with_func_new() -> Result<()>77*cc8d04f4SAlex Crichton async fn require_async_after_linker_with_func_new() -> Result<()> {
78*cc8d04f4SAlex Crichton     let engine = Engine::default();
79*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
80*cc8d04f4SAlex Crichton     let mut linker = Linker::new(store.engine());
81*cc8d04f4SAlex Crichton     let ty = FuncType::new(store.engine(), [], []);
82*cc8d04f4SAlex Crichton     linker.func_new_async("", "", ty, |_, _, _| Box::new(async { Ok(()) }))?;
83*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), r#"(module (import "" "" (func)))"#)?;
84*cc8d04f4SAlex Crichton     linker.instantiate_async(&mut store, &module).await?;
85*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
86*cc8d04f4SAlex Crichton     Ok(())
87*cc8d04f4SAlex Crichton }
88*cc8d04f4SAlex Crichton 
89*cc8d04f4SAlex Crichton #[test]
require_async_after_epochs() -> Result<()>90*cc8d04f4SAlex Crichton fn require_async_after_epochs() -> Result<()> {
91*cc8d04f4SAlex Crichton     let mut config = Config::new();
92*cc8d04f4SAlex Crichton     config.epoch_interruption(true);
93*cc8d04f4SAlex Crichton     let engine = Engine::new(&config)?;
94*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
95*cc8d04f4SAlex Crichton     store.epoch_deadline_async_yield_and_update(1);
96*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
97*cc8d04f4SAlex Crichton     Ok(())
98*cc8d04f4SAlex Crichton }
99*cc8d04f4SAlex Crichton 
100*cc8d04f4SAlex Crichton #[test]
require_async_after_fuel() -> Result<()>101*cc8d04f4SAlex Crichton fn require_async_after_fuel() -> Result<()> {
102*cc8d04f4SAlex Crichton     let mut config = Config::new();
103*cc8d04f4SAlex Crichton     config.consume_fuel(true);
104*cc8d04f4SAlex Crichton     let engine = Engine::new(&config)?;
105*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
106*cc8d04f4SAlex Crichton     store.fuel_async_yield_interval(Some(1))?;
107*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
108*cc8d04f4SAlex Crichton     Ok(())
109*cc8d04f4SAlex Crichton }
110*cc8d04f4SAlex Crichton 
111*cc8d04f4SAlex Crichton #[test]
require_async_after_async_limiter() -> Result<()>112*cc8d04f4SAlex Crichton fn require_async_after_async_limiter() -> Result<()> {
113*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
114*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
115*cc8d04f4SAlex Crichton     Ok(())
116*cc8d04f4SAlex Crichton }
117*cc8d04f4SAlex Crichton 
118*cc8d04f4SAlex Crichton #[tokio::test]
require_async_with_linker_func_wrap() -> Result<()>119*cc8d04f4SAlex Crichton async fn require_async_with_linker_func_wrap() -> Result<()> {
120*cc8d04f4SAlex Crichton     let engine = Engine::default();
121*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
122*cc8d04f4SAlex Crichton     let mut linker = Linker::new(store.engine());
123*cc8d04f4SAlex Crichton     linker.func_wrap_async("", "", |_, ()| Box::new(async {}))?;
124*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), r#"(module (import "" "" (func)))"#)?;
125*cc8d04f4SAlex Crichton     assert!(linker.instantiate(&mut store, &module).is_err());
126*cc8d04f4SAlex Crichton     linker.instantiate_async(&mut store, &module).await?;
127*cc8d04f4SAlex Crichton     Ok(())
128*cc8d04f4SAlex Crichton }
129*cc8d04f4SAlex Crichton 
130*cc8d04f4SAlex Crichton #[test]
require_async_with_debug_handler() -> Result<()>131*cc8d04f4SAlex Crichton fn require_async_with_debug_handler() -> Result<()> {
132*cc8d04f4SAlex Crichton     let mut config = Config::new();
133*cc8d04f4SAlex Crichton     config.guest_debug(true);
134*cc8d04f4SAlex Crichton     let engine = Engine::new(&config)?;
135*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
136*cc8d04f4SAlex Crichton     store.set_debug_handler(MyDebugHandler);
137*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
138*cc8d04f4SAlex Crichton     return Ok(());
139*cc8d04f4SAlex Crichton 
140*cc8d04f4SAlex Crichton     #[derive(Clone)]
141*cc8d04f4SAlex Crichton     struct MyDebugHandler;
142*cc8d04f4SAlex Crichton 
143*cc8d04f4SAlex Crichton     impl DebugHandler for MyDebugHandler {
144*cc8d04f4SAlex Crichton         type Data = ();
145*cc8d04f4SAlex Crichton 
146*cc8d04f4SAlex Crichton         async fn handle(&self, _: StoreContextMut<'_, ()>, _: DebugEvent<'_>) {}
147*cc8d04f4SAlex Crichton     }
148*cc8d04f4SAlex Crichton }
149*cc8d04f4SAlex Crichton 
150*cc8d04f4SAlex Crichton struct MyAsyncCallHook;
151*cc8d04f4SAlex Crichton 
152*cc8d04f4SAlex Crichton #[async_trait::async_trait]
153*cc8d04f4SAlex Crichton impl CallHookHandler<()> for MyAsyncCallHook {
handle_call_event(&self, _: StoreContextMut<'_, ()>, _: CallHook) -> Result<()>154*cc8d04f4SAlex Crichton     async fn handle_call_event(&self, _: StoreContextMut<'_, ()>, _: CallHook) -> Result<()> {
155*cc8d04f4SAlex Crichton         Ok(())
156*cc8d04f4SAlex Crichton     }
157*cc8d04f4SAlex Crichton }
158*cc8d04f4SAlex Crichton 
159*cc8d04f4SAlex Crichton #[test]
require_async_with_async_call_hook() -> Result<()>160*cc8d04f4SAlex Crichton fn require_async_with_async_call_hook() -> Result<()> {
161*cc8d04f4SAlex Crichton     let engine = Engine::default();
162*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
163*cc8d04f4SAlex Crichton     store.call_hook_async(MyAsyncCallHook);
164*cc8d04f4SAlex Crichton     assert_requires_async(&mut store);
165*cc8d04f4SAlex Crichton     Ok(())
166*cc8d04f4SAlex Crichton }
167*cc8d04f4SAlex Crichton 
168*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_instance_new() -> Result<()>169*cc8d04f4SAlex Crichton async fn async_disallows_instance_new() -> Result<()> {
170*cc8d04f4SAlex Crichton     let mut store = async_store();
171*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), "(module)")?;
172*cc8d04f4SAlex Crichton     assert!(Instance::new(&mut store, &module, &[]).is_err());
173*cc8d04f4SAlex Crichton     Instance::new_async(&mut store, &module, &[]).await?;
174*cc8d04f4SAlex Crichton     Ok(())
175*cc8d04f4SAlex Crichton }
176*cc8d04f4SAlex Crichton 
177*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_linker_instantiate() -> Result<()>178*cc8d04f4SAlex Crichton async fn async_disallows_linker_instantiate() -> Result<()> {
179*cc8d04f4SAlex Crichton     let mut store = async_store();
180*cc8d04f4SAlex Crichton     let module = Module::new(store.engine(), "(module)")?;
181*cc8d04f4SAlex Crichton     let linker = Linker::new(store.engine());
182*cc8d04f4SAlex Crichton     assert!(linker.instantiate(&mut store, &module).is_err());
183*cc8d04f4SAlex Crichton     linker.instantiate_async(&mut store, &module).await?;
184*cc8d04f4SAlex Crichton     Ok(())
185*cc8d04f4SAlex Crichton }
186*cc8d04f4SAlex Crichton 
187*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_func_call() -> Result<()>188*cc8d04f4SAlex Crichton async fn async_disallows_func_call() -> Result<()> {
189*cc8d04f4SAlex Crichton     let mut store = async_store();
190*cc8d04f4SAlex Crichton     let func = Func::wrap(&mut store, || {});
191*cc8d04f4SAlex Crichton     assert!(func.call(&mut store, &[], &mut []).is_err());
192*cc8d04f4SAlex Crichton     func.call_async(&mut store, &[], &mut []).await?;
193*cc8d04f4SAlex Crichton     Ok(())
194*cc8d04f4SAlex Crichton }
195*cc8d04f4SAlex Crichton 
196*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_typed_func_call() -> Result<()>197*cc8d04f4SAlex Crichton async fn async_disallows_typed_func_call() -> Result<()> {
198*cc8d04f4SAlex Crichton     let mut store = async_store();
199*cc8d04f4SAlex Crichton     let func = Func::wrap(&mut store, || {});
200*cc8d04f4SAlex Crichton     let func = func.typed::<(), ()>(&mut store)?;
201*cc8d04f4SAlex Crichton     assert!(func.call(&mut store, ()).is_err());
202*cc8d04f4SAlex Crichton     func.call_async(&mut store, ()).await?;
203*cc8d04f4SAlex Crichton     Ok(())
204*cc8d04f4SAlex Crichton }
205*cc8d04f4SAlex Crichton 
206*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_gc() -> Result<()>207*cc8d04f4SAlex Crichton async fn async_disallows_gc() -> Result<()> {
208*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
209*cc8d04f4SAlex Crichton     assert!(store.gc(None).is_err());
210*cc8d04f4SAlex Crichton     store.gc_async(None).await;
211*cc8d04f4SAlex Crichton     Ok(())
212*cc8d04f4SAlex Crichton }
213*cc8d04f4SAlex Crichton 
214*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_array_ref_new() -> Result<()>215*cc8d04f4SAlex Crichton async fn async_disallows_array_ref_new() -> Result<()> {
216*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
217*cc8d04f4SAlex Crichton     let ty = ArrayType::new(
218*cc8d04f4SAlex Crichton         store.engine(),
219*cc8d04f4SAlex Crichton         FieldType::new(Mutability::Var, StorageType::I8),
220*cc8d04f4SAlex Crichton     );
221*cc8d04f4SAlex Crichton     let pre = ArrayRefPre::new(&mut store, ty);
222*cc8d04f4SAlex Crichton     assert!(ArrayRef::new(&mut store, &pre, &Val::I32(0), 10).is_err());
223*cc8d04f4SAlex Crichton     ArrayRef::new_async(&mut store, &pre, &Val::I32(0), 10).await?;
224*cc8d04f4SAlex Crichton     Ok(())
225*cc8d04f4SAlex Crichton }
226*cc8d04f4SAlex Crichton 
227*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_array_ref_new_fixed() -> Result<()>228*cc8d04f4SAlex Crichton async fn async_disallows_array_ref_new_fixed() -> Result<()> {
229*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
230*cc8d04f4SAlex Crichton     let ty = ArrayType::new(
231*cc8d04f4SAlex Crichton         store.engine(),
232*cc8d04f4SAlex Crichton         FieldType::new(Mutability::Var, StorageType::I8),
233*cc8d04f4SAlex Crichton     );
234*cc8d04f4SAlex Crichton     let pre = ArrayRefPre::new(&mut store, ty);
235*cc8d04f4SAlex Crichton     assert!(ArrayRef::new_fixed(&mut store, &pre, &[Val::I32(0)]).is_err());
236*cc8d04f4SAlex Crichton     ArrayRef::new_fixed_async(&mut store, &pre, &[Val::I32(0)]).await?;
237*cc8d04f4SAlex Crichton     Ok(())
238*cc8d04f4SAlex Crichton }
239*cc8d04f4SAlex Crichton 
240*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_exnref_new() -> Result<()>241*cc8d04f4SAlex Crichton async fn async_disallows_exnref_new() -> Result<()> {
242*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
243*cc8d04f4SAlex Crichton     let ty = ExnType::new(store.engine(), [])?;
244*cc8d04f4SAlex Crichton     let pre = ExnRefPre::new(&mut store, ty);
245*cc8d04f4SAlex Crichton     let fty = FuncType::new(store.engine(), [], []);
246*cc8d04f4SAlex Crichton     let tag = Tag::new(&mut store, &TagType::new(fty))?;
247*cc8d04f4SAlex Crichton     assert!(ExnRef::new(&mut store, &pre, &tag, &[]).is_err());
248*cc8d04f4SAlex Crichton     ExnRef::new_async(&mut store, &pre, &tag, &[]).await?;
249*cc8d04f4SAlex Crichton     Ok(())
250*cc8d04f4SAlex Crichton }
251*cc8d04f4SAlex Crichton 
252*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_externref_new() -> Result<()>253*cc8d04f4SAlex Crichton async fn async_disallows_externref_new() -> Result<()> {
254*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
255*cc8d04f4SAlex Crichton     assert!(ExternRef::new(&mut store, 1).is_err());
256*cc8d04f4SAlex Crichton     ExternRef::new_async(&mut store, 1).await?;
257*cc8d04f4SAlex Crichton     Ok(())
258*cc8d04f4SAlex Crichton }
259*cc8d04f4SAlex Crichton 
260*cc8d04f4SAlex Crichton #[tokio::test]
async_disallows_structref_new() -> Result<()>261*cc8d04f4SAlex Crichton async fn async_disallows_structref_new() -> Result<()> {
262*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
263*cc8d04f4SAlex Crichton     let ty = StructType::new(
264*cc8d04f4SAlex Crichton         store.engine(),
265*cc8d04f4SAlex Crichton         [FieldType::new(Mutability::Var, StorageType::I8)],
266*cc8d04f4SAlex Crichton     )?;
267*cc8d04f4SAlex Crichton     let pre = StructRefPre::new(&mut store, ty);
268*cc8d04f4SAlex Crichton     assert!(StructRef::new(&mut store, &pre, &[Val::I32(0)]).is_err());
269*cc8d04f4SAlex Crichton     StructRef::new_async(&mut store, &pre, &[Val::I32(0)]).await?;
270*cc8d04f4SAlex Crichton     Ok(())
271*cc8d04f4SAlex Crichton }
272*cc8d04f4SAlex Crichton 
273*cc8d04f4SAlex Crichton #[test]
epoch_yield_disallowed_without_async() -> Result<()>274*cc8d04f4SAlex Crichton fn epoch_yield_disallowed_without_async() -> Result<()> {
275*cc8d04f4SAlex Crichton     let mut config = Config::new();
276*cc8d04f4SAlex Crichton     config.epoch_interruption(true);
277*cc8d04f4SAlex Crichton     let engine = Engine::new(&config)?;
278*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, ());
279*cc8d04f4SAlex Crichton 
280*cc8d04f4SAlex Crichton     let module = Module::new(&engine, r#"(module (func (export "") (loop br 0)))"#)?;
281*cc8d04f4SAlex Crichton     let instance = Instance::new(&mut store, &module, &[])?;
282*cc8d04f4SAlex Crichton     let func = instance.get_typed_func::<(), ()>(&mut store, "")?;
283*cc8d04f4SAlex Crichton 
284*cc8d04f4SAlex Crichton     store.epoch_deadline_callback(|_store| Ok(UpdateDeadline::Yield(1)));
285*cc8d04f4SAlex Crichton     assert!(func.call(&mut store, ()).is_err());
286*cc8d04f4SAlex Crichton 
287*cc8d04f4SAlex Crichton     store.epoch_deadline_callback(|_store| Ok(UpdateDeadline::YieldCustom(1, Box::pin(async {}))));
288*cc8d04f4SAlex Crichton     assert!(func.call(&mut store, ()).is_err());
289*cc8d04f4SAlex Crichton 
290*cc8d04f4SAlex Crichton     store.epoch_deadline_trap();
291*cc8d04f4SAlex Crichton     let err = func.call(&mut store, ()).unwrap_err().downcast::<Trap>()?;
292*cc8d04f4SAlex Crichton     assert_eq!(err, Trap::Interrupt);
293*cc8d04f4SAlex Crichton     Ok(())
294*cc8d04f4SAlex Crichton }
295*cc8d04f4SAlex Crichton 
296*cc8d04f4SAlex Crichton #[test]
start_sync_then_configure_async_then_do_async() -> Result<()>297*cc8d04f4SAlex Crichton fn start_sync_then_configure_async_then_do_async() -> Result<()> {
298*cc8d04f4SAlex Crichton     let mut config = Config::new();
299*cc8d04f4SAlex Crichton     config.consume_fuel(true);
300*cc8d04f4SAlex Crichton     let engine = Engine::new(&config)?;
301*cc8d04f4SAlex Crichton     let mut store = Store::new(&engine, MyAsyncLimiter);
302*cc8d04f4SAlex Crichton 
303*cc8d04f4SAlex Crichton     let module = Module::new(
304*cc8d04f4SAlex Crichton         &engine,
305*cc8d04f4SAlex Crichton         r#"
306*cc8d04f4SAlex Crichton             (module
307*cc8d04f4SAlex Crichton                 (import "" "" (func $host))
308*cc8d04f4SAlex Crichton                 (memory 1)
309*cc8d04f4SAlex Crichton                 (func (export "")
310*cc8d04f4SAlex Crichton                     call $host
311*cc8d04f4SAlex Crichton                     (loop br 0)
312*cc8d04f4SAlex Crichton                 )
313*cc8d04f4SAlex Crichton             )
314*cc8d04f4SAlex Crichton         "#,
315*cc8d04f4SAlex Crichton     )?;
316*cc8d04f4SAlex Crichton 
317*cc8d04f4SAlex Crichton     let mut linker = Linker::new(&engine);
318*cc8d04f4SAlex Crichton     linker.func_wrap("", "", |mut store: Caller<'_, MyAsyncLimiter>| {
319*cc8d04f4SAlex Crichton         store.as_context_mut().fuel_async_yield_interval(Some(1))
320*cc8d04f4SAlex Crichton     })?;
321*cc8d04f4SAlex Crichton     store.set_fuel(100)?;
322*cc8d04f4SAlex Crichton     let instance = linker.instantiate(&mut store, &module)?;
323*cc8d04f4SAlex Crichton     let func = instance.get_typed_func::<(), ()>(&mut store, "")?;
324*cc8d04f4SAlex Crichton     let err = func.call(&mut store, ()).unwrap_err();
325*cc8d04f4SAlex Crichton     assert!(
326*cc8d04f4SAlex Crichton         format!("{err:?}").contains("configured to do async things"),
327*cc8d04f4SAlex Crichton         "bad error {err:?}",
328*cc8d04f4SAlex Crichton     );
329*cc8d04f4SAlex Crichton     Ok(())
330*cc8d04f4SAlex Crichton }
331*cc8d04f4SAlex Crichton 
332*cc8d04f4SAlex Crichton #[tokio::test]
async_limiter_disallows_table_new() -> Result<()>333*cc8d04f4SAlex Crichton async fn async_limiter_disallows_table_new() -> Result<()> {
334*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
335*cc8d04f4SAlex Crichton     let ty = TableType::new(RefType::FUNCREF, 1, None);
336*cc8d04f4SAlex Crichton     assert!(Table::new(&mut store, ty.clone(), Ref::Func(None)).is_err());
337*cc8d04f4SAlex Crichton     Table::new_async(&mut store, ty, Ref::Func(None)).await?;
338*cc8d04f4SAlex Crichton     Ok(())
339*cc8d04f4SAlex Crichton }
340*cc8d04f4SAlex Crichton 
341*cc8d04f4SAlex Crichton #[tokio::test]
async_limiter_disallows_table_grow() -> Result<()>342*cc8d04f4SAlex Crichton async fn async_limiter_disallows_table_grow() -> Result<()> {
343*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
344*cc8d04f4SAlex Crichton     let ty = TableType::new(RefType::FUNCREF, 1, None);
345*cc8d04f4SAlex Crichton     let table = Table::new_async(&mut store, ty, Ref::Func(None)).await?;
346*cc8d04f4SAlex Crichton     assert!(table.grow(&mut store, 1, Ref::Func(None)).is_err());
347*cc8d04f4SAlex Crichton     table.grow_async(&mut store, 1, Ref::Func(None)).await?;
348*cc8d04f4SAlex Crichton     Ok(())
349*cc8d04f4SAlex Crichton }
350*cc8d04f4SAlex Crichton 
351*cc8d04f4SAlex Crichton #[tokio::test]
async_limiter_disallows_memory_new() -> Result<()>352*cc8d04f4SAlex Crichton async fn async_limiter_disallows_memory_new() -> Result<()> {
353*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
354*cc8d04f4SAlex Crichton     let ty = MemoryType::new(1, None);
355*cc8d04f4SAlex Crichton     assert!(Memory::new(&mut store, ty.clone()).is_err());
356*cc8d04f4SAlex Crichton     Memory::new_async(&mut store, ty).await?;
357*cc8d04f4SAlex Crichton     Ok(())
358*cc8d04f4SAlex Crichton }
359*cc8d04f4SAlex Crichton 
360*cc8d04f4SAlex Crichton #[tokio::test]
async_limiter_disallows_memory_grow() -> Result<()>361*cc8d04f4SAlex Crichton async fn async_limiter_disallows_memory_grow() -> Result<()> {
362*cc8d04f4SAlex Crichton     let mut store = async_limiter_store();
363*cc8d04f4SAlex Crichton     let ty = MemoryType::new(1, None);
364*cc8d04f4SAlex Crichton     let mem = Memory::new_async(&mut store, ty).await?;
365*cc8d04f4SAlex Crichton     assert!(mem.grow(&mut store, 1).is_err());
366*cc8d04f4SAlex Crichton     mem.grow_async(&mut store, 1).await?;
367*cc8d04f4SAlex Crichton     Ok(())
368*cc8d04f4SAlex Crichton }
369