1 #![cfg(not(miri))] // not testing unsafe code 2 3 use wasmtime::component::{Component, Func, Linker, ResourceAny}; 4 use wasmtime::{Config, Engine, Result, Store}; 5 6 fn async_store() -> Store<()> { 7 let engine = Engine::default(); 8 let mut store = Store::new(&engine, ()); 9 wasmtime::Func::wrap_async(&mut store, |_, ()| Box::new(async {})); 10 return store; 11 } 12 13 async fn func_in_store(store: &mut Store<()>) -> Result<Func> { 14 let component = Component::new( 15 store.engine(), 16 r#" 17 (component 18 (core module $a 19 (func (export "hi") ) 20 ) 21 (core instance $i (instantiate $a)) 22 (func (export "hi") (canon lift (core func $i "hi"))) 23 ) 24 "#, 25 )?; 26 let instance = Linker::new(store.engine()) 27 .instantiate_async(&mut *store, &component) 28 .await?; 29 let func = instance.get_func(&mut *store, "hi").unwrap(); 30 Ok(func) 31 } 32 33 fn assert_requires_async<T>(store: &mut Store<T>) { 34 let module = wasmtime::Module::new(store.engine(), "(module)").unwrap(); 35 assert!(wasmtime::Instance::new(&mut *store, &module, &[]).is_err()); 36 } 37 38 #[tokio::test] 39 async fn async_disallows_func_call() -> Result<()> { 40 let mut store = async_store(); 41 let func = func_in_store(&mut store).await?; 42 assert!(func.call(&mut store, &[], &mut []).is_err()); 43 func.call_async(&mut store, &[], &mut []).await?; 44 Ok(()) 45 } 46 47 #[tokio::test] 48 async fn async_disallows_func_post_return() -> Result<()> { 49 let mut store = async_store(); 50 let func = func_in_store(&mut store).await?; 51 func.call_async(&mut store, &[], &mut []).await?; 52 53 assert!(func.post_return(&mut store).is_err()); 54 func.post_return_async(&mut store).await?; 55 Ok(()) 56 } 57 58 #[tokio::test] 59 async fn async_disallows_typed_func_call() -> Result<()> { 60 let mut store = async_store(); 61 let func = func_in_store(&mut store).await?; 62 let func = func.typed::<(), ()>(&store)?; 63 assert!(func.call(&mut store, ()).is_err()); 64 func.call_async(&mut store, ()).await?; 65 Ok(()) 66 } 67 68 #[tokio::test] 69 async fn async_disallows_typed_func_post_return() -> Result<()> { 70 let mut store = async_store(); 71 let func = func_in_store(&mut store).await?; 72 let func = func.typed::<(), ()>(&store)?; 73 func.call_async(&mut store, ()).await?; 74 assert!(func.post_return(&mut store).is_err()); 75 func.post_return_async(&mut store).await?; 76 Ok(()) 77 } 78 79 #[tokio::test] 80 async fn async_disallows_instantiate() -> Result<()> { 81 let mut store = async_store(); 82 let component = Component::new(store.engine(), "(component)")?; 83 let linker = Linker::new(store.engine()); 84 assert!(linker.instantiate(&mut store, &component).is_err()); 85 linker.instantiate_async(&mut store, &component).await?; 86 Ok(()) 87 } 88 89 #[tokio::test] 90 async fn require_async_after_linker_with_func_wrap_async() -> Result<()> { 91 let engine = Engine::default(); 92 let mut store = Store::new(&engine, ()); 93 let mut linker = Linker::new(store.engine()); 94 linker 95 .root() 96 .func_wrap_async("hi", |_, ()| Box::new(async { Ok(()) }))?; 97 let module = Component::new( 98 store.engine(), 99 r#" 100 (component 101 (import "hi" (func)) 102 (core func (canon lower (func 0))) 103 ) 104 "#, 105 )?; 106 linker.instantiate_async(&mut store, &module).await?; 107 assert_requires_async(&mut store); 108 Ok(()) 109 } 110 111 #[tokio::test] 112 async fn require_async_after_linker_with_func_wrap_concurrent() -> Result<()> { 113 let mut config = Config::new(); 114 config.wasm_component_model_async(true); 115 let engine = Engine::new(&config)?; 116 let mut store = Store::new(&engine, ()); 117 let mut linker = Linker::new(store.engine()); 118 linker 119 .root() 120 .func_wrap_concurrent("hi", |_, ()| Box::pin(async { Ok(()) }))?; 121 let module = Component::new( 122 store.engine(), 123 r#" 124 (component 125 (import "hi" (func async)) 126 (core func (canon lower (func 0))) 127 ) 128 "#, 129 )?; 130 linker.instantiate_async(&mut store, &module).await?; 131 assert_requires_async(&mut store); 132 Ok(()) 133 } 134 135 #[tokio::test] 136 async fn require_async_after_linker_with_func_new_async() -> Result<()> { 137 let engine = Engine::default(); 138 let mut store = Store::new(&engine, ()); 139 let mut linker = Linker::new(store.engine()); 140 linker 141 .root() 142 .func_new_async("hi", |_, _, _, _| Box::new(async { Ok(()) }))?; 143 let module = Component::new( 144 store.engine(), 145 r#" 146 (component 147 (import "hi" (func)) 148 (core func (canon lower (func 0))) 149 ) 150 "#, 151 )?; 152 linker.instantiate_async(&mut store, &module).await?; 153 assert_requires_async(&mut store); 154 Ok(()) 155 } 156 157 #[tokio::test] 158 async fn require_async_after_linker_with_func_new_concurrent() -> Result<()> { 159 let mut config = Config::new(); 160 config.wasm_component_model_async(true); 161 let engine = Engine::new(&config)?; 162 let mut store = Store::new(&engine, ()); 163 let mut linker = Linker::new(store.engine()); 164 linker 165 .root() 166 .func_new_concurrent("hi", |_, _, _, _| Box::pin(async { Ok(()) }))?; 167 let module = Component::new( 168 store.engine(), 169 r#" 170 (component 171 (import "hi" (func async)) 172 (core func (canon lower (func 0))) 173 ) 174 "#, 175 )?; 176 linker.instantiate_async(&mut store, &module).await?; 177 assert_requires_async(&mut store); 178 Ok(()) 179 } 180 181 #[tokio::test] 182 async fn async_disallows_resource_any_drop() -> Result<()> { 183 let mut store = async_store(); 184 let component = Component::new( 185 store.engine(), 186 r#" 187 (component 188 (type $t' (resource (rep i32))) 189 (export $t "t" (type $t')) 190 191 (core func $new (canon resource.new $t)) 192 (func (export "mk") (param "r" u32) (result (own $t)) 193 (canon lift (core func $new)) 194 ) 195 ) 196 "#, 197 )?; 198 let instance = Linker::new(store.engine()) 199 .instantiate_async(&mut store, &component) 200 .await?; 201 let func = instance.get_typed_func::<(u32,), (ResourceAny,)>(&mut store, "mk")?; 202 let (resource,) = func.call_async(&mut store, (42,)).await?; 203 func.post_return_async(&mut store).await?; 204 205 assert!(resource.resource_drop(&mut store).is_err()); 206 resource.resource_drop_async(&mut store).await?; 207 208 Ok(()) 209 } 210