diff --git a/Cargo.toml b/Cargo.toml index 5d99cca..cc45ec3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -59,7 +59,7 @@ parking_lot = { version = "0.12", features = ["arc_lock"] } anyhow = { version = "1.0", optional = true } rustversion = "1.0" -ffi = { package = "mlua-sys", version = "0.7.0", path = "mlua-sys" } +ffi = { package = "mlua-sys", version = "0.6.8", path = "mlua-sys" } [target.'cfg(unix)'.dependencies] libloading = { version = "0.8", optional = true } diff --git a/src/luau/package.rs b/src/luau/package.rs index b01ab75..f30d54d 100644 --- a/src/luau/package.rs +++ b/src/luau/package.rs @@ -124,15 +124,16 @@ unsafe extern "C-unwind" fn lua_require(state: *mut ffi::lua_State) -> c_int { ffi::lua_pop(state, 1); // remove nil // load the module - let err_buf = ffi::lua_newuserdata_t(state, StdString::new()); + let err_buf = ffi::lua_newuserdata_t::(state); + err_buf.write(StdString::new()); ffi::luaL_getsubtable(state, ffi::LUA_REGISTRYINDEX, cstr!("_LOADERS")); // _LOADERS is at index 3 for i in 1.. { if ffi::lua_rawgeti(state, -1, i) == ffi::LUA_TNIL { // no more loaders? - if (*err_buf).is_empty() { + if (&*err_buf).is_empty() { ffi::luaL_error(state, cstr!("module '%s' not found"), name); } else { - let bytes = (*err_buf).as_bytes(); + let bytes = (&*err_buf).as_bytes(); let extra = ffi::lua_pushlstring(state, bytes.as_ptr() as *const _, bytes.len()); ffi::luaL_error(state, cstr!("module '%s' not found:%s"), name, extra); } diff --git a/src/memory.rs b/src/memory.rs index e5bab38..f469fe1 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -97,7 +97,7 @@ impl MemoryState { } } -unsafe extern "C" fn allocator( +unsafe extern "C-unwind" fn allocator( extra: *mut c_void, ptr: *mut c_void, osize: usize, diff --git a/src/state.rs b/src/state.rs index 653dd05..a38cb5d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1966,12 +1966,7 @@ impl Lua { #[inline(always)] pub(crate) fn lock(&self) -> ReentrantMutexGuard { - let rawlua = self.raw.lock(); - #[cfg(feature = "luau")] - if unsafe { (*rawlua.extra.get()).running_userdata_gc } { - panic!("Luau VM is suspended while userdata destructor is running"); - } - rawlua + self.raw.lock() } #[inline(always)] @@ -1993,12 +1988,7 @@ impl WeakLua { #[track_caller] #[inline(always)] pub(crate) fn lock(&self) -> LuaGuard { - let guard = LuaGuard::new(self.0.upgrade().expect("Lua instance is destroyed")); - #[cfg(feature = "luau")] - if unsafe { (*guard.extra.get()).running_userdata_gc } { - panic!("Luau VM is suspended while userdata destructor is running"); - } - guard + LuaGuard::new(self.0.upgrade().expect("Lua instance is destroyed")) } #[inline(always)] diff --git a/src/state/extra.rs b/src/state/extra.rs index c0d2fe1..07bfd39 100644 --- a/src/state/extra.rs +++ b/src/state/extra.rs @@ -81,8 +81,6 @@ pub(crate) struct ExtraData { #[cfg(feature = "luau")] pub(super) interrupt_callback: Option, - #[cfg(feature = "luau")] - pub(crate) running_userdata_gc: bool, #[cfg(feature = "luau")] pub(super) sandboxed: bool, #[cfg(feature = "luau")] @@ -184,8 +182,6 @@ impl ExtraData { compiler: None, #[cfg(feature = "luau-jit")] enable_jit: true, - #[cfg(feature = "luau")] - running_userdata_gc: false, })); // Store it in the registry diff --git a/src/userdata/util.rs b/src/userdata/util.rs index 98e2de3..27cc63d 100644 --- a/src/userdata/util.rs +++ b/src/userdata/util.rs @@ -437,18 +437,8 @@ pub(crate) unsafe extern "C-unwind" fn collect_userdata(state: *mut ffi::lua_ // This method is called by Luau GC when it's time to collect the userdata. #[cfg(feature = "luau")] -pub(crate) unsafe extern "C" fn collect_userdata( - state: *mut ffi::lua_State, - ud: *mut std::os::raw::c_void, -) { - // Almost none Lua operations are allowed when destructor is running, - // so we need to set a flag to prevent calling any Lua functions - let extra = (*ffi::lua_callbacks(state)).userdata as *mut crate::state::ExtraData; - (*extra).running_userdata_gc = true; - // Luau does not support _any_ panics in destructors (they are declared as "C", NOT as "C-unwind"), - // so any panics will trigger `abort()`. +pub(crate) unsafe extern "C-unwind" fn collect_userdata(ud: *mut std::os::raw::c_void) { ptr::drop_in_place(ud as *mut T); - (*extra).running_userdata_gc = false; } // This method can be called by user or Lua GC to destroy the userdata. diff --git a/src/util/userdata.rs b/src/util/userdata.rs index 2edbf0b..96f9c7b 100644 --- a/src/util/userdata.rs +++ b/src/util/userdata.rs @@ -15,23 +15,20 @@ pub(crate) unsafe fn push_internal_userdata( #[cfg(not(feature = "luau"))] let ud_ptr = if protect { protect_lua!(state, 0, 1, move |state| { - let ud_ptr = ffi::lua_newuserdata(state, const { mem::size_of::() }) as *mut T; - ptr::write(ud_ptr, t); - ud_ptr + ffi::lua_newuserdata(state, const { mem::size_of::() }) as *mut T })? } else { - let ud_ptr = ffi::lua_newuserdata(state, const { mem::size_of::() }) as *mut T; - ptr::write(ud_ptr, t); - ud_ptr + ffi::lua_newuserdata(state, const { mem::size_of::() }) as *mut T }; #[cfg(feature = "luau")] let ud_ptr = if protect { - protect_lua!(state, 0, 1, move |state| ffi::lua_newuserdata_t::(state, t))? + protect_lua!(state, 0, 1, move |state| ffi::lua_newuserdata_t::(state))? } else { - ffi::lua_newuserdata_t::(state, t) + ffi::lua_newuserdata_t::(state) }; + ptr::write(ud_ptr, t); get_internal_metatable::(state); ffi::lua_setmetatable(state, -2); Ok(ud_ptr)