mlua/
state.rs

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