Skip to content

Commit

Permalink
Provisional "fix" for #71. Requires nightly :(
Browse files Browse the repository at this point in the history
  • Loading branch information
kyren committed Feb 16, 2018
1 parent 6b46e8a commit f0186d1
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ default = ["builtin-lua"]
# * LUA_NUMBER as double
# * LUA_EXTRASPACE is sizeof(void*)
builtin-lua = ["gcc"]
# Error handling is completely broken on windows with
# https://github.com/rust-lang/rust/pull/46833 merged, and this includes stable
# rustc 1.24.0+. This feature fixes error handling on windows, but requires
# nightly! See https://github.com/rust-lang/rust/issues/48251 and
# https://github.com/chucklefish/rlua/issues/71 for details.
unwind = []

[dependencies]
libc = { version = "0.2" }
Expand Down
1 change: 1 addition & 0 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ impl<'lua> Function<'lua> {
/// # }
/// ```
pub fn bind<A: ToLuaMulti<'lua>>(&self, args: A) -> Result<Function<'lua>> {
#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn bind_call_impl(state: *mut ffi::lua_State) -> c_int {
let nargs = ffi::lua_gettop(state);
let nbinds = ffi::lua_tointeger(state, ffi::lua_upvalueindex(2)) as c_int;
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![cfg_attr(feature = "unwind", feature(unwind_attributes))]

//! # High-level bindings to Lua
//!
//! The `rlua` crate provides safe high-level bindings to the [Lua programming language].
Expand Down
2 changes: 2 additions & 0 deletions src/lua.rs
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,7 @@ impl Lua {
pub(crate) unsafe fn userdata_metatable<T: UserData>(&self) -> Result<c_int> {
// Used if both an __index metamethod is set and regular methods, checks methods table
// first, then __index metamethod.
#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn meta_index_impl(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());

Expand Down Expand Up @@ -994,6 +995,7 @@ impl Lua {
&'lua self,
func: Callback<'callback, 'static>,
) -> Result<Function<'lua>> {
#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn callback_call_impl(state: *mut ffi::lua_State) -> c_int {
callback_error(state, || {
let lua = Lua {
Expand Down
12 changes: 11 additions & 1 deletion src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ where
// limited lua stack. `nargs` and `nresults` are similar to the parameters of `lua_pcall`, but the
// given function return type is not the return value count, instead the inner function return
// values are assumed to match the `nresults` param. Internally uses 3 extra stack spaces, and does
// not call checkstack.
// not call checkstack. Provided function must *not* panic.
pub unsafe fn protect_lua_call<F, R>(
state: *mut ffi::lua_State,
nargs: c_int,
Expand All @@ -121,6 +121,7 @@ where
nresults: c_int,
}

#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn do_call<F, R>(state: *mut ffi::lua_State) -> c_int
where
F: FnOnce(*mut ffi::lua_State) -> R,
Expand Down Expand Up @@ -271,6 +272,7 @@ pub unsafe fn take_userdata<T>(state: *mut ffi::lua_State) -> T {
ptr::read(ud)
}

#[cfg_attr(feature = "unwind", unwind)]
pub unsafe extern "C" fn userdata_destructor<T>(state: *mut ffi::lua_State) -> c_int {
callback_error(state, || {
take_userdata::<T>(state);
Expand All @@ -291,11 +293,13 @@ where
Ok(Err(err)) => {
ffi::luaL_checkstack(state, 2, ptr::null());
push_wrapped_error(state, err);
println!("erroring...");
ffi::lua_error(state)
}
Err(p) => {
ffi::luaL_checkstack(state, 2, ptr::null());
push_wrapped_panic(state, p);
println!("erroring...");
ffi::lua_error(state)
}
}
Expand All @@ -304,6 +308,7 @@ where
// Takes an error at the top of the stack, and if it is a WrappedError, converts it to an
// Error::CallbackError with a traceback, if it is some lua type, prints the error along with a
// traceback, and if it is a WrappedPanic, does not modify it.
#[cfg_attr(feature = "unwind", unwind)]
pub unsafe extern "C" fn error_traceback(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());

Expand Down Expand Up @@ -334,6 +339,7 @@ pub unsafe extern "C" fn error_traceback(state: *mut ffi::lua_State) -> c_int {
}

// A variant of pcall that does not allow lua to catch panic errors from callback_error
#[cfg_attr(feature = "unwind", unwind)]
pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());

Expand All @@ -356,7 +362,9 @@ pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int {
}

// A variant of xpcall that does not allow lua to catch panic errors from callback_error
#[cfg_attr(feature = "unwind", unwind)]
pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn xpcall_msgh(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());

Expand Down Expand Up @@ -504,6 +512,7 @@ unsafe fn is_wrapped_panic(state: *mut ffi::lua_State, index: c_int) -> bool {
unsafe fn get_error_metatable(state: *mut ffi::lua_State) -> c_int {
static ERROR_METATABLE_REGISTRY_KEY: u8 = 0;

#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn error_tostring(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());

Expand Down Expand Up @@ -605,6 +614,7 @@ unsafe fn get_panic_metatable(state: *mut ffi::lua_State) -> c_int {
unsafe fn get_destructed_userdata_metatable(state: *mut ffi::lua_State) -> c_int {
static DESTRUCTED_USERDATA_METATABLE: u8 = 0;

#[cfg_attr(feature = "unwind", unwind)]
unsafe extern "C" fn destructed_error(state: *mut ffi::lua_State) -> c_int {
ffi::luaL_checkstack(state, 2, ptr::null());
push_wrapped_error(state, Error::CallbackDestructed);
Expand Down

0 comments on commit f0186d1

Please sign in to comment.