@@ -112,23 +112,23 @@ pub unsafe fn protect_lua_call<F, R>(
112
112
f : F ,
113
113
) -> Result < R >
114
114
where
115
- F : FnOnce ( * mut ffi:: lua_State ) -> R ,
115
+ F : Fn ( * mut ffi:: lua_State ) -> R ,
116
+ R : Copy ,
116
117
{
117
118
struct Params < F , R > {
118
- function : Option < F > ,
119
- result : Option < R > ,
119
+ function : * const F ,
120
+ result : R ,
120
121
nresults : c_int ,
121
122
}
122
123
123
124
unsafe extern "C" fn do_call < F , R > ( state : * mut ffi:: lua_State ) -> c_int
124
125
where
125
- F : FnOnce ( * mut ffi:: lua_State ) -> R ,
126
+ F : Fn ( * mut ffi:: lua_State ) -> R ,
126
127
{
127
128
let params = ffi:: lua_touserdata ( state, -1 ) as * mut Params < F , R > ;
128
129
ffi:: lua_pop ( state, 1 ) ;
129
130
130
- let function = ( * params) . function . take ( ) . unwrap ( ) ;
131
- ( * params) . result = Some ( function ( state) ) ;
131
+ ( * params) . result = ( * ( * params) . function ) ( state) ;
132
132
133
133
if ( * params) . nresults == ffi:: LUA_MULTRET {
134
134
ffi:: lua_gettop ( state)
@@ -144,8 +144,8 @@ where
144
144
ffi:: lua_rotate ( state, stack_start + 1 , 2 ) ;
145
145
146
146
let mut params = Params {
147
- function : Some ( f ) ,
148
- result : None ,
147
+ function : & f ,
148
+ result : mem :: uninitialized ( ) ,
149
149
nresults,
150
150
} ;
151
151
@@ -154,7 +154,9 @@ where
154
154
ffi:: lua_remove ( state, stack_start + 1 ) ;
155
155
156
156
if ret == ffi:: LUA_OK {
157
- Ok ( params. result . take ( ) . unwrap ( ) )
157
+ // LUA_OK is only returned when the do_call function has completed successfully, so
158
+ // params.result is definitely initialized.
159
+ Ok ( params. result )
158
160
} else {
159
161
Err ( pop_error ( state, ret) )
160
162
}
@@ -228,10 +230,11 @@ pub unsafe fn push_string(state: *mut ffi::lua_State, s: &str) -> Result<()> {
228
230
229
231
// Internally uses 4 stack spaces, does not call checkstack
230
232
pub unsafe fn push_userdata < T > ( state : * mut ffi:: lua_State , t : T ) -> Result < ( ) > {
231
- protect_lua_call ( state, 0 , 1 , move |state| {
232
- let ud = ffi:: lua_newuserdata ( state, mem:: size_of :: < T > ( ) ) as * mut T ;
233
- ptr:: write ( ud, t) ;
234
- } )
233
+ let ud = protect_lua_call ( state, 0 , 1 , move |state| {
234
+ ffi:: lua_newuserdata ( state, mem:: size_of :: < T > ( ) ) as * mut T
235
+ } ) ?;
236
+ ptr:: write ( ud, t) ;
237
+ Ok ( ( ) )
235
238
}
236
239
237
240
pub unsafe fn get_userdata < T > ( state : * mut ffi:: lua_State , index : c_int ) -> * mut T {
0 commit comments