• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 macro_rules! ffi_fn {
2     (fn $name:ident($($arg:ident: $arg_ty:ty),*,) -> $ret:ty $body:block) => {
3         ffi_fn!(fn $name($($arg: $arg_ty),*) -> $ret $body);
4     };
5     (fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block) => {
6         #[no_mangle]
7         pub extern fn $name($($arg: $arg_ty),*) -> $ret {
8             use ::std::io::{self, Write};
9             use ::std::panic::{self, AssertUnwindSafe};
10             use ::libc::abort;
11             match panic::catch_unwind(AssertUnwindSafe(move || $body)) {
12                 Ok(v) => v,
13                 Err(err) => {
14                     let msg = if let Some(&s) = err.downcast_ref::<&str>() {
15                         s.to_owned()
16                     } else if let Some(s) = err.downcast_ref::<String>() {
17                         s.to_owned()
18                     } else {
19                         "UNABLE TO SHOW RESULT OF PANIC.".to_owned()
20                     };
21                     let _ = writeln!(
22                         &mut io::stderr(),
23                         "panic unwind caught, aborting: {:?}",
24                         msg);
25                     unsafe { abort() }
26                 }
27             }
28         }
29     };
30     (fn $name:ident($($arg:ident: $arg_ty:ty),*,) $body:block) => {
31         ffi_fn!(fn $name($($arg: $arg_ty),*) -> () $body);
32     };
33     (fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block) => {
34         ffi_fn!(fn $name($($arg: $arg_ty),*) -> () $body);
35     };
36 }
37