still making small structural changes
slowly trying to refactor things until using all the protected calls in protected_ffi is workable
This commit is contained in:
parent
f51a822738
commit
5742e3f20a
73
src/util.rs
73
src/util.rs
|
@ -312,15 +312,10 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ffi::lua_pcall with a message handler that gives a nice traceback. If the
|
// Takes an error at the top of the stack, and if it is a WrappedError, converts it to an
|
||||||
// caught error is actually a Error, will simply pass the error along. Does
|
// Error::CallbackError with a traceback. If it is a lua error, creates a new string error with a
|
||||||
// not call checkstack, and uses 2 extra stack spaces.
|
// printed traceback, and if it is a WrappedPanic, does not modify it.
|
||||||
pub unsafe fn pcall_with_traceback(
|
pub unsafe extern "C" fn error_traceback(state: *mut ffi::lua_State) -> c_int {
|
||||||
state: *mut ffi::lua_State,
|
|
||||||
nargs: c_int,
|
|
||||||
nresults: c_int,
|
|
||||||
) -> c_int {
|
|
||||||
unsafe extern "C" fn message_handler(state: *mut ffi::lua_State) -> c_int {
|
|
||||||
if let Some(error) = pop_wrapped_error(state) {
|
if let Some(error) = pop_wrapped_error(state) {
|
||||||
ffi::luaL_traceback(state, state, ptr::null(), 0);
|
ffi::luaL_traceback(state, state, ptr::null(), 0);
|
||||||
let traceback = CStr::from_ptr(ffi::lua_tolstring(state, -1, ptr::null_mut()))
|
let traceback = CStr::from_ptr(ffi::lua_tolstring(state, -1, ptr::null_mut()))
|
||||||
|
@ -347,8 +342,16 @@ pub unsafe fn pcall_with_traceback(
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ffi::lua_pcall with a message handler that gives a nice traceback. If the
|
||||||
|
// caught error is actually a Error, will simply pass the error along. Does
|
||||||
|
// not call checkstack, and uses 2 extra stack spaces.
|
||||||
|
pub unsafe fn pcall_with_traceback(
|
||||||
|
state: *mut ffi::lua_State,
|
||||||
|
nargs: c_int,
|
||||||
|
nresults: c_int,
|
||||||
|
) -> c_int {
|
||||||
let msgh_position = ffi::lua_gettop(state) - nargs;
|
let msgh_position = ffi::lua_gettop(state) - nargs;
|
||||||
ffi::lua_pushcfunction(state, message_handler);
|
ffi::lua_pushcfunction(state, error_traceback);
|
||||||
ffi::lua_insert(state, msgh_position);
|
ffi::lua_insert(state, msgh_position);
|
||||||
let ret = ffi::lua_pcall(state, nargs, nresults, msgh_position);
|
let ret = ffi::lua_pcall(state, nargs, nresults, msgh_position);
|
||||||
ffi::lua_remove(state, msgh_position);
|
ffi::lua_remove(state, msgh_position);
|
||||||
|
@ -362,29 +365,7 @@ pub unsafe fn resume_with_traceback(
|
||||||
) -> c_int {
|
) -> c_int {
|
||||||
let res = ffi::lua_resume(state, from, nargs);
|
let res = ffi::lua_resume(state, from, nargs);
|
||||||
if res != ffi::LUA_OK && res != ffi::LUA_YIELD {
|
if res != ffi::LUA_OK && res != ffi::LUA_YIELD {
|
||||||
if let Some(error) = pop_wrapped_error(state) {
|
error_traceback(state);
|
||||||
ffi::luaL_traceback(state, state, ptr::null(), 0);
|
|
||||||
let traceback = CStr::from_ptr(ffi::lua_tolstring(state, -1, ptr::null_mut()))
|
|
||||||
.to_str()
|
|
||||||
.unwrap_or_else(|_| "<could not capture traceback>")
|
|
||||||
.to_owned();
|
|
||||||
push_wrapped_error(
|
|
||||||
state,
|
|
||||||
Error::CallbackError {
|
|
||||||
traceback,
|
|
||||||
cause: Arc::new(error),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
ffi::lua_remove(state, -2);
|
|
||||||
} else if !is_wrapped_panic(state, 1) {
|
|
||||||
let s = ffi::lua_tolstring(state, 1, ptr::null_mut());
|
|
||||||
if !s.is_null() {
|
|
||||||
ffi::luaL_traceback(state, state, s, 0);
|
|
||||||
} else {
|
|
||||||
ffi::luaL_traceback(state, state, cstr!("<unprintable lua error>"), 0);
|
|
||||||
}
|
|
||||||
ffi::lua_remove(state, -2);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
@ -493,9 +474,6 @@ pub unsafe fn main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State {
|
||||||
main_state
|
main_state
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WrappedError(pub Error);
|
|
||||||
pub struct WrappedPanic(pub Option<Box<Any + Send>>);
|
|
||||||
|
|
||||||
// Pushes a WrappedError::Error to the top of the stack
|
// Pushes a WrappedError::Error to the top of the stack
|
||||||
pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: Error) {
|
pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: Error) {
|
||||||
ffi::luaL_checkstack(state, 2, ptr::null());
|
ffi::luaL_checkstack(state, 2, ptr::null());
|
||||||
|
@ -506,16 +484,6 @@ pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: Error) {
|
||||||
ffi::lua_setmetatable(state, -2);
|
ffi::lua_setmetatable(state, -2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pushes a WrappedError::Panic to the top of the stack
|
|
||||||
pub unsafe fn push_wrapped_panic(state: *mut ffi::lua_State, panic: Box<Any + Send>) {
|
|
||||||
ffi::luaL_checkstack(state, 2, ptr::null());
|
|
||||||
|
|
||||||
push_userdata(state, WrappedPanic(Some(panic)));
|
|
||||||
|
|
||||||
get_panic_metatable(state);
|
|
||||||
ffi::lua_setmetatable(state, -2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pops a WrappedError off of the top of the stack, if it is a WrappedError. If
|
// 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.
|
// it is not a WrappedError, returns None and does not pop anything.
|
||||||
pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<Error> {
|
pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<Error> {
|
||||||
|
@ -529,6 +497,19 @@ pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct WrappedError(pub Error);
|
||||||
|
struct WrappedPanic(pub Option<Box<Any + Send>>);
|
||||||
|
|
||||||
|
// Pushes a WrappedError::Panic to the top of the stack
|
||||||
|
unsafe fn push_wrapped_panic(state: *mut ffi::lua_State, panic: Box<Any + Send>) {
|
||||||
|
ffi::luaL_checkstack(state, 2, ptr::null());
|
||||||
|
|
||||||
|
push_userdata(state, WrappedPanic(Some(panic)));
|
||||||
|
|
||||||
|
get_panic_metatable(state);
|
||||||
|
ffi::lua_setmetatable(state, -2);
|
||||||
|
}
|
||||||
|
|
||||||
// Checks if the value at the given index is a WrappedError
|
// Checks if the value at the given index is a WrappedError
|
||||||
unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
|
unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
|
||||||
assert_ne!(
|
assert_ne!(
|
||||||
|
|
Loading…
Reference in New Issue