@@ -341,22 +341,25 @@ pub struct Client<F> {
341341 pub ( super ) f : F ,
342342}
343343
344- 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 < ( ) > > (
345348 mut bridge : Bridge < ' _ > ,
346- f : fn ( crate :: TokenStream ) -> crate :: TokenStream ,
349+ f : impl FnOnce ( A ) -> R ,
347350) -> Buffer < u8 > {
348351 // The initial `cached_buffer` contains the input.
349352 let mut b = bridge. cached_buffer . take ( ) ;
350353
351354 panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
352355 bridge. enter ( || {
353356 let reader = & mut & b[ ..] ;
354- let input = TokenStream :: decode ( reader, & mut ( ) ) ;
357+ let input = A :: decode ( reader, & mut ( ) ) ;
355358
356359 // Put the `cached_buffer` back in the `Bridge`, for requests.
357360 Bridge :: with ( |bridge| bridge. cached_buffer = b. take ( ) ) ;
358361
359- let output = f ( crate :: TokenStream ( input) ) . 0 ;
362+ let output = f ( input) ;
360363
361364 // Take the `cached_buffer` back out, for the output value.
362365 b = Bridge :: with ( |bridge| bridge. cached_buffer . take ( ) ) ;
@@ -384,63 +387,35 @@ extern "C" fn run_expand1(
384387
385388impl Client < fn ( crate :: TokenStream ) -> crate :: TokenStream > {
386389 pub const fn expand1 ( f : fn ( crate :: TokenStream ) -> crate :: TokenStream ) -> Self {
390+ extern "C" fn run (
391+ bridge : Bridge < ' _ > ,
392+ f : fn ( crate :: TokenStream ) -> crate :: TokenStream ,
393+ ) -> Buffer < u8 > {
394+ run_client ( bridge, |input| f ( crate :: TokenStream ( input) ) . 0 )
395+ }
387396 Client {
388397 get_handle_counters : HandleCounters :: get,
389- run : run_expand1 ,
398+ run,
390399 f,
391400 }
392401 }
393402}
394403
395- extern "C" fn run_expand2 (
396- mut bridge : Bridge < ' _ > ,
397- f : fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream ,
398- ) -> Buffer < u8 > {
399- // The initial `cached_buffer` contains the input.
400- let mut b = bridge. cached_buffer . take ( ) ;
401-
402- panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
403- bridge. enter ( || {
404- let reader = & mut & b[ ..] ;
405- let input = TokenStream :: decode ( reader, & mut ( ) ) ;
406- let input2 = TokenStream :: decode ( reader, & mut ( ) ) ;
407-
408- // Put the `cached_buffer` back in the `Bridge`, for requests.
409- Bridge :: with ( |bridge| bridge. cached_buffer = b. take ( ) ) ;
410-
411- let output = f ( crate :: TokenStream ( input) , crate :: TokenStream ( input2) ) . 0 ;
412-
413- // Take the `cached_buffer` back out, for the output value.
414- b = Bridge :: with ( |bridge| bridge. cached_buffer . take ( ) ) ;
415-
416- // HACK(eddyb) Separate encoding a success value (`Ok(output)`)
417- // from encoding a panic (`Err(e: PanicMessage)`) to avoid
418- // having handles outside the `bridge.enter(|| ...)` scope, and
419- // to catch panics that could happen while encoding the success.
420- //
421- // Note that panics should be impossible beyond this point, but
422- // this is defensively trying to avoid any accidental panicking
423- // reaching the `extern "C"` (which should `abort` but may not
424- // at the moment, so this is also potentially preventing UB).
425- b. clear ( ) ;
426- Ok :: < _ , ( ) > ( output) . encode ( & mut b, & mut ( ) ) ;
427- } )
428- } ) )
429- . map_err ( PanicMessage :: from)
430- . unwrap_or_else ( |e| {
431- b. clear ( ) ;
432- Err :: < ( ) , _ > ( e) . encode ( & mut b, & mut ( ) ) ;
433- } ) ;
434- b
435- }
436-
437404impl Client < fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream > {
438405 pub const fn expand2 (
439406 f : fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream
440407 ) -> Self {
408+ extern "C" fn run (
409+ bridge : Bridge < ' _ > ,
410+ f : fn ( 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+ }
441416 Client {
442417 get_handle_counters : HandleCounters :: get,
443- run : run_expand2 ,
418+ run,
444419 f,
445420 }
446421 }
0 commit comments