Allow multiple entrypoints in a single module share the same Lua state.
Previously it would initialize different Lua instances. Fixes #49.
This commit is contained in:
parent
973b5c3bf5
commit
e8de2a458a
|
@ -8,10 +8,27 @@ fn used_memory(lua: &Lua, _: ()) -> LuaResult<usize> {
|
|||
Ok(lua.used_memory())
|
||||
}
|
||||
|
||||
fn check_userdata(_: &Lua, ud: MyUserData) -> LuaResult<i32> {
|
||||
Ok(ud.0)
|
||||
}
|
||||
|
||||
#[mlua::lua_module]
|
||||
fn rust_module(lua: &Lua) -> LuaResult<LuaTable> {
|
||||
let exports = lua.create_table()?;
|
||||
exports.set("sum", lua.create_function(sum)?)?;
|
||||
exports.set("used_memory", lua.create_function(used_memory)?)?;
|
||||
exports.set("check_userdata", lua.create_function(check_userdata)?)?;
|
||||
Ok(exports)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct MyUserData(i32);
|
||||
|
||||
impl LuaUserData for MyUserData {}
|
||||
|
||||
#[mlua::lua_module]
|
||||
fn rust_module_second(lua: &Lua) -> LuaResult<LuaTable> {
|
||||
let exports = lua.create_table()?;
|
||||
exports.set("userdata", lua.create_userdata(MyUserData(123))?)?;
|
||||
Ok(exports)
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ pub unsafe extern "C" fn mlua_hook_proc(state: *mut lua_State, ar: *mut lua_Debu
|
|||
_phantom: PhantomData,
|
||||
};
|
||||
|
||||
let lua = Lua::make_from_ptr(state);
|
||||
let lua = mlua_expect!(Lua::make_from_ptr(state), "cannot make Lua instance");
|
||||
let hook_cb = mlua_expect!(lua.hook_callback(), "no hook callback set in hook_proc");
|
||||
|
||||
#[allow(clippy::match_wild_err_arm)]
|
||||
|
|
18
src/lua.rs
18
src/lua.rs
|
@ -369,6 +369,10 @@ impl Lua {
|
|||
let main_state = maybe_main_state.unwrap_or(state);
|
||||
let main_state_top = ffi::lua_gettop(main_state);
|
||||
|
||||
if let Some(lua) = Lua::make_from_ptr(state) {
|
||||
return lua;
|
||||
}
|
||||
|
||||
let ref_thread = mlua_expect!(
|
||||
(|state| {
|
||||
// Before initializing the error registry, we must set Error/Panic size.
|
||||
|
@ -437,8 +441,8 @@ impl Lua {
|
|||
);
|
||||
let extra_key = &EXTRA_REGISTRY_KEY as *const u8 as *const c_void;
|
||||
mlua_expect!(
|
||||
ffi::safe::lua_rawsetp(main_state, ffi::LUA_REGISTRYINDEX, extra_key,),
|
||||
"Error while storing extra data"
|
||||
ffi::safe::lua_rawsetp(main_state, ffi::LUA_REGISTRYINDEX, extra_key),
|
||||
"Error while storing extra data",
|
||||
);
|
||||
|
||||
mlua_debug_assert!(
|
||||
|
@ -1972,12 +1976,14 @@ impl Lua {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn make_from_ptr(state: *mut ffi::lua_State) -> Self {
|
||||
pub(crate) unsafe fn make_from_ptr(state: *mut ffi::lua_State) -> Option<Self> {
|
||||
let _sg = StackGuard::new(state);
|
||||
assert_stack(state, 1);
|
||||
|
||||
let extra_key = &EXTRA_REGISTRY_KEY as *const u8 as *const c_void;
|
||||
ffi::lua_rawgetp(state, ffi::LUA_REGISTRYINDEX, extra_key);
|
||||
if ffi::lua_rawgetp(state, ffi::LUA_REGISTRYINDEX, extra_key) != ffi::LUA_TUSERDATA {
|
||||
return None;
|
||||
}
|
||||
let extra = mlua_expect!(
|
||||
(*get_gc_userdata::<Weak<Mutex<ExtraData>>>(state, -1)).upgrade(),
|
||||
"extra is destroyed"
|
||||
|
@ -1986,14 +1992,14 @@ impl Lua {
|
|||
|
||||
let safe = mlua_expect!(extra.lock(), "extra is poisoned").safe;
|
||||
|
||||
Lua {
|
||||
Some(Lua {
|
||||
state,
|
||||
main_state: get_main_state(state),
|
||||
extra,
|
||||
ephemeral: true,
|
||||
safe,
|
||||
_no_ref_unwind_safe: PhantomData,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) unsafe fn hook_callback(&self) -> Option<HookCallback> {
|
||||
|
|
|
@ -15,6 +15,19 @@ fn test_module() -> Result<()> {
|
|||
.exec()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_module_multi() -> Result<()> {
|
||||
let lua = make_lua()?;
|
||||
lua.load(
|
||||
r#"
|
||||
local mod = require("rust_module")
|
||||
local mod2 = require("rust_module.second")
|
||||
assert(mod.check_userdata(mod2.userdata) == 123)
|
||||
"#,
|
||||
)
|
||||
.exec()
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
|
|
Loading…
Reference in New Issue