From 7dba280a4b17a56e3b81bf04cb181d7850c16317 Mon Sep 17 00:00:00 2001 From: kyren Date: Sun, 25 Jun 2017 02:40:09 -0400 Subject: [PATCH] Tests for LuaError conversion, Important pcall / xpcall bugfixes. --- src/lua.rs | 4 ++-- src/tests.rs | 25 ++++++++++++++++++++++++- src/util.rs | 20 +++++++++++++++++--- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/src/lua.rs b/src/lua.rs index a382aab..e9b3737 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -44,8 +44,8 @@ pub enum LuaValue<'lua> { /// `LuaUserDataType`. Special builtin userdata types will be represented as /// other `LuaValue` variants. UserData(LuaUserData<'lua>), - /// `LuaError` is a special builtin userdata type. When taken out of Lua it - /// is implicitly cloned. + /// `LuaError` is a special builtin userdata type. When received from Lua + /// it is implicitly cloned. Error(LuaError), } pub use self::LuaValue::Nil as LuaNil; diff --git a/src/tests.rs b/src/tests.rs index 49cfd2c..f33c722 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -452,6 +452,16 @@ fn test_error() { rust_error_function() end + function return_error() + local status, res = pcall(rust_error_function) + assert(not status) + return res + end + + function return_string_error() + return "this should be converted to an error" + end + function test_pcall() local testvar = 0 @@ -465,9 +475,10 @@ fn test_error() { return "should be ignored" end - xpcall(function() + local status, res = xpcall(function() error(5) end, handler) + assert(not status) if testvar ~= 8 then error("testvar had the wrong value, pcall / xpcall misbehaving "..testvar) @@ -490,6 +501,10 @@ fn test_error() { let no_error = globals.get::<_, LuaFunction>("no_error").unwrap(); let lua_error = globals.get::<_, LuaFunction>("lua_error").unwrap(); let rust_error = globals.get::<_, LuaFunction>("rust_error").unwrap(); + let return_error = globals.get::<_, LuaFunction>("return_error").unwrap(); + let return_string_error = globals + .get::<_, LuaFunction>("return_string_error") + .unwrap(); let test_pcall = globals.get::<_, LuaFunction>("test_pcall").unwrap(); let understand_recursion = globals .get::<_, LuaFunction>("understand_recursion") @@ -506,6 +521,14 @@ fn test_error() { Err(_) => panic!("error is not CallbackError kind"), _ => panic!("error not returned"), } + + match return_error.call::<_, LuaValue>(()) { + Ok(LuaValue::Error(_)) => {} + _ => panic!("LuaValue::Error not returned"), + } + + assert!(return_string_error.call::<_, LuaError>(()).is_ok()); + match lua.eval::<()>("if youre happy and you know it syntax error") { Err(LuaError::SyntaxError(LuaSyntaxError::Syntax(_))) => {} Err(_) => panic!("error is not LuaSyntaxError::Syntax kind"), diff --git a/src/util.rs b/src/util.rs index 207b74d..99dbb08 100644 --- a/src/util.rs +++ b/src/util.rs @@ -286,8 +286,14 @@ pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int { if is_wrapped_panic(state, -1) { ffi::lua_error(state); } + ffi::lua_pushboolean(state, 0); + ffi::lua_insert(state, -2); + 2 + } else { + ffi::lua_pushboolean(state, 1); + ffi::lua_insert(state, 1); + ffi::lua_gettop(state) } - ffi::lua_gettop(state) } // A variant of xpcall that does not allow lua to catch panic errors from callback_error @@ -313,8 +319,14 @@ pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int { if is_wrapped_panic(state, -1) { ffi::lua_error(state); } + ffi::lua_pushboolean(state, 0); + ffi::lua_insert(state, -2); + 2 + } else { + ffi::lua_pushboolean(state, 1); + ffi::lua_insert(state, 1); + ffi::lua_gettop(state) } - res } /// Does not call checkstack, uses 1 stack space @@ -427,7 +439,9 @@ pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option } else { let userdata = ffi::lua_touserdata(state, -1); let err = &*(userdata as *const WrappedError); - Some(err.0.clone()) + let err = err.0.clone(); + ffi::lua_pop(state, 1); + Some(err) } }