diff --git a/Cargo.toml b/Cargo.toml index c386fd3..a3f4b83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rlua" -version = "0.13.1-alpha.0" +version = "0.14.0-alpha.0" authors = ["kyren "] description = "High level bindings to Lua 5.3" repository = "https://github.com/chucklefish/rlua" diff --git a/src/lua.rs b/src/lua.rs index 14b0455..c858ef3 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -46,14 +46,22 @@ unsafe impl Send for Lua {} impl Drop for Lua { fn drop(&mut self) { unsafe { - if !self.ephemeral { - let top = ffi::lua_gettop(self.state); - rlua_assert!( - top == REF_STACK_SIZE, - "stack problem detected, stack top is {}", - top - REF_STACK_SIZE - ); + if cfg!(debug_assertions) { + for use_count in &self.ref_stack_slots { + rlua_assert!(use_count.get() == 0, "live stack reference detected"); + } + if !self.ephemeral { + let top = ffi::lua_gettop(self.state); + rlua_assert!( + top == REF_STACK_SIZE, + "stack problem detected, stack top is {}", + top - REF_STACK_SIZE + ); + } + } + + if !self.ephemeral { let extra_data = *(ffi::lua_getextraspace(self.state) as *mut *mut ExtraData); *(*extra_data).registry_unref_list.lock().unwrap() = None; Box::from_raw(extra_data); @@ -819,7 +827,7 @@ impl Lua { RefType::Stack { stack_slot } => { let ref_slot = &self.ref_stack_slots[(stack_slot - 1) as usize]; let ref_count = ref_slot.get(); - rlua_assert!(ref_count > 0, "ref slot use count has gone below zero"); + rlua_debug_assert!(ref_count > 0, "ref slot use count has gone below zero"); ref_slot.set(ref_count - 1); if ref_count == 1 { ffi::lua_pushnil(self.state); @@ -1125,7 +1133,7 @@ impl Lua { })); *(ffi::lua_getextraspace(state) as *mut *mut ExtraData) = extra_data; - rlua_assert!(ffi::lua_gettop(state) == 0, "stack leak during creation"); + rlua_debug_assert!(ffi::lua_gettop(state) == 0, "stack leak during creation"); check_stack(state, REF_STACK_SIZE); ffi::lua_settop(state, REF_STACK_SIZE); diff --git a/src/macros.rs b/src/macros.rs index fb10a07..233495f 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -40,6 +40,16 @@ macro_rules! rlua_assert { }; } +macro_rules! rlua_debug_assert { + ($cond:expr, $msg:expr) => { + debug_assert!($cond, concat!("rlua internal error: ", $msg)); + }; + + ($cond:expr, $msg:expr, $($arg:tt)+) => { + debug_assert!($cond, concat!("rlua internal error: ", $msg), $($arg)+); + }; +} + macro_rules! rlua_abort { ($msg:expr) => { { diff --git a/src/string.rs b/src/string.rs index 1610f3e..835eb54 100644 --- a/src/string.rs +++ b/src/string.rs @@ -73,7 +73,7 @@ impl<'lua> String<'lua> { check_stack(lua.state, 1); lua.push_ref(&self.0); - rlua_assert!( + rlua_debug_assert!( ffi::lua_type(lua.state, -1) == ffi::LUA_TSTRING, "string ref is not string type" ); diff --git a/src/tests/mod.rs b/src/tests/mod.rs index f24506f..e40f102 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -781,9 +781,9 @@ fn large_args() { ); } +#[test] fn large_args_ref() { let lua = Lua::new(); - let globals = lua.globals(); let f = lua.create_function(|_, args: Variadic| { for i in 0..args.len() { diff --git a/src/tests/thread.rs b/src/tests/thread.rs index 56b671d..48284d7 100644 --- a/src/tests/thread.rs +++ b/src/tests/thread.rs @@ -100,7 +100,7 @@ fn coroutine_panic() { match catch_unwind(|| -> Result<()> { // check that coroutines propagate panics correctly let lua = Lua::new(); - let thrd_main = lua.create_function(|lua, ()| -> Result<()> { + let thrd_main = lua.create_function(|_, ()| -> Result<()> { panic!("test_panic"); })?; lua.globals().set("main", thrd_main.clone())?; diff --git a/src/userdata.rs b/src/userdata.rs index be8fb32..914914c 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -420,7 +420,7 @@ impl<'lua> AnyUserData<'lua> { lua.push_ref(&self.0); - rlua_assert!( + rlua_debug_assert!( ffi::lua_getmetatable(lua.state, -1) != 0, "AnyUserData missing metatable" ); diff --git a/src/util.rs b/src/util.rs index b5ba46a..99b623c 100644 --- a/src/util.rs +++ b/src/util.rs @@ -158,7 +158,7 @@ where // 3) Otherwise, interprets the error as the appropriate lua error. // Uses 2 stack spaces, does not call lua_checkstack. pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error { - rlua_assert!( + rlua_debug_assert!( err_code != ffi::LUA_OK && err_code != ffi::LUA_YIELD, "pop_error called with non-error return code" ); @@ -229,7 +229,7 @@ pub unsafe fn push_userdata(state: *mut ffi::lua_State, t: T) -> Result<()> { pub unsafe fn get_userdata(state: *mut ffi::lua_State, index: c_int) -> *mut T { let ud = ffi::lua_touserdata(state, index) as *mut T; - rlua_assert!(!ud.is_null(), "userdata pointer is null"); + rlua_debug_assert!(!ud.is_null(), "userdata pointer is null"); ud } @@ -243,7 +243,7 @@ pub unsafe fn take_userdata(state: *mut ffi::lua_State) -> T { get_destructed_userdata_metatable(state); ffi::lua_setmetatable(state, -2); let ud = ffi::lua_touserdata(state, -1) as *mut T; - rlua_assert!(!ud.is_null(), "userdata pointer is null"); + rlua_debug_assert!(!ud.is_null(), "userdata pointer is null"); ffi::lua_pop(state, 1); ptr::read(ud) }