@@ -73,12 +73,18 @@ pub fn maybe_grow<R, F: FnOnce() -> R>(red_zone: usize,
73
73
}
74
74
75
75
#[ 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
+ } ) ;
80
83
}
84
+ ret. unwrap ( )
85
+ }
81
86
87
+ unsafe fn _grow_the_stack ( stack_size : usize , mut f : & mut FnMut ( ) ) {
82
88
// Align to 16-bytes (see below for why)
83
89
let stack_size = ( stack_size + 15 ) / 16 * 16 ;
84
90
@@ -92,12 +98,6 @@ unsafe fn grow_the_stack<R, F: FnOnce() -> R>(stack_size: usize, f: F) -> R {
92
98
// Prepare stack limits for the stack switch
93
99
set_stack_limit ( new_limit) ;
94
100
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
-
101
101
// Make sure the stack is 16-byte aligned which should be enough for all
102
102
// platforms right now. Allocations on 64-bit are already 16-byte aligned
103
103
// 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 {
109
109
0
110
110
} ;
111
111
__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 ) ;
114
114
115
115
// Once we've returned reset bothe stack limits and then return value same
116
116
// value the closure returned.
117
117
set_stack_limit ( old_limit) ;
118
- return cx. ret . unwrap ( ) ;
119
118
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 ( ) ;
122
121
}
123
122
}
124
123
0 commit comments