@@ -22,7 +22,9 @@ use crate::types::{
2222 ReentrantMutex , ReentrantMutexGuard , RegistryKey , XRc , XWeak ,
2323} ;
2424use 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+ } ;
2628use crate :: value:: { FromLua , FromLuaMulti , IntoLua , IntoLuaMulti , MultiValue , Nil , Value } ;
2729
2830#[ cfg( not( feature = "luau" ) ) ]
@@ -276,6 +278,28 @@ impl Lua {
276278 }
277279 }
278280
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+
279303 /// FIXME: Deprecated load_from_std_lib
280304
281305 /// Loads the specified subset of the standard libraries into an existing Lua state.
0 commit comments