@@ -15,8 +15,9 @@ macro_rules! define_handles {
1515 }
1616
1717 impl HandleCounters {
18- // FIXME(#53451) public to work around `Cannot create local mono-item` ICE.
19- pub extern "C" fn get( ) -> & ' static Self {
18+ // FIXME(eddyb) use a reference to the `static COUNTERS`, intead of
19+ // a wrapper `fn` pointer, once `const fn` can reference `static`s.
20+ extern "C" fn get( ) -> & ' static Self {
2021 static COUNTERS : HandleCounters = HandleCounters {
2122 $( $oty: AtomicUsize :: new( 1 ) , ) *
2223 $( $ity: AtomicUsize :: new( 1 ) , ) *
@@ -333,29 +334,32 @@ impl Bridge<'_> {
333334#[ repr( C ) ]
334335#[ derive( Copy , Clone ) ]
335336pub struct Client < F > {
337+ // FIXME(eddyb) use a reference to the `static COUNTERS`, intead of
338+ // a wrapper `fn` pointer, once `const fn` can reference `static`s.
336339 pub ( super ) get_handle_counters : extern "C" fn ( ) -> & ' static HandleCounters ,
337340 pub ( super ) run : extern "C" fn ( Bridge < ' _ > , F ) -> Buffer < u8 > ,
338341 pub ( super ) f : F ,
339342}
340343
341- // FIXME(#53451) public to work around `Cannot create local mono-item` ICE,
342- // affecting not only the function itself, but also the `BridgeState` `thread_local!`.
343- pub extern "C" fn __run_expand1 (
344+ /// Client-side helper for handling client panics, entering the bridge,
345+ /// deserializing input and serializing output.
346+ // FIXME(eddyb) maybe replace `Bridge::enter` with this?
347+ fn run_client < A : for < ' a , ' s > DecodeMut < ' a , ' s , ( ) > , R : Encode < ( ) > > (
344348 mut bridge : Bridge < ' _ > ,
345- f : fn ( crate :: TokenStream ) -> crate :: TokenStream ,
349+ f : impl FnOnce ( A ) -> R ,
346350) -> Buffer < u8 > {
347351 // The initial `cached_buffer` contains the input.
348352 let mut b = bridge. cached_buffer . take ( ) ;
349353
350354 panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
351355 bridge. enter ( || {
352356 let reader = & mut & b[ ..] ;
353- let input = TokenStream :: decode ( reader, & mut ( ) ) ;
357+ let input = A :: decode ( reader, & mut ( ) ) ;
354358
355359 // Put the `cached_buffer` back in the `Bridge`, for requests.
356360 Bridge :: with ( |bridge| bridge. cached_buffer = b. take ( ) ) ;
357361
358- let output = f ( crate :: TokenStream ( input) ) . 0 ;
362+ let output = f ( input) ;
359363
360364 // Take the `cached_buffer` back out, for the output value.
361365 b = Bridge :: with ( |bridge| bridge. cached_buffer . take ( ) ) ;
@@ -383,65 +387,35 @@ pub extern "C" fn __run_expand1(
383387
384388impl Client < fn ( crate :: TokenStream ) -> crate :: TokenStream > {
385389 pub const fn expand1 ( f : fn ( crate :: TokenStream ) -> crate :: TokenStream ) -> Self {
390+ extern "C" fn run (
391+ bridge : Bridge < ' _ > ,
392+ f : impl FnOnce ( crate :: TokenStream ) -> crate :: TokenStream ,
393+ ) -> Buffer < u8 > {
394+ run_client ( bridge, |input| f ( crate :: TokenStream ( input) ) . 0 )
395+ }
386396 Client {
387397 get_handle_counters : HandleCounters :: get,
388- run : __run_expand1 ,
398+ run,
389399 f,
390400 }
391401 }
392402}
393403
394- // FIXME(#53451) public to work around `Cannot create local mono-item` ICE,
395- // affecting not only the function itself, but also the `BridgeState` `thread_local!`.
396- pub extern "C" fn __run_expand2 (
397- mut bridge : Bridge < ' _ > ,
398- f : fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream ,
399- ) -> Buffer < u8 > {
400- // The initial `cached_buffer` contains the input.
401- let mut b = bridge. cached_buffer . take ( ) ;
402-
403- panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
404- bridge. enter ( || {
405- let reader = & mut & b[ ..] ;
406- let input = TokenStream :: decode ( reader, & mut ( ) ) ;
407- let input2 = TokenStream :: decode ( reader, & mut ( ) ) ;
408-
409- // Put the `cached_buffer` back in the `Bridge`, for requests.
410- Bridge :: with ( |bridge| bridge. cached_buffer = b. take ( ) ) ;
411-
412- let output = f ( crate :: TokenStream ( input) , crate :: TokenStream ( input2) ) . 0 ;
413-
414- // Take the `cached_buffer` back out, for the output value.
415- b = Bridge :: with ( |bridge| bridge. cached_buffer . take ( ) ) ;
416-
417- // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
418- // from encoding a panic (`Err(e: PanicMessage)`) to avoid
419- // having handles outside the `bridge.enter(|| ...)` scope, and
420- // to catch panics that could happen while encoding the success.
421- //
422- // Note that panics should be impossible beyond this point, but
423- // this is defensively trying to avoid any accidental panicking
424- // reaching the `extern "C"` (which should `abort` but may not
425- // at the moment, so this is also potentially preventing UB).
426- b. clear ( ) ;
427- Ok :: < _ , ( ) > ( output) . encode ( & mut b, & mut ( ) ) ;
428- } )
429- } ) )
430- . map_err ( PanicMessage :: from)
431- . unwrap_or_else ( |e| {
432- b. clear ( ) ;
433- Err :: < ( ) , _ > ( e) . encode ( & mut b, & mut ( ) ) ;
434- } ) ;
435- b
436- }
437-
438404impl Client < fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream > {
439405 pub const fn expand2 (
440406 f : fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream
441407 ) -> Self {
408+ extern "C" fn run (
409+ bridge : Bridge < ' _ > ,
410+ f : impl FnOnce ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream ,
411+ ) -> Buffer < u8 > {
412+ run_client ( bridge, |( input, input2) | {
413+ f ( crate :: TokenStream ( input) , crate :: TokenStream ( input2) ) . 0
414+ } )
415+ }
442416 Client {
443417 get_handle_counters : HandleCounters :: get,
444- run : __run_expand2 ,
418+ run,
445419 f,
446420 }
447421 }
0 commit comments