qemu-rust
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH 25/26] rust: qemu-api: add a module to wrap functions and zer


From: Zhao Liu
Subject: Re: [PATCH 25/26] rust: qemu-api: add a module to wrap functions and zero-sized closures
Date: Tue, 17 Dec 2024 23:03:54 +0800

> +pub unsafe trait FnCall<Args, R = ()>: 'static + Sync + Sized {
> +    /// Referring to this internal constant asserts that the `Self` type is
> +    /// zero-sized.  Can be replaced by an inline const expression in
> +    /// Rust 1.79.0+.
> +    const ASSERT_ZERO_SIZED: () = { assert!(mem::size_of::<Self>() == 0) };
> +
> +    /// Call the function with the arguments in args.
> +    fn call(a: Args) -> R;
> +}
> +
> +macro_rules! impl_call {
> +    ($($args:ident,)* ) => (
> +        // SAFETY: because each function is treated as a separate type,
> +        // accessing `FnCall` is only possible in code that would be
> +        // allowed to call the function.
> +        unsafe impl<F, $($args,)* R> FnCall<($($args,)*), R> for F
> +        where
> +            F: 'static + Sync + Sized + Fn($($args, )*) -> R,
> +        {
> +            #[inline(always)]
> +            fn call(a: ($($args,)*)) -> R {
> +                let _: () = Self::ASSERT_ZERO_SIZED;
> +
> +                // SAFETY: the safety of this method is the condition for 
> implementing
> +                // `FnCall`.  As to the `NonNull` idiom to create a 
> zero-sized type,
> +                // see https://github.com/rust-lang/libs-team/issues/292.
> +                let f: &'static F = unsafe { 
> &*NonNull::<Self>::dangling().as_ptr() };

Awesome! The definition of FnCall and this trick are both very elegant!
I've learned a lot.

> +                let ($($args,)*) = a;
> +                f($($args,)*)
> +            }
> +        }
> +    )
> +}
> +

The examples and test both show the power of this callback pattern,

Reviewed-by: Zhao Liu <zhao1.liu@intel.com>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]