mlua_codemp_patch/
state.rs

1use std::any::TypeId;
2use std::cell::RefCell;
3use std::marker::PhantomData;
4use std::ops::Deref;
5use std::os::raw::{c_int, c_void};
6use std::panic::Location;
7use std::result::Result as StdResult;
8use std::{fmt, mem, ptr};
9
10use crate::chunk::{AsChunk, Chunk};
11use crate::error::{Error, Result};
12use crate::function::Function;
13use crate::hook::Debug;
14use crate::memory::MemoryState;
15// use crate::scope::Scope;
16use crate::stdlib::StdLib;
17use crate::string::String;
18use crate::table::Table;
19use crate::thread::Thread;
20use crate::types::{
21    AppDataRef, AppDataRefMut, ArcReentrantMutexGuard, Integer, LightUserData, MaybeSend, Number,
22    ReentrantMutex, ReentrantMutexGuard, RegistryKey, XRc, XWeak,
23};
24use crate::userdata::{AnyUserData, UserData, UserDataProxy, UserDataRegistry, UserDataVariant};
25use crate::util::{assert_stack, check_stack, push_string, push_table, rawset_field, StackGuard};
26use crate::value::{FromLua, FromLuaMulti, IntoLua, IntoLuaMulti, MultiValue, Nil, Value};
27
28#[cfg(not(feature = "luau"))]
29use crate::hook::HookTriggers;
30
31#[cfg(any(feature = "luau", doc))]
32use crate::{chunk::Compiler, types::VmState};
33
34#[cfg(feature = "async")]
35use std::future::{self, Future};
36
37#[cfg(feature = "serialize")]
38use serde::Serialize;
39
40pub(crate) use extra::ExtraData;
41pub use raw::RawLua;
42use util::{callback_error_ext, StateGuard};
43
44/// Top level Lua struct which represents an instance of Lua VM.
45#[derive(Clone)]
46pub struct Lua {
47    pub(self) raw: XRc<ReentrantMutex<RawLua>>,
48    // Controls whether garbage collection should be run on drop
49    pub(self) collect_garbage: bool,
50}
51
52#[derive(Clone)]
53pub(crate) struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
54
55pub(crate) struct LuaGuard(ArcReentrantMutexGuard<RawLua>);
56
57/// Mode of the Lua garbage collector (GC).
58///
59/// In Lua 5.4 GC can work in two modes: incremental and generational.
60/// Previous Lua versions support only incremental GC.
61///
62/// More information can be found in the Lua [documentation].
63///
64/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
65#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66pub enum GCMode {
67    Incremental,
68    /// Requires `feature = "lua54"`
69    #[cfg(feature = "lua54")]
70    #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
71    Generational,
72}
73
74/// Controls Lua interpreter behavior such as Rust panics handling.
75#[derive(Clone, Debug)]
76#[non_exhaustive]
77pub struct LuaOptions {
78    /// Catch Rust panics when using [`pcall`]/[`xpcall`].
79    ///
80    /// If disabled, wraps these functions and automatically resumes panic if found.
81    /// Also in Lua 5.1 adds ability to provide arguments to [`xpcall`] similar to Lua >= 5.2.
82    ///
83    /// If enabled, keeps [`pcall`]/[`xpcall`] unmodified.
84    /// Panics are still automatically resumed if returned to the Rust side.
85    ///
86    /// Default: **true**
87    ///
88    /// [`pcall`]: https://www.lua.org/manual/5.4/manual.html#pdf-pcall
89    /// [`xpcall`]: https://www.lua.org/manual/5.4/manual.html#pdf-xpcall
90    pub catch_rust_panics: bool,
91
92    /// Max size of thread (coroutine) object pool used to execute asynchronous functions.
93    ///
94    /// It works on Lua 5.4 and Luau, where [`lua_resetthread`] function
95    /// is available and allows to reuse old coroutines after resetting their state.
96    ///
97    /// Default: **0** (disabled)
98    ///
99    /// [`lua_resetthread`]: https://www.lua.org/manual/5.4/manual.html#lua_resetthread
100    #[cfg(feature = "async")]
101    #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
102    pub thread_pool_size: usize,
103}
104
105impl Default for LuaOptions {
106    fn default() -> Self {
107        const { LuaOptions::new() }
108    }
109}
110
111impl LuaOptions {
112    /// Returns a new instance of `LuaOptions` with default parameters.
113    pub const fn new() -> Self {
114        LuaOptions {
115            catch_rust_panics: true,
116            #[cfg(feature = "async")]
117            thread_pool_size: 0,
118        }
119    }
120
121    /// Sets [`catch_rust_panics`] option.
122    ///
123    /// [`catch_rust_panics`]: #structfield.catch_rust_panics
124    #[must_use]
125    pub const fn catch_rust_panics(mut self, enabled: bool) -> Self {
126        self.catch_rust_panics = enabled;
127        self
128    }
129
130    /// Sets [`thread_pool_size`] option.
131    ///
132    /// [`thread_pool_size`]: #structfield.thread_pool_size
133    #[cfg(feature = "async")]
134    #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
135    #[must_use]
136    pub const fn thread_pool_size(mut self, size: usize) -> Self {
137        self.thread_pool_size = size;
138        self
139    }
140}
141
142impl Drop for Lua {
143    fn drop(&mut self) {
144        if self.collect_garbage {
145            let _ = self.gc_collect();
146        }
147    }
148}
149
150impl fmt::Debug for Lua {
151    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
152        write!(f, "Lua({:p})", self.lock().state())
153    }
154}
155
156impl Default for Lua {
157    #[inline]
158    fn default() -> Self {
159        Lua::new()
160    }
161}
162
163impl Lua {
164    /// Creates a new Lua state and loads the **safe** subset of the standard libraries.
165    ///
166    /// # Safety
167    /// The created Lua state would have _some_ safety guarantees and would not allow to load unsafe
168    /// standard libraries or C modules.
169    ///
170    /// See [`StdLib`] documentation for a list of unsafe modules that cannot be loaded.
171    ///
172    /// [`StdLib`]: crate::StdLib
173    pub fn new() -> Lua {
174        mlua_expect!(
175            Self::new_with(StdLib::ALL_SAFE, LuaOptions::default()),
176            "Cannot create a Lua state"
177        )
178    }
179
180    /// Creates a new Lua state and loads all the standard libraries.
181    ///
182    /// # Safety
183    /// The created Lua state would not have safety guarantees and would allow to load C modules.
184    pub unsafe fn unsafe_new() -> Lua {
185        Self::unsafe_new_with(StdLib::ALL, LuaOptions::default())
186    }
187
188    /// Creates a new Lua state and loads the specified safe subset of the standard libraries.
189    ///
190    /// Use the [`StdLib`] flags to specify the libraries you want to load.
191    ///
192    /// # Safety
193    /// The created Lua state would have _some_ safety guarantees and would not allow to load unsafe
194    /// standard libraries or C modules.
195    ///
196    /// See [`StdLib`] documentation for a list of unsafe modules that cannot be loaded.
197    ///
198    /// [`StdLib`]: crate::StdLib
199    pub fn new_with(libs: StdLib, options: LuaOptions) -> Result<Lua> {
200        #[cfg(not(feature = "luau"))]
201        if libs.contains(StdLib::DEBUG) {
202            return Err(Error::SafetyError(
203                "The unsafe `debug` module can't be loaded using safe `new_with`".to_string(),
204            ));
205        }
206        #[cfg(feature = "luajit")]
207        if libs.contains(StdLib::FFI) {
208            return Err(Error::SafetyError(
209                "The unsafe `ffi` module can't be loaded using safe `new_with`".to_string(),
210            ));
211        }
212
213        let lua = unsafe { Self::inner_new(libs, options) };
214
215        if libs.contains(StdLib::PACKAGE) {
216            mlua_expect!(lua.disable_c_modules(), "Error disabling C modules");
217        }
218        unsafe { lua.lock().set_safe() };
219
220        Ok(lua)
221    }
222
223    /// Creates a new Lua state and loads the specified subset of the standard libraries.
224    ///
225    /// Use the [`StdLib`] flags to specify the libraries you want to load.
226    ///
227    /// # Safety
228    /// The created Lua state will not have safety guarantees and allow to load C modules.
229    ///
230    /// [`StdLib`]: crate::StdLib
231    pub unsafe fn unsafe_new_with(libs: StdLib, options: LuaOptions) -> Lua {
232        // Workaround to avoid stripping a few unused Lua symbols that could be imported
233        // by C modules in unsafe mode
234        let mut _symbols: Vec<*const extern "C-unwind" fn()> =
235            vec![ffi::lua_isuserdata as _, ffi::lua_tocfunction as _];
236
237        #[cfg(not(feature = "luau"))]
238        _symbols.extend_from_slice(&[
239            ffi::lua_atpanic as _,
240            ffi::luaL_loadstring as _,
241            ffi::luaL_openlibs as _,
242        ]);
243        #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
244        {
245            _symbols.push(ffi::lua_getglobal as _);
246            _symbols.push(ffi::lua_setglobal as _);
247            _symbols.push(ffi::luaL_setfuncs as _);
248        }
249
250        Self::inner_new(libs, options)
251    }
252
253    /// Creates a new Lua state with required `libs` and `options`
254    unsafe fn inner_new(libs: StdLib, options: LuaOptions) -> Lua {
255        let lua = Lua {
256            raw: RawLua::new(libs, options),
257            collect_garbage: true,
258        };
259
260        #[cfg(feature = "luau")]
261        mlua_expect!(lua.configure_luau(), "Error configuring Luau");
262
263        lua
264    }
265
266    /// Constructs a new Lua instance from an existing raw state.
267    ///
268    /// Once called, a returned Lua state is cached in the registry and can be retrieved
269    /// by calling this function again.
270    #[allow(clippy::missing_safety_doc)]
271    #[inline]
272    pub unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> Lua {
273        Lua {
274            raw: RawLua::init_from_ptr(state, false),
275            collect_garbage: true,
276        }
277    }
278
279    /// FIXME: Deprecated load_from_std_lib
280
281    /// Loads the specified subset of the standard libraries into an existing Lua state.
282    ///
283    /// Use the [`StdLib`] flags to specify the libraries you want to load.
284    pub fn load_std_libs(&self, libs: StdLib) -> Result<()> {
285        unsafe { self.lock().load_std_libs(libs) }
286    }
287
288    /// Loads module `modname` into an existing Lua state using the specified entrypoint
289    /// function.
290    ///
291    /// Internally calls the Lua function `func` with the string `modname` as an argument,
292    /// sets the call result to `package.loaded[modname]` and returns copy of the result.
293    ///
294    /// If `package.loaded[modname]` value is not nil, returns copy of the value without
295    /// calling the function.
296    ///
297    /// If the function does not return a non-nil value then this method assigns true to
298    /// `package.loaded[modname]`.
299    ///
300    /// Behavior is similar to Lua's [`require`] function.
301    ///
302    /// [`require`]: https://www.lua.org/manual/5.4/manual.html#pdf-require
303    pub fn load_from_function<T>(&self, modname: &str, func: Function) -> Result<T>
304    where
305        T: FromLua,
306    {
307        let lua = self.lock();
308        let state = lua.state();
309        let loaded = unsafe {
310            let _sg = StackGuard::new(state);
311            check_stack(state, 2)?;
312            protect_lua!(state, 0, 1, fn(state) {
313                ffi::luaL_getsubtable(state, ffi::LUA_REGISTRYINDEX, cstr!("_LOADED"));
314            })?;
315            Table(lua.pop_ref())
316        };
317
318        let modname = unsafe { lua.create_string(modname)? };
319        let value = match loaded.raw_get(&modname)? {
320            Value::Nil => {
321                let result = match func.call(&modname)? {
322                    Value::Nil => Value::Boolean(true),
323                    res => res,
324                };
325                loaded.raw_set(modname, &result)?;
326                result
327            }
328            res => res,
329        };
330        T::from_lua(value, self)
331    }
332
333    /// Unloads module `modname`.
334    ///
335    /// Removes module from the [`package.loaded`] table which allows to load it again.
336    /// It does not support unloading binary Lua modules since they are internally cached and can be
337    /// unloaded only by closing Lua state.
338    ///
339    /// [`package.loaded`]: https://www.lua.org/manual/5.4/manual.html#pdf-package.loaded
340    pub fn unload(&self, modname: &str) -> Result<()> {
341        let lua = self.lock();
342        let state = lua.state();
343        let loaded = unsafe {
344            let _sg = StackGuard::new(state);
345            check_stack(state, 2)?;
346            protect_lua!(state, 0, 1, fn(state) {
347                ffi::luaL_getsubtable(state, ffi::LUA_REGISTRYINDEX, cstr!("_LOADED"));
348            })?;
349            Table(lua.pop_ref())
350        };
351
352        loaded.raw_set(modname, Nil)
353    }
354
355    // Executes module entrypoint function, which returns only one Value.
356    // The returned value then pushed onto the stack.
357    #[doc(hidden)]
358    #[cfg(not(tarpaulin_include))]
359    pub unsafe fn entrypoint<F, A, R>(state: *mut ffi::lua_State, func: F) -> c_int
360    where
361        F: FnOnce(&Lua, A) -> Result<R>,
362        A: FromLuaMulti,
363        R: IntoLua,
364    {
365        // Make sure that Lua is initialized
366        let mut lua = Self::init_from_ptr(state);
367        lua.collect_garbage = false;
368        // `Lua` is no longer needed and must be dropped at this point to avoid possible memory leak
369        // in case of possible longjmp (lua_error) below
370        drop(lua);
371
372        callback_error_ext(state, ptr::null_mut(), move |extra, nargs| {
373            let rawlua = (*extra).raw_lua();
374            let _guard = StateGuard::new(rawlua, state);
375            let args = A::from_stack_args(nargs, 1, None, rawlua)?;
376            func(rawlua.lua(), args)?.push_into_stack(rawlua)?;
377            Ok(1)
378        })
379    }
380
381    // A simple module entrypoint without arguments
382    #[doc(hidden)]
383    #[cfg(not(tarpaulin_include))]
384    pub unsafe fn entrypoint1<F, R>(state: *mut ffi::lua_State, func: F) -> c_int
385    where
386        F: FnOnce(&Lua) -> Result<R>,
387        R: IntoLua,
388    {
389        Self::entrypoint(state, move |lua, _: ()| func(lua))
390    }
391
392    /// Skips memory checks for some operations.
393    #[doc(hidden)]
394    #[cfg(feature = "module")]
395    pub fn skip_memory_check(&self, skip: bool) {
396        let lua = self.lock();
397        unsafe { (*lua.extra.get()).skip_memory_check = skip };
398    }
399
400    /// Enables (or disables) sandbox mode on this Lua instance.
401    ///
402    /// This method, in particular:
403    /// - Set all libraries to read-only
404    /// - Set all builtin metatables to read-only
405    /// - Set globals to read-only (and activates safeenv)
406    /// - Setup local environment table that performs writes locally and proxies reads to the global
407    ///   environment.
408    ///
409    /// # Examples
410    ///
411    /// ```
412    /// # use mlua::{Lua, Result};
413    /// # fn main() -> Result<()> {
414    /// let lua = Lua::new();
415    ///
416    /// lua.sandbox(true)?;
417    /// lua.load("var = 123").exec()?;
418    /// assert_eq!(lua.globals().get::<u32>("var")?, 123);
419    ///
420    /// // Restore the global environment (clear changes made in sandbox)
421    /// lua.sandbox(false)?;
422    /// assert_eq!(lua.globals().get::<Option<u32>>("var")?, None);
423    /// # Ok(())
424    /// # }
425    /// ```
426    ///
427    /// Requires `feature = "luau"`
428    #[cfg(any(feature = "luau", docsrs))]
429    #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
430    pub fn sandbox(&self, enabled: bool) -> Result<()> {
431        let lua = self.lock();
432        unsafe {
433            if (*lua.extra.get()).sandboxed != enabled {
434                let state = lua.main_state;
435                check_stack(state, 3)?;
436                protect_lua!(state, 0, 0, |state| {
437                    if enabled {
438                        ffi::luaL_sandbox(state, 1);
439                        ffi::luaL_sandboxthread(state);
440                    } else {
441                        // Restore original `LUA_GLOBALSINDEX`
442                        ffi::lua_xpush(lua.ref_thread(), state, ffi::LUA_GLOBALSINDEX);
443                        ffi::lua_replace(state, ffi::LUA_GLOBALSINDEX);
444                        ffi::luaL_sandbox(state, 0);
445                    }
446                })?;
447                (*lua.extra.get()).sandboxed = enabled;
448            }
449            Ok(())
450        }
451    }
452
453    /// Sets a 'hook' function that will periodically be called as Lua code executes.
454    ///
455    /// When exactly the hook function is called depends on the contents of the `triggers`
456    /// parameter, see [`HookTriggers`] for more details.
457    ///
458    /// The provided hook function can error, and this error will be propagated through the Lua code
459    /// that was executing at the time the hook was triggered. This can be used to implement a
460    /// limited form of execution limits by setting [`HookTriggers.every_nth_instruction`] and
461    /// erroring once an instruction limit has been reached.
462    ///
463    /// This method sets a hook function for the current thread of this Lua instance.
464    /// If you want to set a hook function for another thread (coroutine), use
465    /// [`Thread::set_hook()`] instead.
466    ///
467    /// Please note you cannot have more than one hook function set at a time for this Lua instance.
468    ///
469    /// # Example
470    ///
471    /// Shows each line number of code being executed by the Lua interpreter.
472    ///
473    /// ```
474    /// # use mlua::{Lua, HookTriggers, Result};
475    /// # fn main() -> Result<()> {
476    /// let lua = Lua::new();
477    /// lua.set_hook(HookTriggers::EVERY_LINE, |_lua, debug| {
478    ///     println!("line {}", debug.curr_line());
479    ///     Ok(())
480    /// });
481    ///
482    /// lua.load(r#"
483    ///     local x = 2 + 3
484    ///     local y = x * 63
485    ///     local z = string.len(x..", "..y)
486    /// "#).exec()
487    /// # }
488    /// ```
489    ///
490    /// [`HookTriggers`]: crate::HookTriggers
491    /// [`HookTriggers.every_nth_instruction`]: crate::HookTriggers::every_nth_instruction
492    #[cfg(not(feature = "luau"))]
493    #[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
494    pub fn set_hook<F>(&self, triggers: HookTriggers, callback: F)
495    where
496        F: Fn(&Lua, Debug) -> Result<()> + MaybeSend + 'static,
497    {
498        let lua = self.lock();
499        unsafe { lua.set_thread_hook(lua.state(), triggers, callback) };
500    }
501
502    /// Removes any hook previously set by [`Lua::set_hook()`] or [`Thread::set_hook()`].
503    ///
504    /// This function has no effect if a hook was not previously set.
505    #[cfg(not(feature = "luau"))]
506    #[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
507    pub fn remove_hook(&self) {
508        let lua = self.lock();
509        unsafe {
510            let state = lua.state();
511            ffi::lua_sethook(state, None, 0, 0);
512            match crate::util::get_main_state(lua.main_state) {
513                Some(main_state) if !ptr::eq(state, main_state) => {
514                    // If main_state is different from state, remove hook from it too
515                    ffi::lua_sethook(main_state, None, 0, 0);
516                }
517                _ => {}
518            };
519            (*lua.extra.get()).hook_callback = None;
520            (*lua.extra.get()).hook_thread = ptr::null_mut();
521        }
522    }
523
524    /// Sets an 'interrupt' function that will periodically be called by Luau VM.
525    ///
526    /// Any Luau code is guaranteed to call this handler "eventually"
527    /// (in practice this can happen at any function call or at any loop iteration).
528    ///
529    /// The provided interrupt function can error, and this error will be propagated through
530    /// the Luau code that was executing at the time the interrupt was triggered.
531    /// Also this can be used to implement continuous execution limits by instructing Luau VM to
532    /// yield by returning [`VmState::Yield`].
533    ///
534    /// This is similar to [`Lua::set_hook`] but in more simplified form.
535    ///
536    /// # Example
537    ///
538    /// Periodically yield Luau VM to suspend execution.
539    ///
540    /// ```
541    /// # use std::sync::{Arc, atomic::{AtomicU64, Ordering}};
542    /// # use mlua::{Lua, Result, ThreadStatus, VmState};
543    /// # fn main() -> Result<()> {
544    /// let lua = Lua::new();
545    /// let count = Arc::new(AtomicU64::new(0));
546    /// lua.set_interrupt(move |_| {
547    ///     if count.fetch_add(1, Ordering::Relaxed) % 2 == 0 {
548    ///         return Ok(VmState::Yield);
549    ///     }
550    ///     Ok(VmState::Continue)
551    /// });
552    ///
553    /// let co = lua.create_thread(
554    ///     lua.load(r#"
555    ///         local b = 0
556    ///         for _, x in ipairs({1, 2, 3}) do b += x end
557    ///     "#)
558    ///     .into_function()?,
559    /// )?;
560    /// while co.status() == ThreadStatus::Resumable {
561    ///     co.resume(())?;
562    /// }
563    /// # Ok(())
564    /// # }
565    /// ```
566    #[cfg(any(feature = "luau", docsrs))]
567    #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
568    pub fn set_interrupt<F>(&self, callback: F)
569    where
570        F: Fn(&Lua) -> Result<VmState> + MaybeSend + 'static,
571    {
572        use std::rc::Rc;
573
574        unsafe extern "C-unwind" fn interrupt_proc(state: *mut ffi::lua_State, gc: c_int) {
575            if gc >= 0 {
576                // We don't support GC interrupts since they cannot survive Lua exceptions
577                return;
578            }
579            let result = callback_error_ext(state, ptr::null_mut(), move |extra, _| {
580                let interrupt_cb = (*extra).interrupt_callback.clone();
581                let interrupt_cb = mlua_expect!(interrupt_cb, "no interrupt callback set in interrupt_proc");
582                if Rc::strong_count(&interrupt_cb) > 2 {
583                    return Ok(VmState::Continue); // Don't allow recursion
584                }
585                let _guard = StateGuard::new((*extra).raw_lua(), state);
586                interrupt_cb((*extra).lua())
587            });
588            match result {
589                VmState::Continue => {}
590                VmState::Yield => {
591                    ffi::lua_yield(state, 0);
592                }
593            }
594        }
595
596        // Set interrupt callback
597        let lua = self.lock();
598        unsafe {
599            (*lua.extra.get()).interrupt_callback = Some(Rc::new(callback));
600            (*ffi::lua_callbacks(lua.main_state)).interrupt = Some(interrupt_proc);
601        }
602    }
603
604    /// Removes any 'interrupt' previously set by `set_interrupt`.
605    ///
606    /// This function has no effect if an 'interrupt' was not previously set.
607    #[cfg(any(feature = "luau", docsrs))]
608    #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
609    pub fn remove_interrupt(&self) {
610        let lua = self.lock();
611        unsafe {
612            (*lua.extra.get()).interrupt_callback = None;
613            (*ffi::lua_callbacks(lua.main_state)).interrupt = None;
614        }
615    }
616
617    /// Sets the warning function to be used by Lua to emit warnings.
618    ///
619    /// Requires `feature = "lua54"`
620    #[cfg(feature = "lua54")]
621    #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
622    pub fn set_warning_function<F>(&self, callback: F)
623    where
624        F: Fn(&Lua, &str, bool) -> Result<()> + MaybeSend + 'static,
625    {
626        use std::ffi::CStr;
627        use std::os::raw::c_char;
628        use std::string::String as StdString;
629
630        unsafe extern "C-unwind" fn warn_proc(ud: *mut c_void, msg: *const c_char, tocont: c_int) {
631            let extra = ud as *mut ExtraData;
632            callback_error_ext((*extra).raw_lua().state(), extra, |extra, _| {
633                let cb = mlua_expect!(
634                    (*extra).warn_callback.as_ref(),
635                    "no warning callback set in warn_proc"
636                );
637                let msg = StdString::from_utf8_lossy(CStr::from_ptr(msg).to_bytes());
638                cb((*extra).lua(), &msg, tocont != 0)
639            });
640        }
641
642        let lua = self.lock();
643        let state = lua.main_state;
644        unsafe {
645            (*lua.extra.get()).warn_callback = Some(Box::new(callback));
646            ffi::lua_setwarnf(state, Some(warn_proc), lua.extra.get() as *mut c_void);
647        }
648    }
649
650    /// Removes warning function previously set by `set_warning_function`.
651    ///
652    /// This function has no effect if a warning function was not previously set.
653    ///
654    /// Requires `feature = "lua54"`
655    #[cfg(feature = "lua54")]
656    #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
657    pub fn remove_warning_function(&self) {
658        let lua = self.lock();
659        unsafe {
660            (*lua.extra.get()).warn_callback = None;
661            ffi::lua_setwarnf(lua.main_state, None, ptr::null_mut());
662        }
663    }
664
665    /// Emits a warning with the given message.
666    ///
667    /// A message in a call with `incomplete` set to `true` should be continued in
668    /// another call to this function.
669    ///
670    /// Requires `feature = "lua54"`
671    #[cfg(feature = "lua54")]
672    #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
673    pub fn warning(&self, msg: impl AsRef<str>, incomplete: bool) {
674        let msg = msg.as_ref();
675        let mut bytes = vec![0; msg.len() + 1];
676        bytes[..msg.len()].copy_from_slice(msg.as_bytes());
677        let real_len = bytes.iter().position(|&c| c == 0).unwrap();
678        bytes.truncate(real_len);
679        let lua = self.lock();
680        unsafe {
681            ffi::lua_warning(lua.state(), bytes.as_ptr() as *const _, incomplete as c_int);
682        }
683    }
684
685    /// Gets information about the interpreter runtime stack.
686    ///
687    /// This function returns [`Debug`] structure that can be used to get information about the
688    /// function executing at a given level. Level `0` is the current running function, whereas
689    /// level `n+1` is the function that has called level `n` (except for tail calls, which do
690    /// not count in the stack).
691    ///
692    /// [`Debug`]: crate::hook::Debug
693    pub fn inspect_stack(&self, level: usize) -> Option<Debug> {
694        let lua = self.lock();
695        unsafe {
696            let mut ar: ffi::lua_Debug = mem::zeroed();
697            let level = level as c_int;
698            #[cfg(not(feature = "luau"))]
699            if ffi::lua_getstack(lua.state(), level, &mut ar) == 0 {
700                return None;
701            }
702            #[cfg(feature = "luau")]
703            if ffi::lua_getinfo(lua.state(), level, cstr!(""), &mut ar) == 0 {
704                return None;
705            }
706            Some(Debug::new_owned(lua, level, ar))
707        }
708    }
709
710    /// Returns the amount of memory (in bytes) currently used inside this Lua state.
711    pub fn used_memory(&self) -> usize {
712        let lua = self.lock();
713        unsafe {
714            match MemoryState::get(lua.main_state) {
715                mem_state if !mem_state.is_null() => (*mem_state).used_memory(),
716                _ => {
717                    // Get data from the Lua GC
718                    let used_kbytes = ffi::lua_gc(lua.main_state, ffi::LUA_GCCOUNT, 0);
719                    let used_kbytes_rem = ffi::lua_gc(lua.main_state, ffi::LUA_GCCOUNTB, 0);
720                    (used_kbytes as usize) * 1024 + (used_kbytes_rem as usize)
721                }
722            }
723        }
724    }
725
726    /// Sets a memory limit (in bytes) on this Lua state.
727    ///
728    /// Once an allocation occurs that would pass this memory limit,
729    /// a `Error::MemoryError` is generated instead.
730    /// Returns previous limit (zero means no limit).
731    ///
732    /// Does not work in module mode where Lua state is managed externally.
733    pub fn set_memory_limit(&self, limit: usize) -> Result<usize> {
734        let lua = self.lock();
735        unsafe {
736            match MemoryState::get(lua.main_state) {
737                mem_state if !mem_state.is_null() => Ok((*mem_state).set_memory_limit(limit)),
738                _ => Err(Error::MemoryLimitNotAvailable),
739            }
740        }
741    }
742
743    /// Returns true if the garbage collector is currently running automatically.
744    ///
745    /// Requires `feature = "lua54/lua53/lua52/luau"`
746    #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
747    pub fn gc_is_running(&self) -> bool {
748        let lua = self.lock();
749        unsafe { ffi::lua_gc(lua.main_state, ffi::LUA_GCISRUNNING, 0) != 0 }
750    }
751
752    /// Stop the Lua GC from running
753    pub fn gc_stop(&self) {
754        let lua = self.lock();
755        unsafe { ffi::lua_gc(lua.main_state, ffi::LUA_GCSTOP, 0) };
756    }
757
758    /// Restarts the Lua GC if it is not running
759    pub fn gc_restart(&self) {
760        let lua = self.lock();
761        unsafe { ffi::lua_gc(lua.main_state, ffi::LUA_GCRESTART, 0) };
762    }
763
764    /// Perform a full garbage-collection cycle.
765    ///
766    /// It may be necessary to call this function twice to collect all currently unreachable
767    /// objects. Once to finish the current gc cycle, and once to start and finish the next cycle.
768    pub fn gc_collect(&self) -> Result<()> {
769        let lua = self.lock();
770        unsafe {
771            check_stack(lua.main_state, 2)?;
772            protect_lua!(lua.main_state, 0, 0, fn(state) ffi::lua_gc(state, ffi::LUA_GCCOLLECT, 0))
773        }
774    }
775
776    /// Steps the garbage collector one indivisible step.
777    ///
778    /// Returns true if this has finished a collection cycle.
779    pub fn gc_step(&self) -> Result<bool> {
780        self.gc_step_kbytes(0)
781    }
782
783    /// Steps the garbage collector as though memory had been allocated.
784    ///
785    /// if `kbytes` is 0, then this is the same as calling `gc_step`. Returns true if this step has
786    /// finished a collection cycle.
787    pub fn gc_step_kbytes(&self, kbytes: c_int) -> Result<bool> {
788        let lua = self.lock();
789        unsafe {
790            check_stack(lua.main_state, 3)?;
791            protect_lua!(lua.main_state, 0, 0, |state| {
792                ffi::lua_gc(state, ffi::LUA_GCSTEP, kbytes) != 0
793            })
794        }
795    }
796
797    /// Sets the 'pause' value of the collector.
798    ///
799    /// Returns the previous value of 'pause'. More information can be found in the Lua
800    /// [documentation].
801    ///
802    /// For Luau this parameter sets GC goal
803    ///
804    /// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
805    pub fn gc_set_pause(&self, pause: c_int) -> c_int {
806        let lua = self.lock();
807        unsafe {
808            #[cfg(not(feature = "luau"))]
809            return ffi::lua_gc(lua.main_state, ffi::LUA_GCSETPAUSE, pause);
810            #[cfg(feature = "luau")]
811            return ffi::lua_gc(lua.main_state, ffi::LUA_GCSETGOAL, pause);
812        }
813    }
814
815    /// Sets the 'step multiplier' value of the collector.
816    ///
817    /// Returns the previous value of the 'step multiplier'. More information can be found in the
818    /// Lua [documentation].
819    ///
820    /// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
821    pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
822        let lua = self.lock();
823        unsafe { ffi::lua_gc(lua.main_state, ffi::LUA_GCSETSTEPMUL, step_multiplier) }
824    }
825
826    /// Changes the collector to incremental mode with the given parameters.
827    ///
828    /// Returns the previous mode (always `GCMode::Incremental` in Lua < 5.4).
829    /// More information can be found in the Lua [documentation].
830    ///
831    /// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5.1
832    pub fn gc_inc(&self, pause: c_int, step_multiplier: c_int, step_size: c_int) -> GCMode {
833        let lua = self.lock();
834        let state = lua.main_state;
835
836        #[cfg(any(
837            feature = "lua53",
838            feature = "lua52",
839            feature = "lua51",
840            feature = "luajit",
841            feature = "luau"
842        ))]
843        unsafe {
844            if pause > 0 {
845                #[cfg(not(feature = "luau"))]
846                ffi::lua_gc(state, ffi::LUA_GCSETPAUSE, pause);
847                #[cfg(feature = "luau")]
848                ffi::lua_gc(state, ffi::LUA_GCSETGOAL, pause);
849            }
850
851            if step_multiplier > 0 {
852                ffi::lua_gc(state, ffi::LUA_GCSETSTEPMUL, step_multiplier);
853            }
854
855            #[cfg(feature = "luau")]
856            if step_size > 0 {
857                ffi::lua_gc(state, ffi::LUA_GCSETSTEPSIZE, step_size);
858            }
859            #[cfg(not(feature = "luau"))]
860            let _ = step_size; // Ignored
861
862            GCMode::Incremental
863        }
864
865        #[cfg(feature = "lua54")]
866        let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCINC, pause, step_multiplier, step_size) };
867        #[cfg(feature = "lua54")]
868        match prev_mode {
869            ffi::LUA_GCINC => GCMode::Incremental,
870            ffi::LUA_GCGEN => GCMode::Generational,
871            _ => unreachable!(),
872        }
873    }
874
875    /// Changes the collector to generational mode with the given parameters.
876    ///
877    /// Returns the previous mode. More information about the generational GC
878    /// can be found in the Lua 5.4 [documentation][lua_doc].
879    ///
880    /// Requires `feature = "lua54"`
881    ///
882    /// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5.2
883    #[cfg(feature = "lua54")]
884    #[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
885    pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
886        let lua = self.lock();
887        let state = lua.main_state;
888        let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCGEN, minor_multiplier, major_multiplier) };
889        match prev_mode {
890            ffi::LUA_GCGEN => GCMode::Generational,
891            ffi::LUA_GCINC => GCMode::Incremental,
892            _ => unreachable!(),
893        }
894    }
895
896    /// Sets a default Luau compiler (with custom options).
897    ///
898    /// This compiler will be used by default to load all Lua chunks
899    /// including via `require` function.
900    ///
901    /// See [`Compiler`] for details and possible options.
902    ///
903    /// Requires `feature = "luau"`
904    #[cfg(any(feature = "luau", doc))]
905    #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
906    pub fn set_compiler(&self, compiler: Compiler) {
907        let lua = self.lock();
908        unsafe { (*lua.extra.get()).compiler = Some(compiler) };
909    }
910
911    /// Toggles JIT compilation mode for new chunks of code.
912    ///
913    /// By default JIT is enabled. Changing this option does not have any effect on
914    /// already loaded functions.
915    #[cfg(any(feature = "luau-jit", doc))]
916    #[cfg_attr(docsrs, doc(cfg(feature = "luau-jit")))]
917    pub fn enable_jit(&self, enable: bool) {
918        let lua = self.lock();
919        unsafe { (*lua.extra.get()).enable_jit = enable };
920    }
921
922    /// Sets Luau feature flag (global setting).
923    ///
924    /// See https://github.com/luau-lang/luau/blob/master/CONTRIBUTING.md#feature-flags for details.
925    #[cfg(feature = "luau")]
926    #[doc(hidden)]
927    #[allow(clippy::result_unit_err)]
928    pub fn set_fflag(name: &str, enabled: bool) -> StdResult<(), ()> {
929        if let Ok(name) = std::ffi::CString::new(name) {
930            if unsafe { ffi::luau_setfflag(name.as_ptr(), enabled as c_int) != 0 } {
931                return Ok(());
932            }
933        }
934        Err(())
935    }
936
937    /// Returns Lua source code as a `Chunk` builder type.
938    ///
939    /// In order to actually compile or run the resulting code, you must call [`Chunk::exec`] or
940    /// similar on the returned builder. Code is not even parsed until one of these methods is
941    /// called.
942    ///
943    /// [`Chunk::exec`]: crate::Chunk::exec
944    #[track_caller]
945    pub fn load<'a>(&self, chunk: impl AsChunk<'a>) -> Chunk<'a> {
946        let caller = Location::caller();
947        Chunk {
948            lua: self.weak(),
949            name: chunk.name().unwrap_or_else(|| caller.to_string()),
950            env: chunk.environment(self),
951            mode: chunk.mode(),
952            source: chunk.source(),
953            #[cfg(feature = "luau")]
954            compiler: unsafe { (*self.lock().extra.get()).compiler.clone() },
955        }
956    }
957
958    /// Create and return an interned Lua string. Lua strings can be arbitrary `[u8]` data including
959    /// embedded nulls, so in addition to `&str` and `&String`, you can also pass plain `&[u8]`
960    /// here.
961    #[inline]
962    pub fn create_string(&self, s: impl AsRef<[u8]>) -> Result<String> {
963        unsafe { self.lock().create_string(s) }
964    }
965
966    /// Create and return a Luau [buffer] object from a byte slice of data.
967    ///
968    /// Requires `feature = "luau"`
969    ///
970    /// [buffer]: https://luau-lang.org/library#buffer-library
971    #[cfg(feature = "luau")]
972    pub fn create_buffer(&self, buf: impl AsRef<[u8]>) -> Result<AnyUserData> {
973        use crate::types::SubtypeId;
974
975        let lua = self.lock();
976        let state = lua.state();
977        unsafe {
978            if lua.unlikely_memory_error() {
979                crate::util::push_buffer(lua.ref_thread(), buf.as_ref(), false)?;
980                return Ok(AnyUserData(lua.pop_ref_thread(), SubtypeId::Buffer));
981            }
982
983            let _sg = StackGuard::new(state);
984            check_stack(state, 4)?;
985            crate::util::push_buffer(state, buf.as_ref(), true)?;
986            Ok(AnyUserData(lua.pop_ref(), SubtypeId::Buffer))
987        }
988    }
989
990    /// Creates and returns a new empty table.
991    pub fn create_table(&self) -> Result<Table> {
992        self.create_table_with_capacity(0, 0)
993    }
994
995    /// Creates and returns a new empty table, with the specified capacity.
996    /// `narr` is a hint for how many elements the table will have as a sequence;
997    /// `nrec` is a hint for how many other elements the table will have.
998    /// Lua may use these hints to preallocate memory for the new table.
999    pub fn create_table_with_capacity(&self, narr: usize, nrec: usize) -> Result<Table> {
1000        unsafe { self.lock().create_table_with_capacity(narr, nrec) }
1001    }
1002
1003    /// Creates a table and fills it with values from an iterator.
1004    pub fn create_table_from<K, V, I>(&self, iter: I) -> Result<Table>
1005    where
1006        K: IntoLua,
1007        V: IntoLua,
1008        I: IntoIterator<Item = (K, V)>,
1009    {
1010        let lua = self.lock();
1011        let state = lua.state();
1012        unsafe {
1013            let _sg = StackGuard::new(state);
1014            check_stack(state, 6)?;
1015
1016            let iter = iter.into_iter();
1017            let lower_bound = iter.size_hint().0;
1018            let protect = !lua.unlikely_memory_error();
1019            push_table(state, 0, lower_bound, protect)?;
1020            for (k, v) in iter {
1021                lua.push(k)?;
1022                lua.push(v)?;
1023                if protect {
1024                    protect_lua!(state, 3, 1, fn(state) ffi::lua_rawset(state, -3))?;
1025                } else {
1026                    ffi::lua_rawset(state, -3);
1027                }
1028            }
1029
1030            Ok(Table(lua.pop_ref()))
1031        }
1032    }
1033
1034    /// Creates a table from an iterator of values, using `1..` as the keys.
1035    pub fn create_sequence_from<T, I>(&self, iter: I) -> Result<Table>
1036    where
1037        T: IntoLua,
1038        I: IntoIterator<Item = T>,
1039    {
1040        unsafe { self.lock().create_sequence_from(iter) }
1041    }
1042
1043    /// Wraps a Rust function or closure, creating a callable Lua function handle to it.
1044    ///
1045    /// The function's return value is always a `Result`: If the function returns `Err`, the error
1046    /// is raised as a Lua error, which can be caught using `(x)pcall` or bubble up to the Rust code
1047    /// that invoked the Lua code. This allows using the `?` operator to propagate errors through
1048    /// intermediate Lua code.
1049    ///
1050    /// If the function returns `Ok`, the contained value will be converted to one or more Lua
1051    /// values. For details on Rust-to-Lua conversions, refer to the [`IntoLua`] and
1052    /// [`IntoLuaMulti`] traits.
1053    ///
1054    /// # Examples
1055    ///
1056    /// Create a function which prints its argument:
1057    ///
1058    /// ```
1059    /// # use mlua::{Lua, Result};
1060    /// # fn main() -> Result<()> {
1061    /// # let lua = Lua::new();
1062    /// let greet = lua.create_function(|_, name: String| {
1063    ///     println!("Hello, {}!", name);
1064    ///     Ok(())
1065    /// });
1066    /// # let _ = greet;    // used
1067    /// # Ok(())
1068    /// # }
1069    /// ```
1070    ///
1071    /// Use tuples to accept multiple arguments:
1072    ///
1073    /// ```
1074    /// # use mlua::{Lua, Result};
1075    /// # fn main() -> Result<()> {
1076    /// # let lua = Lua::new();
1077    /// let print_person = lua.create_function(|_, (name, age): (String, u8)| {
1078    ///     println!("{} is {} years old!", name, age);
1079    ///     Ok(())
1080    /// });
1081    /// # let _ = print_person;    // used
1082    /// # Ok(())
1083    /// # }
1084    /// ```
1085    ///
1086    /// [`IntoLua`]: crate::IntoLua
1087    /// [`IntoLuaMulti`]: crate::IntoLuaMulti
1088    pub fn create_function<F, A, R>(&self, func: F) -> Result<Function>
1089    where
1090        F: Fn(&Lua, A) -> Result<R> + MaybeSend + 'static,
1091        A: FromLuaMulti,
1092        R: IntoLuaMulti,
1093    {
1094        (self.lock()).create_callback(Box::new(move |rawlua, nargs| unsafe {
1095            let args = A::from_stack_args(nargs, 1, None, rawlua)?;
1096            func(rawlua.lua(), args)?.push_into_stack_multi(rawlua)
1097        }))
1098    }
1099
1100    /// Wraps a Rust mutable closure, creating a callable Lua function handle to it.
1101    ///
1102    /// This is a version of [`create_function`] that accepts a FnMut argument. Refer to
1103    /// [`create_function`] for more information about the implementation.
1104    ///
1105    /// [`create_function`]: #method.create_function
1106    pub fn create_function_mut<F, A, R>(&self, func: F) -> Result<Function>
1107    where
1108        F: FnMut(&Lua, A) -> Result<R> + MaybeSend + 'static,
1109        A: FromLuaMulti,
1110        R: IntoLuaMulti,
1111    {
1112        let func = RefCell::new(func);
1113        self.create_function(move |lua, args| {
1114            (*func.try_borrow_mut().map_err(|_| Error::RecursiveMutCallback)?)(lua, args)
1115        })
1116    }
1117
1118    /// Wraps a C function, creating a callable Lua function handle to it.
1119    ///
1120    /// # Safety
1121    /// This function is unsafe because provides a way to execute unsafe C function.
1122    pub unsafe fn create_c_function(&self, func: ffi::lua_CFunction) -> Result<Function> {
1123        let lua = self.lock();
1124        ffi::lua_pushcfunction(lua.ref_thread(), func);
1125        Ok(Function(lua.pop_ref_thread()))
1126    }
1127
1128    /// Wraps a Rust async function or closure, creating a callable Lua function handle to it.
1129    ///
1130    /// While executing the function Rust will poll the Future and if the result is not ready,
1131    /// call `yield()` passing internal representation of a `Poll::Pending` value.
1132    ///
1133    /// The function must be called inside Lua coroutine ([`Thread`]) to be able to suspend its
1134    /// execution. An executor should be used to poll [`AsyncThread`] and mlua will take a
1135    /// provided Waker in that case. Otherwise noop waker will be used if try to call the
1136    /// function outside of Rust executors.
1137    ///
1138    /// The family of `call_async()` functions takes care about creating [`Thread`].
1139    ///
1140    /// Requires `feature = "async"`
1141    ///
1142    /// # Examples
1143    ///
1144    /// Non blocking sleep:
1145    ///
1146    /// ```
1147    /// use std::time::Duration;
1148    /// use mlua::{Lua, Result};
1149    ///
1150    /// async fn sleep(_lua: Lua, n: u64) -> Result<&'static str> {
1151    ///     tokio::time::sleep(Duration::from_millis(n)).await;
1152    ///     Ok("done")
1153    /// }
1154    ///
1155    /// #[tokio::main]
1156    /// async fn main() -> Result<()> {
1157    ///     let lua = Lua::new();
1158    ///     lua.globals().set("sleep", lua.create_async_function(sleep)?)?;
1159    ///     let res: String = lua.load("return sleep(...)").call_async(100).await?; // Sleep 100ms
1160    ///     assert_eq!(res, "done");
1161    ///     Ok(())
1162    /// }
1163    /// ```
1164    ///
1165    /// [`Thread`]: crate::Thread
1166    /// [`AsyncThread`]: crate::AsyncThread
1167    #[cfg(feature = "async")]
1168    #[cfg_attr(docsrs, doc(cfg(feature = "async")))]
1169    pub fn create_async_function<F, A, FR, R>(&self, func: F) -> Result<Function>
1170    where
1171        F: Fn(Lua, A) -> FR + MaybeSend + 'static,
1172        A: FromLuaMulti,
1173        FR: Future<Output = Result<R>> + MaybeSend + 'static,
1174        R: IntoLuaMulti,
1175    {
1176        // In future we should switch to async closures when they are stable to capture `&Lua`
1177        // See https://rust-lang.github.io/rfcs/3668-async-closures.html
1178        (self.lock()).create_async_callback(Box::new(move |rawlua, nargs| unsafe {
1179            let args = match A::from_stack_args(nargs, 1, None, rawlua) {
1180                Ok(args) => args,
1181                Err(e) => return Box::pin(future::ready(Err(e))),
1182            };
1183            let lua = rawlua.lua();
1184            let fut = func(lua.clone(), args);
1185            Box::pin(async move { fut.await?.push_into_stack_multi(lua.raw_lua()) })
1186        }))
1187    }
1188
1189    /// Wraps a Lua function into a new thread (or coroutine).
1190    ///
1191    /// Equivalent to `coroutine.create`.
1192    pub fn create_thread(&self, func: Function) -> Result<Thread> {
1193        unsafe { self.lock().create_thread(&func) }
1194    }
1195
1196    /// Creates a Lua userdata object from a custom userdata type.
1197    ///
1198    /// All userdata instances of the same type `T` shares the same metatable.
1199    #[inline]
1200    pub fn create_userdata<T>(&self, data: T) -> Result<AnyUserData>
1201    where
1202        T: UserData + MaybeSend + 'static,
1203    {
1204        unsafe { self.lock().make_userdata(UserDataVariant::new(data)) }
1205    }
1206
1207    /// Creates a Lua userdata object from a custom serializable userdata type.
1208    ///
1209    /// Requires `feature = "serialize"`
1210    #[cfg(feature = "serialize")]
1211    #[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
1212    #[inline]
1213    pub fn create_ser_userdata<T>(&self, data: T) -> Result<AnyUserData>
1214    where
1215        T: UserData + Serialize + MaybeSend + 'static,
1216    {
1217        unsafe { self.lock().make_userdata(UserDataVariant::new_ser(data)) }
1218    }
1219
1220    /// Creates a Lua userdata object from a custom Rust type.
1221    ///
1222    /// You can register the type using [`Lua::register_userdata_type()`] to add fields or methods
1223    /// _before_ calling this method.
1224    /// Otherwise, the userdata object will have an empty metatable.
1225    ///
1226    /// All userdata instances of the same type `T` shares the same metatable.
1227    #[inline]
1228    pub fn create_any_userdata<T>(&self, data: T) -> Result<AnyUserData>
1229    where
1230        T: MaybeSend + 'static,
1231    {
1232        unsafe { self.lock().make_any_userdata(UserDataVariant::new(data)) }
1233    }
1234
1235    /// Creates a Lua userdata object from a custom serializable Rust type.
1236    ///
1237    /// See [`Lua::create_any_userdata()`] for more details.
1238    ///
1239    /// Requires `feature = "serialize"`
1240    #[cfg(feature = "serialize")]
1241    #[cfg_attr(docsrs, doc(cfg(feature = "serialize")))]
1242    #[inline]
1243    pub fn create_ser_any_userdata<T>(&self, data: T) -> Result<AnyUserData>
1244    where
1245        T: Serialize + MaybeSend + 'static,
1246    {
1247        unsafe { (self.lock()).make_any_userdata(UserDataVariant::new_ser(data)) }
1248    }
1249
1250    /// Registers a custom Rust type in Lua to use in userdata objects.
1251    ///
1252    /// This methods provides a way to add fields or methods to userdata objects of a type `T`.
1253    pub fn register_userdata_type<T: 'static>(&self, f: impl FnOnce(&mut UserDataRegistry<T>)) -> Result<()> {
1254        let mut registry = const { UserDataRegistry::new() };
1255        f(&mut registry);
1256
1257        let lua = self.lock();
1258        unsafe {
1259            // Deregister the type if it already registered
1260            let type_id = TypeId::of::<T>();
1261            if let Some(&table_id) = (*lua.extra.get()).registered_userdata.get(&type_id) {
1262                ffi::luaL_unref(lua.state(), ffi::LUA_REGISTRYINDEX, table_id);
1263            }
1264
1265            // Register the type
1266            lua.register_userdata_metatable(registry)?;
1267        }
1268        Ok(())
1269    }
1270
1271    /// Create a Lua userdata "proxy" object from a custom userdata type.
1272    ///
1273    /// Proxy object is an empty userdata object that has `T` metatable attached.
1274    /// The main purpose of this object is to provide access to static fields and functions
1275    /// without creating an instance of type `T`.
1276    ///
1277    /// You can get or set uservalues on this object but you cannot borrow any Rust type.
1278    ///
1279    /// # Examples
1280    ///
1281    /// ```
1282    /// # use mlua::{Lua, Result, UserData, UserDataFields, UserDataMethods};
1283    /// # fn main() -> Result<()> {
1284    /// # let lua = Lua::new();
1285    /// struct MyUserData(i32);
1286    ///
1287    /// impl UserData for MyUserData {
1288    ///     fn add_fields<F: UserDataFields<Self>>(fields: &mut F) {
1289    ///         fields.add_field_method_get("val", |_, this| Ok(this.0));
1290    ///     }
1291    ///
1292    ///     fn add_methods<M: UserDataMethods<Self>>(methods: &mut M) {
1293    ///         methods.add_function("new", |_, value: i32| Ok(MyUserData(value)));
1294    ///     }
1295    /// }
1296    ///
1297    /// lua.globals().set("MyUserData", lua.create_proxy::<MyUserData>()?)?;
1298    ///
1299    /// lua.load("assert(MyUserData.new(321).val == 321)").exec()?;
1300    /// # Ok(())
1301    /// # }
1302    /// ```
1303    #[inline]
1304    pub fn create_proxy<T>(&self) -> Result<AnyUserData>
1305    where
1306        T: UserData + 'static,
1307    {
1308        let ud = UserDataProxy::<T>(PhantomData);
1309        unsafe { self.lock().make_userdata(UserDataVariant::new(ud)) }
1310    }
1311
1312    /// Sets the metatable for a Luau builtin vector type.
1313    #[cfg(any(feature = "luau", doc))]
1314    #[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
1315    pub fn set_vector_metatable(&self, metatable: Option<Table>) {
1316        let lua = self.lock();
1317        let state = lua.state();
1318        unsafe {
1319            let _sg = StackGuard::new(state);
1320            assert_stack(state, 2);
1321
1322            #[cfg(not(feature = "luau-vector4"))]
1323            ffi::lua_pushvector(state, 0., 0., 0.);
1324            #[cfg(feature = "luau-vector4")]
1325            ffi::lua_pushvector(state, 0., 0., 0., 0.);
1326            match metatable {
1327                Some(metatable) => lua.push_ref(&metatable.0),
1328                None => ffi::lua_pushnil(state),
1329            };
1330            ffi::lua_setmetatable(state, -2);
1331        }
1332    }
1333
1334    /// Returns a handle to the global environment.
1335    pub fn globals(&self) -> Table {
1336        let lua = self.lock();
1337        let state = lua.state();
1338        unsafe {
1339            let _sg = StackGuard::new(state);
1340            assert_stack(state, 1);
1341            #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
1342            ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
1343            #[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
1344            ffi::lua_pushvalue(state, ffi::LUA_GLOBALSINDEX);
1345            Table(lua.pop_ref())
1346        }
1347    }
1348
1349    /// Returns a handle to the active `Thread`. For calls to `Lua` this will be the main Lua
1350    /// thread, for parameters given to a callback, this will be whatever Lua thread called the
1351    /// callback.
1352    pub fn current_thread(&self) -> Thread {
1353        let lua = self.lock();
1354        let state = lua.state();
1355        unsafe {
1356            let _sg = StackGuard::new(state);
1357            assert_stack(state, 1);
1358            ffi::lua_pushthread(state);
1359            Thread(lua.pop_ref(), state)
1360        }
1361    }
1362
1363    /// Calls the given function with a `Scope` parameter, giving the function the ability to create
1364    /// userdata and callbacks from rust types that are !Send or non-'static.
1365    ///
1366    /// The lifetime of any function or userdata created through `Scope` lasts only until the
1367    /// completion of this method call, on completion all such created values are automatically
1368    /// dropped and Lua references to them are invalidated. If a script accesses a value created
1369    /// through `Scope` outside of this method, a Lua error will result. Since we can ensure the
1370    /// lifetime of values created through `Scope`, and we know that `Lua` cannot be sent to another
1371    /// thread while `Scope` is live, it is safe to allow !Send datatypes and whose lifetimes only
1372    /// outlive the scope lifetime.
1373    ///
1374    /// Inside the scope callback, all handles created through Scope will share the same unique 'lua
1375    /// lifetime of the parent `Lua`. This allows scoped and non-scoped values to be mixed in
1376    /// API calls, which is very useful (e.g. passing a scoped userdata to a non-scoped function).
1377    /// However, this also enables handles to scoped values to be trivially leaked from the given
1378    /// callback. This is not dangerous, though!  After the callback returns, all scoped values are
1379    /// invalidated, which means that though references may exist, the Rust types backing them have
1380    /// dropped. `Function` types will error when called, and `AnyUserData` will be typeless. It
1381    /// would be impossible to prevent handles to scoped values from escaping anyway, since you
1382    /// would always be able to smuggle them through Lua state.
1383    // pub fn scope<'lua, 'scope, R>(
1384    //     &'lua self,
1385    //     f: impl FnOnce(&Scope<'lua, 'scope>) -> Result<R>,
1386    // ) -> Result<R>
1387    // where
1388    //     'lua: 'scope,
1389    // {
1390    //     f(&Scope::new(self))
1391    // }
1392
1393    /// Attempts to coerce a Lua value into a String in a manner consistent with Lua's internal
1394    /// behavior.
1395    ///
1396    /// To succeed, the value must be a string (in which case this is a no-op), an integer, or a
1397    /// number.
1398    pub fn coerce_string(&self, v: Value) -> Result<Option<String>> {
1399        Ok(match v {
1400            Value::String(s) => Some(s),
1401            v => unsafe {
1402                let lua = self.lock();
1403                let state = lua.state();
1404                let _sg = StackGuard::new(state);
1405                check_stack(state, 4)?;
1406
1407                lua.push_value(&v)?;
1408                let res = if lua.unlikely_memory_error() {
1409                    ffi::lua_tolstring(state, -1, ptr::null_mut())
1410                } else {
1411                    protect_lua!(state, 1, 1, |state| {
1412                        ffi::lua_tolstring(state, -1, ptr::null_mut())
1413                    })?
1414                };
1415                if !res.is_null() {
1416                    Some(String(lua.pop_ref()))
1417                } else {
1418                    None
1419                }
1420            },
1421        })
1422    }
1423
1424    /// Attempts to coerce a Lua value into an integer in a manner consistent with Lua's internal
1425    /// behavior.
1426    ///
1427    /// To succeed, the value must be an integer, a floating point number that has an exact
1428    /// representation as an integer, or a string that can be converted to an integer. Refer to the
1429    /// Lua manual for details.
1430    pub fn coerce_integer(&self, v: Value) -> Result<Option<Integer>> {
1431        Ok(match v {
1432            Value::Integer(i) => Some(i),
1433            v => unsafe {
1434                let lua = self.lock();
1435                let state = lua.state();
1436                let _sg = StackGuard::new(state);
1437                check_stack(state, 2)?;
1438
1439                lua.push_value(&v)?;
1440                let mut isint = 0;
1441                let i = ffi::lua_tointegerx(state, -1, &mut isint);
1442                if isint == 0 {
1443                    None
1444                } else {
1445                    Some(i)
1446                }
1447            },
1448        })
1449    }
1450
1451    /// Attempts to coerce a Lua value into a Number in a manner consistent with Lua's internal
1452    /// behavior.
1453    ///
1454    /// To succeed, the value must be a number or a string that can be converted to a number. Refer
1455    /// to the Lua manual for details.
1456    pub fn coerce_number(&self, v: Value) -> Result<Option<Number>> {
1457        Ok(match v {
1458            Value::Number(n) => Some(n),
1459            v => unsafe {
1460                let lua = self.lock();
1461                let state = lua.state();
1462                let _sg = StackGuard::new(state);
1463                check_stack(state, 2)?;
1464
1465                lua.push_value(&v)?;
1466                let mut isnum = 0;
1467                let n = ffi::lua_tonumberx(state, -1, &mut isnum);
1468                if isnum == 0 {
1469                    None
1470                } else {
1471                    Some(n)
1472                }
1473            },
1474        })
1475    }
1476
1477    /// Converts a value that implements `IntoLua` into a `Value` instance.
1478    #[inline]
1479    pub fn pack(&self, t: impl IntoLua) -> Result<Value> {
1480        t.into_lua(self)
1481    }
1482
1483    /// Converts a `Value` instance into a value that implements `FromLua`.
1484    #[inline]
1485    pub fn unpack<T: FromLua>(&self, value: Value) -> Result<T> {
1486        T::from_lua(value, self)
1487    }
1488
1489    /// Converts a value that implements `IntoLuaMulti` into a `MultiValue` instance.
1490    #[inline]
1491    pub fn pack_multi(&self, t: impl IntoLuaMulti) -> Result<MultiValue> {
1492        t.into_lua_multi(self)
1493    }
1494
1495    /// Converts a `MultiValue` instance into a value that implements `FromLuaMulti`.
1496    #[inline]
1497    pub fn unpack_multi<T: FromLuaMulti>(&self, value: MultiValue) -> Result<T> {
1498        T::from_lua_multi(value, self)
1499    }
1500
1501    /// Set a value in the Lua registry based on a string name.
1502    ///
1503    /// This value will be available to rust from all `Lua` instances which share the same main
1504    /// state.
1505    pub fn set_named_registry_value(&self, name: &str, t: impl IntoLua) -> Result<()> {
1506        let lua = self.lock();
1507        let state = lua.state();
1508        unsafe {
1509            let _sg = StackGuard::new(state);
1510            check_stack(state, 5)?;
1511
1512            lua.push(t)?;
1513            rawset_field(state, ffi::LUA_REGISTRYINDEX, name)
1514        }
1515    }
1516
1517    /// Get a value from the Lua registry based on a string name.
1518    ///
1519    /// Any Lua instance which shares the underlying main state may call this method to
1520    /// get a value previously set by [`Lua::set_named_registry_value`].
1521    pub fn named_registry_value<T>(&self, name: &str) -> Result<T>
1522    where
1523        T: FromLua,
1524    {
1525        let lua = self.lock();
1526        let state = lua.state();
1527        unsafe {
1528            let _sg = StackGuard::new(state);
1529            check_stack(state, 3)?;
1530
1531            let protect = !lua.unlikely_memory_error();
1532            push_string(state, name.as_bytes(), protect)?;
1533            ffi::lua_rawget(state, ffi::LUA_REGISTRYINDEX);
1534
1535            T::from_stack(-1, &lua)
1536        }
1537    }
1538
1539    /// Removes a named value in the Lua registry.
1540    ///
1541    /// Equivalent to calling [`Lua::set_named_registry_value`] with a value of Nil.
1542    pub fn unset_named_registry_value(&self, name: &str) -> Result<()> {
1543        self.set_named_registry_value(name, Nil)
1544    }
1545
1546    /// Place a value in the Lua registry with an auto-generated key.
1547    ///
1548    /// This value will be available to Rust from all `Lua` instances which share the same main
1549    /// state.
1550    ///
1551    /// Be warned, garbage collection of values held inside the registry is not automatic, see
1552    /// [`RegistryKey`] for more details.
1553    /// However, dropped [`RegistryKey`]s automatically reused to store new values.
1554    pub fn create_registry_value(&self, t: impl IntoLua) -> Result<RegistryKey> {
1555        let lua = self.lock();
1556        let state = lua.state();
1557        unsafe {
1558            let _sg = StackGuard::new(state);
1559            check_stack(state, 4)?;
1560
1561            lua.push(t)?;
1562
1563            let unref_list = (*lua.extra.get()).registry_unref_list.clone();
1564
1565            // Check if the value is nil (no need to store it in the registry)
1566            if ffi::lua_isnil(state, -1) != 0 {
1567                return Ok(RegistryKey::new(ffi::LUA_REFNIL, unref_list));
1568            }
1569
1570            // Try to reuse previously allocated slot
1571            let free_registry_id = unref_list.lock().as_mut().and_then(|x| x.pop());
1572            if let Some(registry_id) = free_registry_id {
1573                // It must be safe to replace the value without triggering memory error
1574                ffi::lua_rawseti(state, ffi::LUA_REGISTRYINDEX, registry_id as Integer);
1575                return Ok(RegistryKey::new(registry_id, unref_list));
1576            }
1577
1578            // Allocate a new RegistryKey slot
1579            let registry_id = if lua.unlikely_memory_error() {
1580                ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX)
1581            } else {
1582                protect_lua!(state, 1, 0, |state| {
1583                    ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX)
1584                })?
1585            };
1586            Ok(RegistryKey::new(registry_id, unref_list))
1587        }
1588    }
1589
1590    /// Get a value from the Lua registry by its `RegistryKey`
1591    ///
1592    /// Any Lua instance which shares the underlying main state may call this method to get a value
1593    /// previously placed by [`Lua::create_registry_value`].
1594    pub fn registry_value<T: FromLua>(&self, key: &RegistryKey) -> Result<T> {
1595        let lua = self.lock();
1596        if !lua.owns_registry_value(key) {
1597            return Err(Error::MismatchedRegistryKey);
1598        }
1599
1600        let state = lua.state();
1601        match key.id() {
1602            ffi::LUA_REFNIL => T::from_lua(Value::Nil, self),
1603            registry_id => unsafe {
1604                let _sg = StackGuard::new(state);
1605                check_stack(state, 1)?;
1606
1607                ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, registry_id as Integer);
1608                T::from_stack(-1, &lua)
1609            },
1610        }
1611    }
1612
1613    /// Removes a value from the Lua registry.
1614    ///
1615    /// You may call this function to manually remove a value placed in the registry with
1616    /// [`Lua::create_registry_value`]. In addition to manual [`RegistryKey`] removal, you can also
1617    /// call [`Lua::expire_registry_values`] to automatically remove values from the registry
1618    /// whose [`RegistryKey`]s have been dropped.
1619    pub fn remove_registry_value(&self, key: RegistryKey) -> Result<()> {
1620        let lua = self.lock();
1621        if !lua.owns_registry_value(&key) {
1622            return Err(Error::MismatchedRegistryKey);
1623        }
1624
1625        unsafe {
1626            ffi::luaL_unref(lua.state(), ffi::LUA_REGISTRYINDEX, key.take());
1627        }
1628        Ok(())
1629    }
1630
1631    /// Replaces a value in the Lua registry by its [`RegistryKey`].
1632    ///
1633    /// An identifier used in [`RegistryKey`] may possibly be changed to a new value.
1634    ///
1635    /// See [`Lua::create_registry_value`] for more details.
1636    pub fn replace_registry_value(&self, key: &mut RegistryKey, t: impl IntoLua) -> Result<()> {
1637        let lua = self.lock();
1638        if !lua.owns_registry_value(key) {
1639            return Err(Error::MismatchedRegistryKey);
1640        }
1641
1642        let t = t.into_lua(self)?;
1643
1644        let state = lua.state();
1645        unsafe {
1646            let _sg = StackGuard::new(state);
1647            check_stack(state, 2)?;
1648
1649            match (t, key.id()) {
1650                (Value::Nil, ffi::LUA_REFNIL) => {
1651                    // Do nothing, no need to replace nil with nil
1652                }
1653                (Value::Nil, registry_id) => {
1654                    // Remove the value
1655                    ffi::luaL_unref(state, ffi::LUA_REGISTRYINDEX, registry_id);
1656                    key.set_id(ffi::LUA_REFNIL);
1657                }
1658                (value, ffi::LUA_REFNIL) => {
1659                    // Allocate a new `RegistryKey`
1660                    let new_key = self.create_registry_value(value)?;
1661                    key.set_id(new_key.take());
1662                }
1663                (value, registry_id) => {
1664                    // It must be safe to replace the value without triggering memory error
1665                    lua.push_value(&value)?;
1666                    ffi::lua_rawseti(state, ffi::LUA_REGISTRYINDEX, registry_id as Integer);
1667                }
1668            }
1669        }
1670        Ok(())
1671    }
1672
1673    /// Returns true if the given [`RegistryKey`] was created by a [`Lua`] which shares the
1674    /// underlying main state with this [`Lua`] instance.
1675    ///
1676    /// Other than this, methods that accept a [`RegistryKey`] will return
1677    /// [`Error::MismatchedRegistryKey`] if passed a [`RegistryKey`] that was not created with a
1678    /// matching [`Lua`] state.
1679    #[inline]
1680    pub fn owns_registry_value(&self, key: &RegistryKey) -> bool {
1681        self.lock().owns_registry_value(key)
1682    }
1683
1684    /// Remove any registry values whose [`RegistryKey`]s have all been dropped.
1685    ///
1686    /// Unlike normal handle values, [`RegistryKey`]s do not automatically remove themselves on
1687    /// Drop, but you can call this method to remove any unreachable registry values not
1688    /// manually removed by [`Lua::remove_registry_value`].
1689    pub fn expire_registry_values(&self) {
1690        let lua = self.lock();
1691        let state = lua.state();
1692        unsafe {
1693            let mut unref_list = (*lua.extra.get()).registry_unref_list.lock();
1694            let unref_list = mem::replace(&mut *unref_list, Some(Vec::new()));
1695            for id in mlua_expect!(unref_list, "unref list not set") {
1696                ffi::luaL_unref(state, ffi::LUA_REGISTRYINDEX, id);
1697            }
1698        }
1699    }
1700
1701    /// Sets or replaces an application data object of type `T`.
1702    ///
1703    /// Application data could be accessed at any time by using [`Lua::app_data_ref`] or
1704    /// [`Lua::app_data_mut`] methods where `T` is the data type.
1705    ///
1706    /// # Panics
1707    ///
1708    /// Panics if the app data container is currently borrowed.
1709    ///
1710    /// # Examples
1711    ///
1712    /// ```
1713    /// use mlua::{Lua, Result};
1714    ///
1715    /// fn hello(lua: &Lua, _: ()) -> Result<()> {
1716    ///     let mut s = lua.app_data_mut::<&str>().unwrap();
1717    ///     assert_eq!(*s, "hello");
1718    ///     *s = "world";
1719    ///     Ok(())
1720    /// }
1721    ///
1722    /// fn main() -> Result<()> {
1723    ///     let lua = Lua::new();
1724    ///     lua.set_app_data("hello");
1725    ///     lua.create_function(hello)?.call(())?;
1726    ///     let s = lua.app_data_ref::<&str>().unwrap();
1727    ///     assert_eq!(*s, "world");
1728    ///     Ok(())
1729    /// }
1730    /// ```
1731    #[track_caller]
1732    pub fn set_app_data<T: MaybeSend + 'static>(&self, data: T) -> Option<T> {
1733        let lua = self.lock();
1734        let extra = unsafe { &*lua.extra.get() };
1735        extra.app_data.insert(data)
1736    }
1737
1738    /// Tries to set or replace an application data object of type `T`.
1739    ///
1740    /// Returns:
1741    /// - `Ok(Some(old_data))` if the data object of type `T` was successfully replaced.
1742    /// - `Ok(None)` if the data object of type `T` was successfully inserted.
1743    /// - `Err(data)` if the data object of type `T` was not inserted because the container is
1744    ///   currently borrowed.
1745    ///
1746    /// See [`Lua::set_app_data()`] for examples.
1747    pub fn try_set_app_data<T: MaybeSend + 'static>(&self, data: T) -> StdResult<Option<T>, T> {
1748        let lua = self.lock();
1749        let extra = unsafe { &*lua.extra.get() };
1750        extra.app_data.try_insert(data)
1751    }
1752
1753    /// Gets a reference to an application data object stored by [`Lua::set_app_data()`] of type
1754    /// `T`.
1755    ///
1756    /// # Panics
1757    ///
1758    /// Panics if the data object of type `T` is currently mutably borrowed. Multiple immutable
1759    /// reads can be taken out at the same time.
1760    #[track_caller]
1761    pub fn app_data_ref<T: 'static>(&self) -> Option<AppDataRef<T>> {
1762        let guard = self.lock_arc();
1763        let extra = unsafe { &*guard.extra.get() };
1764        extra.app_data.borrow(Some(guard))
1765    }
1766
1767    /// Gets a mutable reference to an application data object stored by [`Lua::set_app_data()`] of
1768    /// type `T`.
1769    ///
1770    /// # Panics
1771    ///
1772    /// Panics if the data object of type `T` is currently borrowed.
1773    #[track_caller]
1774    pub fn app_data_mut<T: 'static>(&self) -> Option<AppDataRefMut<T>> {
1775        let guard = self.lock_arc();
1776        let extra = unsafe { &*guard.extra.get() };
1777        extra.app_data.borrow_mut(Some(guard))
1778    }
1779
1780    /// Removes an application data of type `T`.
1781    ///
1782    /// # Panics
1783    ///
1784    /// Panics if the app data container is currently borrowed.
1785    #[track_caller]
1786    pub fn remove_app_data<T: 'static>(&self) -> Option<T> {
1787        let lua = self.lock();
1788        let extra = unsafe { &*lua.extra.get() };
1789        extra.app_data.remove()
1790    }
1791
1792    /// Pushes a value that implements `IntoLua` onto the Lua stack.
1793    ///
1794    /// Uses 2 stack spaces, does not call checkstack.
1795    #[doc(hidden)]
1796    #[inline(always)]
1797    pub unsafe fn push(&self, value: impl IntoLua) -> Result<()> {
1798        self.lock().push(value)
1799    }
1800
1801    /// Returns an internal `Poll::Pending` constant used for executing async callbacks.
1802    #[cfg(feature = "async")]
1803    #[doc(hidden)]
1804    #[inline(always)]
1805    pub fn poll_pending() -> LightUserData {
1806        static ASYNC_POLL_PENDING: u8 = 0;
1807        LightUserData(&ASYNC_POLL_PENDING as *const u8 as *mut c_void)
1808    }
1809
1810    // Luau version located in `luau/mod.rs`
1811    #[cfg(not(feature = "luau"))]
1812    fn disable_c_modules(&self) -> Result<()> {
1813        let package: Table = self.globals().get("package")?;
1814
1815        package.set(
1816            "loadlib",
1817            self.create_function(|_, ()| -> Result<()> {
1818                Err(Error::SafetyError(
1819                    "package.loadlib is disabled in safe mode".to_string(),
1820                ))
1821            })?,
1822        )?;
1823
1824        #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
1825        let searchers: Table = package.get("searchers")?;
1826        #[cfg(any(feature = "lua51", feature = "luajit"))]
1827        let searchers: Table = package.get("loaders")?;
1828
1829        let loader = self.create_function(|_, ()| Ok("\n\tcan't load C modules in safe mode"))?;
1830
1831        // The third and fourth searchers looks for a loader as a C library
1832        searchers.raw_set(3, loader)?;
1833        searchers.raw_remove(4)?;
1834
1835        Ok(())
1836    }
1837
1838    #[inline(always)]
1839    pub(crate) fn lock(&self) -> ReentrantMutexGuard<RawLua> {
1840        self.raw.lock()
1841    }
1842
1843    #[inline(always)]
1844    pub(crate) fn lock_arc(&self) -> LuaGuard {
1845        LuaGuard(self.raw.lock_arc())
1846    }
1847
1848    #[inline(always)]
1849    pub(crate) fn weak(&self) -> WeakLua {
1850        WeakLua(XRc::downgrade(&self.raw))
1851    }
1852
1853    /// Returns a handle to the unprotected Lua state without any synchronization.
1854    ///
1855    /// This is useful where we know that the lock is already held by the caller.
1856    #[inline(always)]
1857    pub(crate) unsafe fn raw_lua(&self) -> &RawLua {
1858        &*self.raw.data_ptr()
1859    }
1860}
1861
1862impl WeakLua {
1863    #[track_caller]
1864    #[inline(always)]
1865    pub(crate) fn lock(&self) -> LuaGuard {
1866        LuaGuard::new(self.0.upgrade().expect("Lua instance is destroyed"))
1867    }
1868
1869    #[inline(always)]
1870    pub(crate) fn try_lock(&self) -> Option<LuaGuard> {
1871        Some(LuaGuard::new(self.0.upgrade()?))
1872    }
1873
1874    #[track_caller]
1875    #[inline(always)]
1876    pub(crate) fn upgrade(&self) -> Lua {
1877        Lua {
1878            raw: self.0.upgrade().expect("Lua instance is destroyed"),
1879            collect_garbage: false,
1880        }
1881    }
1882}
1883
1884impl PartialEq for WeakLua {
1885    fn eq(&self, other: &Self) -> bool {
1886        XWeak::ptr_eq(&self.0, &other.0)
1887    }
1888}
1889
1890impl Eq for WeakLua {}
1891
1892impl LuaGuard {
1893    #[cfg(feature = "send")]
1894    pub(crate) fn new(handle: XRc<ReentrantMutex<RawLua>>) -> Self {
1895        LuaGuard(handle.lock_arc())
1896    }
1897
1898    #[cfg(not(feature = "send"))]
1899    pub(crate) fn new(handle: XRc<ReentrantMutex<RawLua>>) -> Self {
1900        LuaGuard(handle.into_lock_arc())
1901    }
1902}
1903
1904impl Deref for LuaGuard {
1905    type Target = RawLua;
1906
1907    fn deref(&self) -> &Self::Target {
1908        &self.0
1909    }
1910}
1911
1912pub(crate) mod extra;
1913mod raw;
1914pub(crate) mod util;
1915
1916#[cfg(test)]
1917mod assertions {
1918    use super::*;
1919
1920    // Lua has lots of interior mutability, should not be RefUnwindSafe
1921    static_assertions::assert_not_impl_any!(Lua: std::panic::RefUnwindSafe);
1922
1923    #[cfg(not(feature = "send"))]
1924    static_assertions::assert_not_impl_any!(Lua: Send);
1925    #[cfg(feature = "send")]
1926    static_assertions::assert_impl_all!(Lua: Send, Sync);
1927}