@@ -15,8 +15,9 @@ macro_rules! define_handles {
15
15
}
16
16
17
17
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 {
20
21
static COUNTERS : HandleCounters = HandleCounters {
21
22
$( $oty: AtomicUsize :: new( 1 ) , ) *
22
23
$( $ity: AtomicUsize :: new( 1 ) , ) *
@@ -333,29 +334,32 @@ impl Bridge<'_> {
333
334
#[ repr( C ) ]
334
335
#[ derive( Copy , Clone ) ]
335
336
pub 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.
336
339
pub ( super ) get_handle_counters : extern "C" fn ( ) -> & ' static HandleCounters ,
337
340
pub ( super ) run : extern "C" fn ( Bridge < ' _ > , F ) -> Buffer < u8 > ,
338
341
pub ( super ) f : F ,
339
342
}
340
343
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 < ( ) > > (
344
348
mut bridge : Bridge < ' _ > ,
345
- f : fn ( crate :: TokenStream ) -> crate :: TokenStream ,
349
+ f : impl FnOnce ( A ) -> R ,
346
350
) -> Buffer < u8 > {
347
351
// The initial `cached_buffer` contains the input.
348
352
let mut b = bridge. cached_buffer . take ( ) ;
349
353
350
354
panic:: catch_unwind ( panic:: AssertUnwindSafe ( || {
351
355
bridge. enter ( || {
352
356
let reader = & mut & b[ ..] ;
353
- let input = TokenStream :: decode ( reader, & mut ( ) ) ;
357
+ let input = A :: decode ( reader, & mut ( ) ) ;
354
358
355
359
// Put the `cached_buffer` back in the `Bridge`, for requests.
356
360
Bridge :: with ( |bridge| bridge. cached_buffer = b. take ( ) ) ;
357
361
358
- let output = f ( crate :: TokenStream ( input) ) . 0 ;
362
+ let output = f ( input) ;
359
363
360
364
// Take the `cached_buffer` back out, for the output value.
361
365
b = Bridge :: with ( |bridge| bridge. cached_buffer . take ( ) ) ;
@@ -383,65 +387,35 @@ pub extern "C" fn __run_expand1(
383
387
384
388
impl Client < fn ( crate :: TokenStream ) -> crate :: TokenStream > {
385
389
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
+ }
386
396
Client {
387
397
get_handle_counters : HandleCounters :: get,
388
- run : __run_expand1 ,
398
+ run,
389
399
f,
390
400
}
391
401
}
392
402
}
393
403
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
-
438
404
impl Client < fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream > {
439
405
pub const fn expand2 (
440
406
f : fn ( crate :: TokenStream , crate :: TokenStream ) -> crate :: TokenStream
441
407
) -> 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
+ }
442
416
Client {
443
417
get_handle_counters : HandleCounters :: get,
444
- run : __run_expand2 ,
418
+ run,
445
419
f,
446
420
}
447
421
}
0 commit comments