diff --git a/src/lua.rs b/src/lua.rs index fcef729..d1d286e 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -1721,14 +1721,29 @@ impl Lua { let _sg = StackGuard::new(self.state); check_stack(self.state, 4)?; + let unref_list = (*self.extra.get()).registry_unref_list.clone(); self.push_value(t)?; + + // Try to reuse previously allocated RegistryKey + let unref_list2 = unref_list.clone(); + let mut unref_list2 = mlua_expect!(unref_list2.lock(), "unref list poisoned"); + if let Some(registry_id) = unref_list2.as_mut().and_then(|x| x.pop()) { + // It must be safe to replace the value without triggering memory error + ffi::lua_rawseti(self.state, ffi::LUA_REGISTRYINDEX, registry_id as Integer); + return Ok(RegistryKey { + registry_id, + unref_list, + }); + } + + // Allocate a new RegistryKey let registry_id = protect_lua!(self.state, 1, 0, |state| { ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX) })?; Ok(RegistryKey { registry_id, - unref_list: (*self.extra.get()).registry_unref_list.clone(), + unref_list, }) } } @@ -1787,6 +1802,10 @@ impl Lua { key: &RegistryKey, t: T, ) -> Result<()> { + if !self.owns_registry_value(key) { + return Err(Error::MismatchedRegistryKey); + } + let t = t.to_lua(self)?; unsafe { let _sg = StackGuard::new(self.state);