summaryrefslogtreecommitdiffstats
path: root/third_party/rust/hyper/src/ffi/macros.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/hyper/src/ffi/macros.rs')
-rw-r--r--third_party/rust/hyper/src/ffi/macros.rs53
1 files changed, 53 insertions, 0 deletions
diff --git a/third_party/rust/hyper/src/ffi/macros.rs b/third_party/rust/hyper/src/ffi/macros.rs
new file mode 100644
index 0000000000..022711baaa
--- /dev/null
+++ b/third_party/rust/hyper/src/ffi/macros.rs
@@ -0,0 +1,53 @@
+macro_rules! ffi_fn {
+ ($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block ?= $default:expr) => {
+ $(#[$doc])*
+ #[no_mangle]
+ pub extern fn $name($($arg: $arg_ty),*) -> $ret {
+ use std::panic::{self, AssertUnwindSafe};
+
+ match panic::catch_unwind(AssertUnwindSafe(move || $body)) {
+ Ok(v) => v,
+ Err(_) => {
+ $default
+ }
+ }
+ }
+ };
+
+ ($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) -> $ret:ty $body:block) => {
+ ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> $ret $body ?= {
+ eprintln!("panic unwind caught, aborting");
+ std::process::abort()
+ });
+ };
+
+ ($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block ?= $default:expr) => {
+ ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> () $body ?= $default);
+ };
+
+ ($(#[$doc:meta])* fn $name:ident($($arg:ident: $arg_ty:ty),*) $body:block) => {
+ ffi_fn!($(#[$doc])* fn $name($($arg: $arg_ty),*) -> () $body);
+ };
+}
+
+macro_rules! non_null {
+ ($ptr:ident, $eval:expr, $err:expr) => {{
+ debug_assert!(!$ptr.is_null(), "{:?} must not be null", stringify!($ptr));
+ if $ptr.is_null() {
+ return $err;
+ }
+ unsafe { $eval }
+ }};
+ (&*$ptr:ident ?= $err:expr) => {{
+ non_null!($ptr, &*$ptr, $err)
+ }};
+ (&mut *$ptr:ident ?= $err:expr) => {{
+ non_null!($ptr, &mut *$ptr, $err)
+ }};
+ (Box::from_raw($ptr:ident) ?= $err:expr) => {{
+ non_null!($ptr, Box::from_raw($ptr), $err)
+ }};
+ (Arc::from_raw($ptr:ident) ?= $err:expr) => {{
+ non_null!($ptr, Arc::from_raw($ptr), $err)
+ }};
+}