@@ -22,7 +22,9 @@ use crate::types::{
22
22
ReentrantMutex , ReentrantMutexGuard , RegistryKey , XRc , XWeak ,
23
23
} ;
24
24
use crate :: userdata:: { AnyUserData , UserData , UserDataProxy , UserDataRegistry , UserDataStorage } ;
25
- use crate :: util:: { assert_stack, check_stack, push_string, push_table, rawset_field, StackGuard } ;
25
+ use crate :: util:: {
26
+ assert_stack, check_stack, protect_lua_closure, push_string, push_table, rawset_field, StackGuard ,
27
+ } ;
26
28
use crate :: value:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti , MultiValue , Nil , Value } ;
27
29
28
30
#[ cfg( not( feature = "luau" ) ) ]
@@ -276,6 +278,28 @@ impl Lua {
276
278
}
277
279
}
278
280
281
+ /// Calls provided function passing a raw lua state.
282
+ ///
283
+ /// The arguments will be pushed onto the stack before calling the function.
284
+ ///
285
+ /// This method ensures that the Lua instance is locked while the function is called
286
+ /// and restores Lua stack after the function returns.
287
+ pub unsafe fn with_raw_state < R : FromLuaMulti > (
288
+ & self ,
289
+ args : impl IntoLuaMulti ,
290
+ f : impl FnOnce ( * mut ffi:: lua_State ) ,
291
+ ) -> Result < R > {
292
+ let lua = self . lock ( ) ;
293
+ let state = lua. state ( ) ;
294
+ let _sg = StackGuard :: new ( state) ;
295
+ let stack_start = ffi:: lua_gettop ( state) ;
296
+ let nargs = args. push_into_stack_multi ( & lua) ?;
297
+ check_stack ( state, 3 ) ?;
298
+ protect_lua_closure :: < _ , ( ) > ( state, nargs, ffi:: LUA_MULTRET , f) ?;
299
+ let nresults = ffi:: lua_gettop ( state) - stack_start;
300
+ R :: from_stack_multi ( nresults, & lua)
301
+ }
302
+
279
303
/// FIXME: Deprecated load_from_std_lib
280
304
281
305
/// Loads the specified subset of the standard libraries into an existing Lua state.
0 commit comments