@@ -73,12 +73,18 @@ pub fn maybe_grow<R, F: FnOnce() -> R>(red_zone: usize,
7373}
7474
7575#[ inline( never) ]
76- unsafe fn grow_the_stack < R , F : FnOnce ( ) -> R > ( stack_size : usize , f : F ) -> R {
77- struct Context < F : FnOnce ( ) -> R , R > {
78- thunk : Option < F > ,
79- ret : Option < R > ,
76+ fn grow_the_stack < R , F : FnOnce ( ) -> R > ( stack_size : usize , f : F ) -> R {
77+ let mut f = Some ( f) ;
78+ let mut ret = None ;
79+ unsafe {
80+ _grow_the_stack ( stack_size, & mut || {
81+ ret = Some ( f. take ( ) . unwrap ( ) ( ) ) ;
82+ } ) ;
8083 }
84+ ret. unwrap ( )
85+ }
8186
87+ unsafe fn _grow_the_stack ( stack_size : usize , mut f : & mut FnMut ( ) ) {
8288 // Align to 16-bytes (see below for why)
8389 let stack_size = ( stack_size + 15 ) / 16 * 16 ;
8490
@@ -92,12 +98,6 @@ unsafe fn grow_the_stack<R, F: FnOnce() -> R>(stack_size: usize, f: F) -> R {
9298 // Prepare stack limits for the stack switch
9399 set_stack_limit ( new_limit) ;
94100
95- // Set up the arguments and do the actual stack switch.
96- let mut cx: Context < F , R > = Context {
97- thunk : Some ( f) ,
98- ret : None ,
99- } ;
100-
101101 // Make sure the stack is 16-byte aligned which should be enough for all
102102 // platforms right now. Allocations on 64-bit are already 16-byte aligned
103103 // and our switching routine doesn't push any other data, but the routine on
@@ -109,16 +109,15 @@ unsafe fn grow_the_stack<R, F: FnOnce() -> R>(stack_size: usize, f: F) -> R {
109109 0
110110 } ;
111111 __stacker_switch_stacks ( stack. as_mut_ptr ( ) as usize + stack_size - offset,
112- doit :: < R , F > as usize as * const _ ,
113- & mut cx as * mut _ as * mut _ ) ;
112+ doit as usize as * const _ ,
113+ & mut f as * mut & mut FnMut ( ) as * mut u8 ) ;
114114
115115 // Once we've returned reset bothe stack limits and then return value same
116116 // value the closure returned.
117117 set_stack_limit ( old_limit) ;
118- return cx. ret . unwrap ( ) ;
119118
120- unsafe extern fn doit < R , F : FnOnce ( ) -> R > ( cx : & mut Context < F , R > ) {
121- cx . ret = Some ( cx . thunk . take ( ) . unwrap ( ) ( ) ) ;
119+ unsafe extern fn doit ( f : & mut & mut FnMut ( ) ) {
120+ f ( ) ;
122121 }
123122}
124123
0 commit comments