| 387 | |
| 388 | #[test] |
| 389 | fn rust_panic_import() -> Result<()> { |
| 390 | let mut store = Store::<()>::default(); |
| 391 | let binary = wat::parse_str( |
| 392 | r#" |
| 393 | (module $a |
| 394 | (import "" "" (func $foo)) |
| 395 | (import "" "" (func $bar)) |
| 396 | (func (export "foo") call $foo) |
| 397 | (func (export "bar") call $bar) |
| 398 | ) |
| 399 | "#, |
| 400 | )?; |
| 401 | |
| 402 | let module = Module::new(store.engine(), &binary)?; |
| 403 | let sig = FuncType::new(store.engine(), None, None); |
| 404 | let func = Func::new(&mut store, sig, |_, _, _| panic!("this is a panic")); |
| 405 | let func2 = Func::wrap(&mut store, || -> () { panic!("this is another panic") }); |
| 406 | let instance = Instance::new(&mut store, &module, &[func.into(), func2.into()])?; |
| 407 | let func = instance.get_typed_func::<(), ()>(&mut store, "foo")?; |
| 408 | let err = |
| 409 | panic::catch_unwind(AssertUnwindSafe(|| drop(func.call(&mut store, ())))).unwrap_err(); |
| 410 | assert_eq!(err.downcast_ref::<&'static str>(), Some(&"this is a panic")); |
| 411 | |
| 412 | let func = instance.get_typed_func::<(), ()>(&mut store, "bar")?; |
| 413 | let err = panic::catch_unwind(AssertUnwindSafe(|| { |
| 414 | drop(func.call(&mut store, ())); |
| 415 | })) |
| 416 | .unwrap_err(); |
| 417 | assert_eq!( |
| 418 | err.downcast_ref::<&'static str>(), |
| 419 | Some(&"this is another panic") |
| 420 | ); |
| 421 | Ok(()) |
| 422 | } |
| 423 | |
| 424 | // Test that we properly save/restore our trampolines' saved Wasm registers |
| 425 | // (used when capturing backtraces) before we resume panics. |