@@ -28,45 +28,118 @@ pub struct ShimSig<'tcx, const ARGS: usize> {
2828/// - `winapi::$ty` for a type from `std::sys::pal::windows::c`
2929#[ macro_export]
3030macro_rules! shim_sig {
31- ( extern $abi: literal fn ( $( $arg : ty ) , * $ ( , ) ? ) -> $ret: ty ) => {
31+ ( extern $abi: literal fn ( $( $args : tt ) * ) -> $( $ ret: tt ) * ) => {
3232 |this| $crate:: shims:: sig:: ShimSig {
3333 abi: std:: str :: FromStr :: from_str( $abi) . expect( "incorrect abi specified" ) ,
34- args: [ $ ( shim_sig_arg !( this, $arg ) ) , * ] ,
35- ret: shim_sig_arg!( this, $ret) ,
34+ args: shim_sig_args_sep !( this, [ $ ( $args ) * ] ) ,
35+ ret: shim_sig_arg!( this, $( $ ret) * ) ,
3636 }
3737 } ;
3838}
3939
4040/// Helper for `shim_sig!`.
41+ ///
42+ /// Groups tokens into comma-separated chunks and calls the provided macro on them.
43+ ///
44+ /// # Examples
45+ ///
46+ /// ```ignore
47+ /// shim_sig_args_sep!(this, [*const _, i32, libc::off64_t]);
48+ /// // expands to:
49+ /// [shim_sig_arg!(*const _), shim_sig_arg!(i32), shim_sig_arg!(libc::off64_t)];
50+ /// ```
51+ #[ macro_export]
52+ macro_rules! shim_sig_args_sep {
53+ ( $this: ident, [ $( $tt: tt) * ] ) => {
54+ shim_sig_args_sep!( @ $this [ ] [ ] $( $tt) * )
55+ } ;
56+
57+ // All below matchers form a fairly simple iterator over the input.
58+ // - Non-comma token - append to collector
59+ // - Comma token - call the provided macro on the collector and reset the collector
60+ // - End of input - empty collector one last time. emit output as an array
61+
62+ // Handles `,` token - take collected type and call shim_sig_arg on it.
63+ // Append the result to the final output.
64+ ( @ $this: ident [ $( $final: tt) * ] [ $( $collected: tt) * ] , $( $tt: tt) * ) => {
65+ shim_sig_args_sep!( @ $this [ $( $final) * shim_sig_arg!( $this, $( $collected) * ) , ] [ ] $( $tt) * )
66+ } ;
67+ // Handle non-comma token - append to collected type.
68+ ( @ $this: ident [ $( $final: tt) * ] [ $( $collected: tt) * ] $first: tt $( $tt: tt) * ) => {
69+ shim_sig_args_sep!( @ $this [ $( $final) * ] [ $( $collected) * $first] $( $tt) * )
70+ } ;
71+ // No more tokens - emit final output, including final non-comma type.
72+ ( @ $this: ident [ $( $final: tt) * ] [ $( $collected: tt) +] ) => {
73+ [ $( $final) * shim_sig_arg!( $this, $( $collected) * ) ]
74+ } ;
75+ // No more tokens - emit final output.
76+ ( @ $this: ident [ $( $final: tt) * ] [ ] ) => {
77+ [ $( $final) * ]
78+ } ;
79+ }
80+
81+ /// Helper for `shim_sig!`.
82+ ///
83+ /// Converts a type
4184#[ macro_export]
4285macro_rules! shim_sig_arg {
43- // Unfortuantely we cannot take apart a `ty`-typed token at compile time,
44- // so we have to stringify it and match at runtime.
45- ( $this: ident, $x: ty) => { {
46- match stringify!( $x) {
47- "i8" => $this. tcx. types. i8 ,
48- "i16" => $this. tcx. types. i16 ,
49- "i32" => $this. tcx. types. i32 ,
50- "i64" => $this. tcx. types. i64 ,
51- "i128" => $this. tcx. types. i128 ,
52- "isize" => $this. tcx. types. isize ,
53- "u8" => $this. tcx. types. u8 ,
54- "u16" => $this. tcx. types. u16 ,
55- "u32" => $this. tcx. types. u32 ,
56- "u64" => $this. tcx. types. u64 ,
57- "u128" => $this. tcx. types. u128 ,
58- "usize" => $this. tcx. types. usize ,
59- "()" => $this. tcx. types. unit,
60- "bool" => $this. tcx. types. bool ,
61- "*const _" => $this. machine. layouts. const_raw_ptr. ty,
62- "*mut _" => $this. machine. layouts. mut_raw_ptr. ty,
63- ty if let Some ( win_ty) = ty. strip_prefix( "winapi::" ) =>
64- $this. windows_ty_layout( win_ty) . ty,
65- ty if ty. contains( "::" ) =>
66- helpers:: path_ty_layout( $this, & ty. split( "::" ) . collect:: <Vec <_>>( ) ) . ty,
67- ty => panic!( "unsupported signature type {ty:?}" ) ,
68- }
69- } } ;
86+ ( $this: ident, i8 ) => {
87+ $this. tcx. types. i8
88+ } ;
89+ ( $this: ident, i16 ) => {
90+ $this. tcx. types. i16
91+ } ;
92+ ( $this: ident, i32 ) => {
93+ $this. tcx. types. i32
94+ } ;
95+ ( $this: ident, i64 ) => {
96+ $this. tcx. types. i64
97+ } ;
98+ ( $this: ident, i128 ) => {
99+ $this. tcx. types. i128
100+ } ;
101+ ( $this: ident, isize ) => {
102+ $this. tcx. types. isize
103+ } ;
104+ ( $this: ident, u8 ) => {
105+ $this. tcx. types. u8
106+ } ;
107+ ( $this: ident, u16 ) => {
108+ $this. tcx. types. u16
109+ } ;
110+ ( $this: ident, u32 ) => {
111+ $this. tcx. types. u32
112+ } ;
113+ ( $this: ident, u64 ) => {
114+ $this. tcx. types. u64
115+ } ;
116+ ( $this: ident, u128 ) => {
117+ $this. tcx. types. u128
118+ } ;
119+ ( $this: ident, usize ) => {
120+ $this. tcx. types. usize
121+ } ;
122+ ( $this: ident, ( ) ) => {
123+ $this. tcx. types. unit
124+ } ;
125+ ( $this: ident, bool ) => {
126+ $this. tcx. types. bool
127+ } ;
128+ ( $this: ident, * const _) => {
129+ $this. machine. layouts. const_raw_ptr. ty
130+ } ;
131+ ( $this: ident, * mut _) => {
132+ $this. machine. layouts. mut_raw_ptr. ty
133+ } ;
134+ ( $this: ident, winapi:: $ty: ident) => {
135+ $this. windows_ty_layout( stringify!( $ty) ) . ty
136+ } ;
137+ ( $this: ident, $krate: ident :: $( $path: ident) ::+) => {
138+ helpers:: path_ty_layout( $this, & [ stringify!( $krate) , $( stringify!( $path) ) ,* ] ) . ty
139+ } ;
140+ ( $this: ident, $( $other: tt) * ) => {
141+ compile_error!( concat!( "unsupported signature type: " , stringify!( $( $other) * ) ) )
142+ }
70143}
71144
72145/// Helper function to compare two ABIs.
0 commit comments