A lot of corner case bugfixes
This commit is contained in:
parent
b59b8cc23b
commit
a609f709ee
40
src/util.rs
40
src/util.rs
|
@ -113,11 +113,10 @@ where
|
|||
}
|
||||
|
||||
// If the return code indicates an error, pops the error off of the stack and
|
||||
// returns Err. If the error was actually a rust panic, clears the current lua
|
||||
// stack and panics. If the error on the top of the stack is actually a
|
||||
// WrappedError::Error, just returns it. If the error on the top of the stack
|
||||
// is a WrappedError::Panic, clears the rust stack and resumes the panic,
|
||||
// otherwise interprets the error as the appropriate lua error.
|
||||
// returns Err. If the error is actually a WrappedPaic, clears the current lua
|
||||
// stack continues the panic. If the error on the top of the stack is actually
|
||||
// a WrappedError, just returns it. Otherwise, interprets the error as the
|
||||
// appropriate lua error.
|
||||
pub unsafe fn handle_error(state: *mut ffi::lua_State, err: c_int) -> LuaResult<()> {
|
||||
if err == ffi::LUA_OK || err == ffi::LUA_YIELD {
|
||||
Ok(())
|
||||
|
@ -126,12 +125,19 @@ pub unsafe fn handle_error(state: *mut ffi::lua_State, err: c_int) -> LuaResult<
|
|||
Err(pop_wrapped_error(state).unwrap())
|
||||
|
||||
} else if is_wrapped_panic(state, -1) {
|
||||
resume_unwind(pop_wrapped_panic(state).unwrap())
|
||||
let userdata = ffi::lua_touserdata(state, -1);
|
||||
let panic = &mut *(userdata as *mut WrappedPanic);
|
||||
resume_unwind(panic.0.take().expect(
|
||||
"internal error: panic was resumed twice",
|
||||
))
|
||||
|
||||
} else {
|
||||
let err_string =
|
||||
if let Some(s) = ffi::lua_tolstring(state, -1, ptr::null_mut()).as_ref() {
|
||||
CStr::from_ptr(s).to_str().unwrap().to_owned()
|
||||
CStr::from_ptr(s)
|
||||
.to_str()
|
||||
.unwrap_or_else(|_| "<unprintable error>")
|
||||
.to_owned()
|
||||
} else {
|
||||
"<unprintable error>".to_owned()
|
||||
};
|
||||
|
@ -227,7 +233,7 @@ pub unsafe fn pcall_with_traceback(
|
|||
ffi::luaL_traceback(state, state, ptr::null(), 0);
|
||||
let traceback = CStr::from_ptr(ffi::lua_tolstring(state, -1, ptr::null_mut()))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.unwrap_or_else(|_| "<could not capture traceback>")
|
||||
.to_owned();
|
||||
push_wrapped_error(state, LuaError::CallbackError(traceback, Arc::new(error)));
|
||||
} else if !is_wrapped_panic(state, 1) {
|
||||
|
@ -261,7 +267,7 @@ pub unsafe fn resume_with_traceback(
|
|||
ffi::luaL_traceback(from, state, ptr::null(), 0);
|
||||
let traceback = CStr::from_ptr(ffi::lua_tolstring(from, -1, ptr::null_mut()))
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.unwrap_or_else(|_| "<could not capture traceback>")
|
||||
.to_owned();
|
||||
push_wrapped_error(from, LuaError::CallbackError(traceback, Arc::new(error)));
|
||||
} else if !is_wrapped_panic(state, 1) {
|
||||
|
@ -321,8 +327,8 @@ pub unsafe fn main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State {
|
|||
state
|
||||
}
|
||||
|
||||
pub struct WrappedError(LuaError);
|
||||
pub struct WrappedPanic(Option<Box<Any + Send>>);
|
||||
pub struct WrappedError(pub LuaError);
|
||||
pub struct WrappedPanic(pub Option<Box<Any + Send>>);
|
||||
|
||||
// Pushes a WrappedError::Error to the top of the stack
|
||||
pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: LuaError) {
|
||||
|
@ -427,18 +433,6 @@ pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<LuaError>
|
|||
}
|
||||
}
|
||||
|
||||
// Pops a WrappedError off of the top of the stack, if it is a WrappedError. If
|
||||
// it is not a WrappedError, returns None and does not pop anything.
|
||||
pub unsafe fn pop_wrapped_panic(state: *mut ffi::lua_State) -> Option<Box<Any + Send>> {
|
||||
if ffi::lua_gettop(state) == 0 || !is_wrapped_panic(state, -1) {
|
||||
None
|
||||
} else {
|
||||
let userdata = ffi::lua_touserdata(state, -1);
|
||||
let panic = &mut *(userdata as *mut WrappedPanic);
|
||||
panic.0.take()
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the value at the given index is a WrappedError
|
||||
pub unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
|
||||
assert_ne!(
|
||||
|
|
Loading…
Reference in New Issue