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
async_store() -> Store<()>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
func_in_store(store: &mut Store<()>) -> Result<Func>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
assert_requires_async<T>(store: &mut Store<T>)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]
async_disallows_func_call() -> Result<()>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]
async_disallows_typed_func_call() -> Result<()>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]
async_disallows_instantiate() -> Result<()>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]
require_async_after_linker_with_func_wrap_async() -> Result<()>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]
require_async_after_linker_with_func_wrap_concurrent() -> Result<()>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]
require_async_after_linker_with_func_new_async() -> Result<()>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]
require_async_after_linker_with_func_new_concurrent() -> Result<()>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]
async_disallows_resource_any_drop() -> Result<()>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