()
| 171 | // Use the Linker to define a sync func, call it through WebAssembly: |
| 172 | #[test] |
| 173 | fn call_linked_func() -> Result<(), Error> { |
| 174 | let engine = Engine::default(); |
| 175 | let mut store = Store::new(&engine, State::default()); |
| 176 | store.call_hook(sync_call_hook); |
| 177 | let mut linker = Linker::new(&engine); |
| 178 | |
| 179 | linker.func_wrap( |
| 180 | "host", |
| 181 | "f", |
| 182 | |caller: Caller<State>, a: i32, b: i64, c: f32, d: f64| { |
| 183 | // Calling this func will switch context into wasm, then back to host: |
| 184 | assert_eq!(caller.data().context, vec![Context::Wasm, Context::Host]); |
| 185 | |
| 186 | assert_eq!( |
| 187 | caller.data().calls_into_host, |
| 188 | caller.data().returns_from_host + 1 |
| 189 | ); |
| 190 | assert_eq!( |
| 191 | caller.data().calls_into_wasm, |
| 192 | caller.data().returns_from_wasm + 1 |
| 193 | ); |
| 194 | |
| 195 | assert_eq!(a, 1); |
| 196 | assert_eq!(b, 2); |
| 197 | assert_eq!(c, 3.0); |
| 198 | assert_eq!(d, 4.0); |
| 199 | }, |
| 200 | )?; |
| 201 | |
| 202 | let wat = r#" |
| 203 | (module |
| 204 | (import "host" "f" |
| 205 | (func $f (param i32) (param i64) (param f32) (param f64))) |
| 206 | (func (export "export") |
| 207 | (call $f (i32.const 1) (i64.const 2) (f32.const 3.0) (f64.const 4.0))) |
| 208 | ) |
| 209 | "#; |
| 210 | let module = Module::new(&engine, wat)?; |
| 211 | |
| 212 | let inst = linker.instantiate(&mut store, &module)?; |
| 213 | let export = inst |
| 214 | .get_export(&mut store, "export") |
| 215 | .expect("get export") |
| 216 | .into_func() |
| 217 | .expect("export is func"); |
| 218 | |
| 219 | export.call(&mut store, &[], &mut [])?; |
| 220 | |
| 221 | // One switch from vm to host to call f, another in return from f. |
| 222 | assert_eq!(store.data().calls_into_host, 1); |
| 223 | assert_eq!(store.data().returns_from_host, 1); |
| 224 | assert_eq!(store.data().calls_into_wasm, 1); |
| 225 | assert_eq!(store.data().returns_from_wasm, 1); |
| 226 | |
| 227 | export.typed::<(), ()>(&store)?.call(&mut store, ())?; |
| 228 | |
| 229 | assert_eq!(store.data().calls_into_host, 2); |
| 230 | assert_eq!(store.data().returns_from_host, 2); |
nothing calls this directly
no test coverage detected