Tests for LuaError conversion, Important pcall / xpcall bugfixes.
This commit is contained in:
parent
cbae1a805a
commit
7dba280a4b
|
@ -44,8 +44,8 @@ pub enum LuaValue<'lua> {
|
||||||
/// `LuaUserDataType`. Special builtin userdata types will be represented as
|
/// `LuaUserDataType`. Special builtin userdata types will be represented as
|
||||||
/// other `LuaValue` variants.
|
/// other `LuaValue` variants.
|
||||||
UserData(LuaUserData<'lua>),
|
UserData(LuaUserData<'lua>),
|
||||||
/// `LuaError` is a special builtin userdata type. When taken out of Lua it
|
/// `LuaError` is a special builtin userdata type. When received from Lua
|
||||||
/// is implicitly cloned.
|
/// it is implicitly cloned.
|
||||||
Error(LuaError),
|
Error(LuaError),
|
||||||
}
|
}
|
||||||
pub use self::LuaValue::Nil as LuaNil;
|
pub use self::LuaValue::Nil as LuaNil;
|
||||||
|
|
25
src/tests.rs
25
src/tests.rs
|
@ -452,6 +452,16 @@ fn test_error() {
|
||||||
rust_error_function()
|
rust_error_function()
|
||||||
end
|
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()
|
function test_pcall()
|
||||||
local testvar = 0
|
local testvar = 0
|
||||||
|
|
||||||
|
@ -465,9 +475,10 @@ fn test_error() {
|
||||||
return "should be ignored"
|
return "should be ignored"
|
||||||
end
|
end
|
||||||
|
|
||||||
xpcall(function()
|
local status, res = xpcall(function()
|
||||||
error(5)
|
error(5)
|
||||||
end, handler)
|
end, handler)
|
||||||
|
assert(not status)
|
||||||
|
|
||||||
if testvar ~= 8 then
|
if testvar ~= 8 then
|
||||||
error("testvar had the wrong value, pcall / xpcall misbehaving "..testvar)
|
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 no_error = globals.get::<_, LuaFunction>("no_error").unwrap();
|
||||||
let lua_error = globals.get::<_, LuaFunction>("lua_error").unwrap();
|
let lua_error = globals.get::<_, LuaFunction>("lua_error").unwrap();
|
||||||
let rust_error = globals.get::<_, LuaFunction>("rust_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 test_pcall = globals.get::<_, LuaFunction>("test_pcall").unwrap();
|
||||||
let understand_recursion = globals
|
let understand_recursion = globals
|
||||||
.get::<_, LuaFunction>("understand_recursion")
|
.get::<_, LuaFunction>("understand_recursion")
|
||||||
|
@ -506,6 +521,14 @@ fn test_error() {
|
||||||
Err(_) => panic!("error is not CallbackError kind"),
|
Err(_) => panic!("error is not CallbackError kind"),
|
||||||
_ => panic!("error not returned"),
|
_ => 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") {
|
match lua.eval::<()>("if youre happy and you know it syntax error") {
|
||||||
Err(LuaError::SyntaxError(LuaSyntaxError::Syntax(_))) => {}
|
Err(LuaError::SyntaxError(LuaSyntaxError::Syntax(_))) => {}
|
||||||
Err(_) => panic!("error is not LuaSyntaxError::Syntax kind"),
|
Err(_) => panic!("error is not LuaSyntaxError::Syntax kind"),
|
||||||
|
|
20
src/util.rs
20
src/util.rs
|
@ -286,9 +286,15 @@ pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int {
|
||||||
if is_wrapped_panic(state, -1) {
|
if is_wrapped_panic(state, -1) {
|
||||||
ffi::lua_error(state);
|
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
|
// A variant of xpcall that does not allow lua to catch panic errors from callback_error
|
||||||
pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
|
pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
|
||||||
|
@ -313,8 +319,14 @@ pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
|
||||||
if is_wrapped_panic(state, -1) {
|
if is_wrapped_panic(state, -1) {
|
||||||
ffi::lua_error(state);
|
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
|
/// Does not call checkstack, uses 1 stack space
|
||||||
|
@ -427,7 +439,9 @@ pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<LuaError>
|
||||||
} else {
|
} else {
|
||||||
let userdata = ffi::lua_touserdata(state, -1);
|
let userdata = ffi::lua_touserdata(state, -1);
|
||||||
let err = &*(userdata as *const WrappedError);
|
let err = &*(userdata as *const WrappedError);
|
||||||
Some(err.0.clone())
|
let err = err.0.clone();
|
||||||
|
ffi::lua_pop(state, 1);
|
||||||
|
Some(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue