capi: better clarify story around panic safety
- catches panics for all functions now except frame for performance reasons
This commit is contained in:
parent
70aa4091e0
commit
3a5c477442
|
@ -1,6 +1,31 @@
|
||||||
macro_rules! ffi_body {
|
macro_rules! ffi_body {
|
||||||
|
(nopanic $body:block) => {
|
||||||
|
{
|
||||||
|
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||||
|
$body
|
||||||
|
};
|
||||||
|
|
||||||
|
let Err(e) = result else {
|
||||||
|
return $crate::error::LibrashaderError::ok()
|
||||||
|
};
|
||||||
|
e.export()
|
||||||
|
}
|
||||||
|
};
|
||||||
($body:block) => {
|
($body:block) => {
|
||||||
{
|
{
|
||||||
|
let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
|
||||||
|
$crate::ffi::ffi_body!(nopanic $body)
|
||||||
|
}));
|
||||||
|
|
||||||
|
result.unwrap_or_else(|e| $crate::error::LibrashaderError::UnknownError(e).export())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(nopanic |$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
|
{
|
||||||
|
$($crate::error::assert_non_null!($ref_capture);)*
|
||||||
|
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
||||||
|
$($crate::error::assert_non_null!($mut_capture);)*
|
||||||
|
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
||||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||||
$body
|
$body
|
||||||
};
|
};
|
||||||
|
@ -13,8 +38,15 @@ macro_rules! ffi_body {
|
||||||
};
|
};
|
||||||
(|$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
(|$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
{
|
{
|
||||||
$($crate::error::assert_non_null!($ref_capture);)*
|
let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
|
||||||
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
$crate::ffi::ffi_body!(nopanic |$($ref_capture),*|; mut |$($mut_capture),*| $body)
|
||||||
|
}));
|
||||||
|
|
||||||
|
result.unwrap_or_else(|e| $crate::error::LibrashaderError::UnknownError(e).export())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(nopanic mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
|
{
|
||||||
$($crate::error::assert_non_null!($mut_capture);)*
|
$($crate::error::assert_non_null!($mut_capture);)*
|
||||||
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
||||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
let result: Result<(), $crate::error::LibrashaderError> = try {
|
||||||
|
@ -29,19 +61,14 @@ macro_rules! ffi_body {
|
||||||
};
|
};
|
||||||
(mut |$($mut_capture:ident),*| $body:block) => {
|
(mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
{
|
{
|
||||||
$($crate::error::assert_non_null!($mut_capture);)*
|
let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
|
||||||
$(let $mut_capture = unsafe { &mut *$mut_capture };)*
|
$crate::ffi::ffi_body!(nopanic mut |$($mut_capture),*| $body)
|
||||||
let result: Result<(), $crate::error::LibrashaderError> = try {
|
}));
|
||||||
$body
|
|
||||||
};
|
|
||||||
|
|
||||||
let Err(e) = result else {
|
result.unwrap_or_else(|e| $crate::error::LibrashaderError::UnknownError(e).export())
|
||||||
return $crate::error::LibrashaderError::ok()
|
|
||||||
};
|
|
||||||
e.export()
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(|$($ref_capture:ident),*| $body:block) => {
|
(nopanic |$($ref_capture:ident),*| $body:block) => {
|
||||||
{
|
{
|
||||||
$($crate::error::assert_non_null!($ref_capture);)*
|
$($crate::error::assert_non_null!($ref_capture);)*
|
||||||
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
$(let $ref_capture = unsafe { &*$ref_capture };)*
|
||||||
|
@ -54,24 +81,20 @@ macro_rules! ffi_body {
|
||||||
};
|
};
|
||||||
e.export()
|
e.export()
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
(|$($ref_capture:ident),*| $body:block) => {
|
||||||
|
{
|
||||||
|
let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| {
|
||||||
|
$crate::ffi::ffi_body!(nopanic |$($ref_capture),*| $body)
|
||||||
|
}));
|
||||||
|
|
||||||
|
result.unwrap_or_else(|e| $crate::error::LibrashaderError::UnknownError(e).export())
|
||||||
}
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! extern_fn {
|
macro_rules! extern_fn {
|
||||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) $body:block) => {
|
// raw doesn't wrap in ffi_body
|
||||||
::paste::paste! {
|
|
||||||
/// Function pointer definition for
|
|
||||||
#[doc = ::std::stringify!($func_name)]
|
|
||||||
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
|
||||||
$(#[$($attrss)*])*
|
|
||||||
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
|
||||||
$crate::ffi::ffi_body!($body)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
($(#[$($attrss:tt)*])* raw fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) $body:block) => {
|
($(#[$($attrss:tt)*])* raw fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) $body:block) => {
|
||||||
::paste::paste! {
|
::paste::paste! {
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
|
@ -86,6 +109,21 @@ macro_rules! extern_fn {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ffi_body but panic-safe
|
||||||
|
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) $body:block) => {
|
||||||
|
::paste::paste! {
|
||||||
|
/// Function pointer definition for
|
||||||
|
#[doc = ::std::stringify!($func_name)]
|
||||||
|
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
$(#[$($attrss)*])*
|
||||||
|
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||||
|
$crate::ffi::ffi_body!($body)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) |$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
($(#[$($attrss:tt)*])* fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) |$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
::paste::paste! {
|
::paste::paste! {
|
||||||
/// Function pointer definition for
|
/// Function pointer definition for
|
||||||
|
@ -126,6 +164,62 @@ macro_rules! extern_fn {
|
||||||
$crate::ffi::ffi_body!(|$($ref_capture),*| $body)
|
$crate::ffi::ffi_body!(|$($ref_capture),*| $body)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// nopanic variants that are UB if panics
|
||||||
|
($(#[$($attrss:tt)*])* nopanic fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) $body:block) => {
|
||||||
|
::paste::paste! {
|
||||||
|
/// Function pointer definition for
|
||||||
|
#[doc = ::std::stringify!($func_name)]
|
||||||
|
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
$(#[$($attrss)*])*
|
||||||
|
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||||
|
$crate::ffi::ffi_body!(nopanic $body)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($(#[$($attrss:tt)*])* nopanic fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) |$($ref_capture:ident),*|; mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
|
::paste::paste! {
|
||||||
|
/// Function pointer definition for
|
||||||
|
#[doc = ::std::stringify!($func_name)]
|
||||||
|
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
$(#[$($attrss)*])*
|
||||||
|
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||||
|
$crate::ffi::ffi_body!(nopanic |$($ref_capture),*|; mut |$($mut_capture),*| $body)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
($(#[$($attrss:tt)*])* nopanic fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) mut |$($mut_capture:ident),*| $body:block) => {
|
||||||
|
::paste::paste! {
|
||||||
|
/// Function pointer definition for
|
||||||
|
#[doc = ::std::stringify!($func_name)]
|
||||||
|
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
$(#[$($attrss)*])*
|
||||||
|
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||||
|
$crate::ffi::ffi_body!(nopanic mut |$($mut_capture),*| $body)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
($(#[$($attrss:tt)*])* nopanic fn $func_name:ident ($($arg_name:ident : $arg_ty:ty),* $(,)?) |$($ref_capture:ident),*| $body:block) => {
|
||||||
|
::paste::paste! {
|
||||||
|
/// Function pointer definition for
|
||||||
|
#[doc = ::std::stringify!($func_name)]
|
||||||
|
pub type [<PFN_ $func_name>] = unsafe extern "C" fn($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
$(#[$($attrss)*])*
|
||||||
|
pub unsafe extern "C" fn $func_name($($arg_name: $arg_ty,)*) -> $crate::ctypes::libra_error_t {
|
||||||
|
$crate::ffi::ffi_body!(nopanic |$($ref_capture),*| $body)
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) use extern_fn;
|
pub(crate) use extern_fn;
|
||||||
|
|
|
@ -216,7 +216,7 @@ extern_fn! {
|
||||||
/// the filter chain was created with.
|
/// the filter chain was created with.
|
||||||
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
||||||
/// thread at a time may call this function.
|
/// thread at a time may call this function.
|
||||||
fn libra_d3d11_filter_chain_frame(
|
nopanic fn libra_d3d11_filter_chain_frame(
|
||||||
chain: *mut libra_d3d11_filter_chain_t,
|
chain: *mut libra_d3d11_filter_chain_t,
|
||||||
// cbindgen can't discover that ID3D11DeviceContext has the niche optimization
|
// cbindgen can't discover that ID3D11DeviceContext has the niche optimization
|
||||||
// so ManuallyDrop<Option<ID3D11DeviceContext>> doesn't generate correct bindings.
|
// so ManuallyDrop<Option<ID3D11DeviceContext>> doesn't generate correct bindings.
|
||||||
|
|
|
@ -226,7 +226,7 @@ extern_fn! {
|
||||||
/// and must be associated with the `ID3D12Device` this filter chain was created with.
|
/// and must be associated with the `ID3D12Device` this filter chain was created with.
|
||||||
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
||||||
/// thread at a time may call this function.
|
/// thread at a time may call this function.
|
||||||
fn libra_d3d12_filter_chain_frame(
|
nopanic fn libra_d3d12_filter_chain_frame(
|
||||||
chain: *mut libra_d3d12_filter_chain_t,
|
chain: *mut libra_d3d12_filter_chain_t,
|
||||||
command_list: ManuallyDrop<ID3D12GraphicsCommandList>,
|
command_list: ManuallyDrop<ID3D12GraphicsCommandList>,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
|
|
|
@ -172,7 +172,7 @@ extern_fn! {
|
||||||
/// thread at a time may call this function. The thread `libra_gl_filter_chain_frame` is called from
|
/// thread at a time may call this function. The thread `libra_gl_filter_chain_frame` is called from
|
||||||
/// must have its thread-local OpenGL context initialized with the same context used to create
|
/// must have its thread-local OpenGL context initialized with the same context used to create
|
||||||
/// the filter chain.
|
/// the filter chain.
|
||||||
fn libra_gl_filter_chain_frame(
|
nopanic fn libra_gl_filter_chain_frame(
|
||||||
chain: *mut libra_gl_filter_chain_t,
|
chain: *mut libra_gl_filter_chain_t,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
image: libra_source_image_gl_t,
|
image: libra_source_image_gl_t,
|
||||||
|
|
|
@ -246,7 +246,7 @@ extern_fn! {
|
||||||
/// struct.
|
/// struct.
|
||||||
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
/// - You must ensure that only one thread has access to `chain` before you call this function. Only one
|
||||||
/// thread at a time may call this function.
|
/// thread at a time may call this function.
|
||||||
fn libra_vk_filter_chain_frame(
|
nopanic fn libra_vk_filter_chain_frame(
|
||||||
chain: *mut libra_vk_filter_chain_t,
|
chain: *mut libra_vk_filter_chain_t,
|
||||||
command_buffer: vk::CommandBuffer,
|
command_buffer: vk::CommandBuffer,
|
||||||
frame_count: usize,
|
frame_count: usize,
|
||||||
|
|
Loading…
Reference in a new issue