1- use core:: mem:: { ManuallyDrop , MaybeUninit } ;
1+ use core:: mem:: ManuallyDrop ;
22use crossbeam_queue:: ArrayQueue ;
33use std:: sync:: { Arc , Weak } ;
44use wasmtime:: { StackCreator , StackMemory } ;
55use wasmtime_internal_fiber:: FiberStack ;
66
7+ /// The stack size for async stacks.
8+ pub const ASYNC_STACK_SIZE : usize = 2 << 20 ;
9+
710pub struct PoolingStackCreator {
811 /// The actual pool of stacks.
912 pool : ArrayQueue < FiberStack > ,
1013 /// A weak reference to `self` that can be cloned
1114 /// and put into a `PooledFiberStack` which uses `weak` on drop.
1215 /// We do it self-referentially so that we can avoid another indirection.
13- weak : MaybeUninit < Weak < PoolingStackCreator > > ,
16+ weak : Weak < PoolingStackCreator > ,
1417}
1518
1619struct PooledFiberStack {
@@ -33,19 +36,21 @@ impl Drop for PooledFiberStack {
3336 }
3437}
3538
39+ const UNIX_SOME : & str = "FiberStack on unix always returns `Some(_)`" ;
40+
3641/// SAFETY: The implementation forwards to `FiberStack as StackMemory`,
3742/// which wasmtime promises to be sound.
3843unsafe impl StackMemory for PooledFiberStack {
3944 fn top ( & self ) -> * mut u8 {
40- self . stack . top ( ) . unwrap ( )
45+ self . stack . top ( ) . expect ( UNIX_SOME )
4146 }
4247
4348 fn range ( & self ) -> std:: ops:: Range < usize > {
44- self . stack . range ( ) . unwrap ( )
49+ self . stack . range ( ) . expect ( UNIX_SOME )
4550 }
4651
4752 fn guard_range ( & self ) -> std:: ops:: Range < * mut u8 > {
48- self . stack . guard_range ( ) . unwrap ( )
53+ self . stack . guard_range ( ) . expect ( UNIX_SOME )
4954 }
5055}
5156
@@ -54,15 +59,17 @@ unsafe impl StackMemory for PooledFiberStack {
5459// and are not modified elsewhere.
5560unsafe impl StackCreator for PoolingStackCreator {
5661 fn new_stack ( & self , size : usize , zeroed : bool ) -> anyhow:: Result < Box < dyn wasmtime:: StackMemory > , anyhow:: Error > {
62+ debug_assert_eq ! ( size, ASYNC_STACK_SIZE ) ;
63+
5764 // SAFETY: `self.weak` is fully initialized whenever `new_stack` is called.
58- let weak = unsafe { self . weak . assume_init_ref ( ) } . clone ( ) ;
65+ let weak = self . weak . clone ( ) ;
5966
6067 // Either take the stack from the pool
6168 // or fall back to creating a new one.
6269 let stack = weak
6370 . upgrade ( )
6471 . and_then ( |pool| pool. pool . pop ( ) . map ( Ok ) )
65- . unwrap_or_else ( || FiberStack :: new ( size , zeroed) ) ?;
72+ . unwrap_or_else ( || FiberStack :: new ( ASYNC_STACK_SIZE , zeroed) ) ?;
6673
6774 // Ship it.
6875 let stack = ManuallyDrop :: new ( stack) ;
@@ -74,7 +81,7 @@ impl PoolingStackCreator {
7481 pub fn new ( ) -> Arc < Self > {
7582 Arc :: new_cyclic ( |weak| {
7683 let pool = ArrayQueue :: new ( 100 ) ;
77- let weak = MaybeUninit :: new ( weak. clone ( ) ) ;
84+ let weak = weak. clone ( ) ;
7885 Self { pool, weak }
7986 } )
8087 }
0 commit comments