()
| 965 | |
| 966 | #[tokio::test] |
| 967 | async fn async_then_sync_trap() -> Result<()> { |
| 968 | // Test the trapping and capturing the stack with the following sequence of |
| 969 | // calls: |
| 970 | // |
| 971 | // a[async] ---> b[host] ---> c[sync] |
| 972 | |
| 973 | drop(env_logger::try_init()); |
| 974 | |
| 975 | let wat = r#" |
| 976 | (module |
| 977 | (import "" "b" (func $b)) |
| 978 | (func $a (export "a") |
| 979 | call $b |
| 980 | ) |
| 981 | (func $c (export "c") |
| 982 | unreachable |
| 983 | ) |
| 984 | ) |
| 985 | "#; |
| 986 | |
| 987 | let mut sync_store = Store::new(&Engine::default(), ()); |
| 988 | |
| 989 | let sync_module = Module::new(sync_store.engine(), wat)?; |
| 990 | |
| 991 | let mut sync_linker = Linker::new(sync_store.engine()); |
| 992 | sync_linker.func_wrap("", "b", |_caller: Caller<_>| -> () { unreachable!() })?; |
| 993 | |
| 994 | let sync_instance = sync_linker.instantiate(&mut sync_store, &sync_module)?; |
| 995 | |
| 996 | struct AsyncCtx { |
| 997 | sync_instance: Instance, |
| 998 | sync_store: Store<()>, |
| 999 | } |
| 1000 | |
| 1001 | let mut async_store = Store::new( |
| 1002 | &Engine::default(), |
| 1003 | AsyncCtx { |
| 1004 | sync_instance, |
| 1005 | sync_store, |
| 1006 | }, |
| 1007 | ); |
| 1008 | |
| 1009 | let async_module = Module::new(async_store.engine(), wat)?; |
| 1010 | |
| 1011 | let mut async_linker = Linker::new(async_store.engine()); |
| 1012 | async_linker.func_wrap("", "b", move |mut caller: Caller<AsyncCtx>| { |
| 1013 | log::info!("Called `b`..."); |
| 1014 | let sync_instance = caller.data().sync_instance; |
| 1015 | let sync_store = &mut caller.data_mut().sync_store; |
| 1016 | |
| 1017 | log::info!("Calling `c`..."); |
| 1018 | let c = sync_instance |
| 1019 | .get_typed_func::<(), ()>(&mut *sync_store, "c") |
| 1020 | .unwrap(); |
| 1021 | c.call(sync_store, ())?; |
| 1022 | Ok(()) |
| 1023 | })?; |
| 1024 |
nothing calls this directly
no test coverage detected