@@ -33,8 +33,8 @@ pub struct Lua {
33
33
/// See [`Lua::scope`] for more details.
34
34
///
35
35
/// [`Lua::scope`]: struct.Lua.html#method.scope
36
- pub struct Scope < ' lua , ' scope > {
37
- lua : & ' lua Lua ,
36
+ pub struct Scope < ' scope > {
37
+ lua : & ' scope Lua ,
38
38
destructors : RefCell < Vec < Box < Fn ( * mut ffi:: lua_State ) -> Box < Any > > > > ,
39
39
// 'scope lifetime must be invariant
40
40
_scope : PhantomData < & ' scope mut & ' scope ( ) > ,
@@ -347,15 +347,15 @@ impl Lua {
347
347
/// thread while `Scope` is live, it is safe to allow !Send datatypes and functions whose
348
348
/// lifetimes only outlive the scope lifetime.
349
349
///
350
- /// To make the lifetimes work out, handles that `Lua::scope` produces have the `'lua` lifetime
351
- /// of the parent `Lua` instance . This allows the handles to scoped values to escape the
352
- /// callback, but this was possible anyway by going through Lua itself. This is safe to do, but
353
- /// not useful, because after the scope is dropped, all references to scoped values, whether in
354
- /// Lua or in rust, are invalidated. `Function` types will error when called, and `AnyUserData`
355
- /// types will be typeless.
356
- pub fn scope < ' lua , ' scope , F , R > ( & ' lua self , f : F ) -> R
350
+ /// Handles that `Lua::scope` produces have a `'lua` lifetime of the scope parameter, to prevent
351
+ /// the handles from escaping the callback . However, this is not the only way for values to
352
+ /// escape the callback, as they can be smuggled through Lua itself. This is safe to do, but
353
+ /// not very useful, because after the scope is dropped, all references to scoped values,
354
+ /// whether in Lua or in rust, are invalidated. `Function` types will error when called, and
355
+ /// `AnyUserData` types will be typeless.
356
+ pub fn scope < ' scope , ' lua : ' scope , F , R > ( & ' lua self , f : F ) -> R
357
357
where
358
- F : FnOnce ( & Scope < ' lua , ' scope > ) -> R ,
358
+ F : FnOnce ( & Scope < ' scope > ) -> R ,
359
359
{
360
360
let scope = Scope {
361
361
lua : self ,
@@ -1082,15 +1082,15 @@ impl Lua {
1082
1082
}
1083
1083
}
1084
1084
1085
- impl < ' lua , ' scope > Scope < ' lua , ' scope > {
1085
+ impl < ' scope > Scope < ' scope > {
1086
1086
/// Wraps a Rust function or closure, creating a callable Lua function handle to it.
1087
1087
///
1088
1088
/// This is a version of [`Lua::create_function`] that creates a callback which expires on scope
1089
1089
/// drop. See [`Lua::scope`] for more details.
1090
1090
///
1091
1091
/// [`Lua::create_function`]: struct.Lua.html#method.create_function
1092
1092
/// [`Lua::scope`]: struct.Lua.html#method.scope
1093
- pub fn create_function < ' callback , A , R , F > ( & self , func : F ) -> Result < Function < ' lua > >
1093
+ pub fn create_function < ' callback , ' lua , A , R , F > ( & ' lua self , func : F ) -> Result < Function < ' lua > >
1094
1094
where
1095
1095
A : FromLuaMulti < ' callback > ,
1096
1096
R : ToLuaMulti < ' callback > ,
@@ -1107,22 +1107,25 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
1107
1107
let mut destructors = self . destructors . borrow_mut ( ) ;
1108
1108
let registry_id = f. 0 . registry_id ;
1109
1109
destructors. push ( Box :: new ( move |state| {
1110
- check_stack ( state, 2 ) ;
1111
- ffi:: lua_rawgeti (
1112
- state,
1113
- ffi:: LUA_REGISTRYINDEX ,
1114
- registry_id as ffi:: lua_Integer ,
1115
- ) ;
1116
- ffi:: luaL_unref ( state, ffi:: LUA_REGISTRYINDEX , registry_id) ;
1110
+ stack_guard ( state, 0 , || {
1111
+ check_stack ( state, 2 ) ;
1117
1112
1118
- ffi:: lua_getupvalue ( state, -1 , 1 ) ;
1119
- let ud = take_userdata :: < Callback > ( state) ;
1113
+ ffi:: lua_rawgeti (
1114
+ state,
1115
+ ffi:: LUA_REGISTRYINDEX ,
1116
+ registry_id as ffi:: lua_Integer ,
1117
+ ) ;
1118
+ ffi:: luaL_unref ( state, ffi:: LUA_REGISTRYINDEX , registry_id) ;
1120
1119
1121
- ffi:: lua_pushnil ( state) ;
1122
- ffi :: lua_setupvalue ( state, - 2 , 1 ) ;
1120
+ ffi:: lua_getupvalue ( state, - 1 , 1 ) ;
1121
+ let ud = take_userdata :: < Callback > ( state) ;
1123
1122
1124
- ffi:: lua_pop ( state, 1 ) ;
1125
- Box :: new ( ud)
1123
+ ffi:: lua_pushnil ( state) ;
1124
+ ffi:: lua_setupvalue ( state, -2 , 1 ) ;
1125
+
1126
+ ffi:: lua_pop ( state, 1 ) ;
1127
+ Box :: new ( ud)
1128
+ } )
1126
1129
} ) ) ;
1127
1130
Ok ( f)
1128
1131
}
@@ -1135,7 +1138,10 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
1135
1138
///
1136
1139
/// [`Lua::create_function_mut`]: struct.Lua.html#method.create_function_mut
1137
1140
/// [`Lua::scope`]: struct.Lua.html#method.scope
1138
- pub fn create_function_mut < ' callback , A , R , F > ( & self , func : F ) -> Result < Function < ' lua > >
1141
+ pub fn create_function_mut < ' callback , ' lua , A , R , F > (
1142
+ & ' lua self ,
1143
+ func : F ,
1144
+ ) -> Result < Function < ' lua > >
1139
1145
where
1140
1146
A : FromLuaMulti < ' callback > ,
1141
1147
R : ToLuaMulti < ' callback > ,
@@ -1155,7 +1161,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
1155
1161
///
1156
1162
/// [`Lua::create_userdata`]: struct.Lua.html#method.create_userdata
1157
1163
/// [`Lua::scope`]: struct.Lua.html#method.scope
1158
- pub fn create_userdata < T > ( & self , data : T ) -> Result < AnyUserData < ' lua > >
1164
+ pub fn create_userdata < ' lua , T > ( & ' lua self , data : T ) -> Result < AnyUserData < ' lua > >
1159
1165
where
1160
1166
T : UserData ,
1161
1167
{
@@ -1165,21 +1171,23 @@ impl<'lua, 'scope> Scope<'lua, 'scope> {
1165
1171
let mut destructors = self . destructors . borrow_mut ( ) ;
1166
1172
let registry_id = u. 0 . registry_id ;
1167
1173
destructors. push ( Box :: new ( move |state| {
1168
- check_stack ( state, 1 ) ;
1169
- ffi:: lua_rawgeti (
1170
- state,
1171
- ffi:: LUA_REGISTRYINDEX ,
1172
- registry_id as ffi:: lua_Integer ,
1173
- ) ;
1174
- ffi:: luaL_unref ( state, ffi:: LUA_REGISTRYINDEX , registry_id) ;
1175
- Box :: new ( take_userdata :: < RefCell < T > > ( state) )
1174
+ stack_guard ( state, 0 , || {
1175
+ check_stack ( state, 1 ) ;
1176
+ ffi:: lua_rawgeti (
1177
+ state,
1178
+ ffi:: LUA_REGISTRYINDEX ,
1179
+ registry_id as ffi:: lua_Integer ,
1180
+ ) ;
1181
+ ffi:: luaL_unref ( state, ffi:: LUA_REGISTRYINDEX , registry_id) ;
1182
+ Box :: new ( take_userdata :: < RefCell < T > > ( state) )
1183
+ } )
1176
1184
} ) ) ;
1177
1185
Ok ( u)
1178
1186
}
1179
1187
}
1180
1188
}
1181
1189
1182
- impl < ' lua , ' scope > Drop for Scope < ' lua , ' scope > {
1190
+ impl < ' scope > Drop for Scope < ' scope > {
1183
1191
fn drop ( & mut self ) {
1184
1192
// We separate the action of invalidating the userdata in Lua and actually dropping the
1185
1193
// userdata type into two phases. This is so that, in the event a userdata drop panics, we
0 commit comments