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_typed_func_call() -> Result<()> { 49 let mut store = async_store(); 50 let func = func_in_store(&mut store).await?; 51 let func = func.typed::<(), ()>(&store)?; 52 assert!(func.call(&mut store, ()).is_err()); 53 func.call_async(&mut store, ()).await?; 54 Ok(()) 55 } 56 57 #[tokio::test] 58 async fn async_disallows_instantiate() -> Result<()> { 59 let mut store = async_store(); 60 let component = Component::new(store.engine(), "(component)")?; 61 let linker = Linker::new(store.engine()); 62 assert!(linker.instantiate(&mut store, &component).is_err()); 63 linker.instantiate_async(&mut store, &component).await?; 64 Ok(()) 65 } 66 67 #[tokio::test] 68 async fn require_async_after_linker_with_func_wrap_async() -> Result<()> { 69 let engine = Engine::default(); 70 let mut store = Store::new(&engine, ()); 71 let mut linker = Linker::new(store.engine()); 72 linker 73 .root() 74 .func_wrap_async("hi", |_, ()| Box::new(async { Ok(()) }))?; 75 let module = Component::new( 76 store.engine(), 77 r#" 78 (component 79 (import "hi" (func)) 80 (core func (canon lower (func 0))) 81 ) 82 "#, 83 )?; 84 linker.instantiate_async(&mut store, &module).await?; 85 assert_requires_async(&mut store); 86 Ok(()) 87 } 88 89 #[tokio::test] 90 async fn require_async_after_linker_with_func_wrap_concurrent() -> Result<()> { 91 let mut config = Config::new(); 92 config.wasm_component_model_async(true); 93 let engine = Engine::new(&config)?; 94 let mut store = Store::new(&engine, ()); 95 let mut linker = Linker::new(store.engine()); 96 linker 97 .root() 98 .func_wrap_concurrent("hi", |_, ()| Box::pin(async { Ok(()) }))?; 99 let module = Component::new( 100 store.engine(), 101 r#" 102 (component 103 (import "hi" (func async)) 104 (core func (canon lower (func 0))) 105 ) 106 "#, 107 )?; 108 linker.instantiate_async(&mut store, &module).await?; 109 assert_requires_async(&mut store); 110 Ok(()) 111 } 112 113 #[tokio::test] 114 async fn require_async_after_linker_with_func_new_async() -> Result<()> { 115 let engine = Engine::default(); 116 let mut store = Store::new(&engine, ()); 117 let mut linker = Linker::new(store.engine()); 118 linker 119 .root() 120 .func_new_async("hi", |_, _, _, _| Box::new(async { Ok(()) }))?; 121 let module = Component::new( 122 store.engine(), 123 r#" 124 (component 125 (import "hi" (func)) 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_concurrent() -> Result<()> { 137 let mut config = Config::new(); 138 config.wasm_component_model_async(true); 139 let engine = Engine::new(&config)?; 140 let mut store = Store::new(&engine, ()); 141 let mut linker = Linker::new(store.engine()); 142 linker 143 .root() 144 .func_new_concurrent("hi", |_, _, _, _| Box::pin(async { Ok(()) }))?; 145 let module = Component::new( 146 store.engine(), 147 r#" 148 (component 149 (import "hi" (func async)) 150 (core func (canon lower (func 0))) 151 ) 152 "#, 153 )?; 154 linker.instantiate_async(&mut store, &module).await?; 155 assert_requires_async(&mut store); 156 Ok(()) 157 } 158 159 #[tokio::test] 160 async fn async_disallows_resource_any_drop() -> Result<()> { 161 let mut store = async_store(); 162 let component = Component::new( 163 store.engine(), 164 r#" 165 (component 166 (type $t' (resource (rep i32))) 167 (export $t "t" (type $t')) 168 169 (core func $new (canon resource.new $t)) 170 (func (export "mk") (param "r" u32) (result (own $t)) 171 (canon lift (core func $new)) 172 ) 173 ) 174 "#, 175 )?; 176 let instance = Linker::new(store.engine()) 177 .instantiate_async(&mut store, &component) 178 .await?; 179 let func = instance.get_typed_func::<(u32,), (ResourceAny,)>(&mut store, "mk")?; 180 let (resource,) = func.call_async(&mut store, (42,)).await?; 181 182 assert!(resource.resource_drop(&mut store).is_err()); 183 resource.resource_drop_async(&mut store).await?; 184 185 Ok(()) 186 } 187