Use dynamic Lua state ownership instead of compile-time module cfg flag to allow

creating new VMs in module mode (and destructing them properly).
This commit is contained in:
Alex Orlenko
2024-08-31 22:52:55 +01:00
parent 1634c43f0a
commit 825bdbfa04
8 changed files with 43 additions and 17 deletions
+1 -1
View File
@@ -271,7 +271,7 @@ impl Lua {
#[inline]
pub unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> Lua {
Lua {
raw: RawLua::init_from_ptr(state),
raw: RawLua::init_from_ptr(state, false),
collect_garbage: true,
}
}
+8 -6
View File
@@ -33,6 +33,7 @@ const REF_STACK_RESERVE: c_int = 1;
pub(crate) struct ExtraData {
pub(super) lua: MaybeUninit<Lua>,
pub(super) weak: MaybeUninit<WeakLua>,
pub(super) owned: bool,
pub(super) registered_userdata: FxHashMap<TypeId, c_int>,
pub(super) registered_userdata_mt: FxHashMap<*const c_void, Option<TypeId>>,
@@ -46,7 +47,7 @@ pub(crate) struct ExtraData {
pub(super) safe: bool,
pub(super) libs: StdLib,
#[cfg(feature = "module")]
// Used in module mode
pub(super) skip_memory_check: bool,
// Auxiliary thread to store references
@@ -88,8 +89,9 @@ pub(crate) struct ExtraData {
impl Drop for ExtraData {
fn drop(&mut self) {
unsafe {
#[cfg(feature = "module")]
self.lua.assume_init_drop();
if !self.owned {
self.lua.assume_init_drop();
}
self.weak.assume_init_drop();
}
@@ -111,7 +113,7 @@ impl ExtraData {
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
pub(super) const ERROR_TRACEBACK_IDX: c_int = 1;
pub(super) unsafe fn init(state: *mut ffi::lua_State) -> XRc<UnsafeCell<Self>> {
pub(super) unsafe fn init(state: *mut ffi::lua_State, owned: bool) -> XRc<UnsafeCell<Self>> {
// Create ref stack thread and place it in the registry to prevent it
// from being garbage collected.
let ref_thread = mlua_expect!(
@@ -141,6 +143,7 @@ impl ExtraData {
let extra = XRc::new(UnsafeCell::new(ExtraData {
lua: MaybeUninit::uninit(),
weak: MaybeUninit::uninit(),
owned,
registered_userdata: FxHashMap::default(),
registered_userdata_mt: FxHashMap::default(),
last_checked_userdata_mt: (ptr::null(), None),
@@ -148,7 +151,6 @@ impl ExtraData {
app_data: AppData::default(),
safe: false,
libs: StdLib::NONE,
#[cfg(feature = "module")]
skip_memory_check: false,
ref_thread,
// We need some reserved stack space to move values in and out of the ref stack.
@@ -188,7 +190,7 @@ impl ExtraData {
raw: XRc::clone(raw),
collect_garbage: false,
});
if cfg!(not(feature = "module")) {
if self.owned {
XRc::decrement_strong_count(XRc::as_ptr(raw));
}
self.weak.write(WeakLua(XRc::downgrade(raw)));
+7 -7
View File
@@ -50,10 +50,13 @@ pub struct RawLua {
pub(super) extra: XRc<UnsafeCell<ExtraData>>,
}
#[cfg(not(feature = "module"))]
impl Drop for RawLua {
fn drop(&mut self) {
unsafe {
if !(*self.extra.get()).owned {
return;
}
let mem_state = MemoryState::get(self.main_state);
ffi::lua_close(self.main_state);
@@ -115,7 +118,7 @@ impl RawLua {
ffi::luau_codegen_create(state);
}
let rawlua = Self::init_from_ptr(state);
let rawlua = Self::init_from_ptr(state, true);
let extra = rawlua.lock().extra.get();
mlua_expect!(
@@ -154,7 +157,7 @@ impl RawLua {
rawlua
}
pub(super) unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> XRc<ReentrantMutex<Self>> {
pub(super) unsafe fn init_from_ptr(state: *mut ffi::lua_State, owned: bool) -> XRc<ReentrantMutex<Self>> {
assert!(!state.is_null(), "Lua state is NULL");
if let Some(lua) = Self::try_from_ptr(state) {
return lua;
@@ -191,7 +194,7 @@ impl RawLua {
);
// Init ExtraData
let extra = ExtraData::init(main_state);
let extra = ExtraData::init(main_state, owned);
// Register `DestructedUserdata` type
get_destructed_userdata_metatable(main_state);
@@ -704,10 +707,7 @@ impl RawLua {
// MemoryInfo is empty in module mode so we cannot predict memory limits
match MemoryState::get(self.main_state) {
mem_state if !mem_state.is_null() => (*mem_state).memory_limit() == 0,
#[cfg(feature = "module")]
_ => (*self.extra.get()).skip_memory_check, // Check the special flag (only for module mode)
#[cfg(not(feature = "module"))]
_ => false,
}
}