summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml3
-rw-r--r--src/function.rs2
-rw-r--r--src/lua.rs13
-rw-r--r--src/string.rs6
-rw-r--r--src/table.rs4
-rw-r--r--src/thread.rs2
-rw-r--r--src/userdata.rs2
-rw-r--r--src/util.rs38
8 files changed, 34 insertions, 36 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 3d93404..3f07e6e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -32,5 +32,4 @@ compiletest_rs = { version = "0.3", optional = true }
gcc = { version = "0.3.52", optional = true }
[dev-dependencies]
-rustyline = "1.0.0"
-
+rustyline = "1.0.0" \ No newline at end of file
diff --git a/src/function.rs b/src/function.rs
index c268de3..97906a3 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -80,7 +80,7 @@ impl<'lua> Function<'lua> {
}
let nresults = ffi::lua_gettop(lua.state) - stack_start;
let mut results = MultiValue::new();
- check_stack(lua.state, 1);
+ check_stack(lua.state, 2);
for _ in 0..nresults {
results.push_front(lua.pop_value(lua.state));
}
diff --git a/src/lua.rs b/src/lua.rs
index 65d03d9..f0722f9 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -565,7 +565,7 @@ impl Lua {
}
stack_err_guard(self.state, 0, || {
- check_stack(self.state, 1);
+ check_stack(self.state, 2);
ffi::lua_rawgeti(
self.state,
ffi::LUA_REGISTRYINDEX,
@@ -672,7 +672,7 @@ impl Lua {
}
}
- // Uses 1 stack space, does not call checkstack
+ // Uses 2 stack spaces, does not call checkstack
pub(crate) unsafe fn pop_value(&self, state: *mut ffi::lua_State) -> Value {
match ffi::lua_type(state, -1) {
ffi::LUA_TNIL => {
@@ -709,10 +709,9 @@ impl Lua {
ffi::LUA_TFUNCTION => Value::Function(Function(self.pop_ref(state))),
ffi::LUA_TUSERDATA => {
- // It should not be possible to interact with userdata types
- // other than custom UserData types OR a WrappedError.
- // WrappedPanic should never be able to be caught in lua, so it
- // should never be here.
+ // It should not be possible to interact with userdata types other than custom
+ // UserData types OR a WrappedError. WrappedPanic should never be able to be caught
+ // in lua, so it should never be here.
if let Some(err) = pop_wrapped_error(state) {
Value::Error(err)
} else {
@@ -1011,7 +1010,7 @@ impl Lua {
let nargs = ffi::lua_gettop(state);
let mut args = MultiValue::new();
- check_stack(state, 1);
+ check_stack(state, 2);
for _ in 0..nargs {
args.push_front(lua.pop_value(state));
}
diff --git a/src/string.rs b/src/string.rs
index 5eda24a..31e937b 100644
--- a/src/string.rs
+++ b/src/string.rs
@@ -72,7 +72,11 @@ impl<'lua> String<'lua> {
stack_guard(lua.state, 0, || {
check_stack(lua.state, 1);
lua.push_ref(lua.state, &self.0);
- assert_eq!(ffi::lua_type(lua.state, -1), ffi::LUA_TSTRING);
+ lua_internal_assert!(
+ lua.state,
+ ffi::lua_type(lua.state, -1) == ffi::LUA_TSTRING,
+ "string ref is not string type"
+ );
let mut size = 0;
// This will not trigger a 'm' error, because the reference is guaranteed to be of
diff --git a/src/table.rs b/src/table.rs
index afac271..adf156d 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -347,7 +347,7 @@ where
unsafe {
stack_guard(lua.state, 0, || {
- check_stack(lua.state, 5);
+ check_stack(lua.state, 6);
lua.push_ref(lua.state, &self.table);
lua.push_ref(lua.state, &next_key);
@@ -409,7 +409,7 @@ where
unsafe {
stack_guard(lua.state, 0, || {
- check_stack(lua.state, 4);
+ check_stack(lua.state, 5);
lua.push_ref(lua.state, &self.table);
match protect_lua_call(lua.state, 1, 1, |state| ffi::lua_geti(state, -1, index))
diff --git a/src/thread.rs b/src/thread.rs
index d775827..ab5b97a 100644
--- a/src/thread.rs
+++ b/src/thread.rs
@@ -107,7 +107,7 @@ impl<'lua> Thread<'lua> {
let nresults = ffi::lua_gettop(thread_state);
let mut results = MultiValue::new();
- check_stack(thread_state, 1);
+ check_stack(thread_state, 2);
for _ in 0..nresults {
results.push_front(lua.pop_value(thread_state));
}
diff --git a/src/userdata.rs b/src/userdata.rs
index 7929de5..e29aa59 100644
--- a/src/userdata.rs
+++ b/src/userdata.rs
@@ -470,7 +470,7 @@ impl<'lua> AnyUserData<'lua> {
let lua = self.0.lua;
unsafe {
stack_err_guard(lua.state, 0, || {
- check_stack(lua.state, 2);
+ check_stack(lua.state, 3);
lua.push_ref(lua.state, &self.0);
ffi::lua_getuservalue(lua.state, -1);
let res = V::from_lua(lua.pop_value(lua.state), lua)?;
diff --git a/src/util.rs b/src/util.rs
index a56f132..660c058 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -179,6 +179,7 @@ where
// Pops an error off of the stack and returns it. If the error is actually a WrappedPanic, clears
// the current lua stack and 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.
+// Uses 2 stack spaces, does not call lua_checkstack.
pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error {
lua_internal_assert!(
state,
@@ -334,6 +335,8 @@ 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
pub unsafe extern "C" fn safe_pcall(state: *mut ffi::lua_State) -> c_int {
+ ffi::luaL_checkstack(state, 2, ptr::null());
+
let top = ffi::lua_gettop(state);
if top == 0 {
ffi::lua_pushstring(state, cstr!("not enough arguments to pcall"));
@@ -355,6 +358,8 @@ 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
pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
unsafe extern "C" fn xpcall_msgh(state: *mut ffi::lua_State) -> c_int {
+ ffi::luaL_checkstack(state, 2, ptr::null());
+
if is_wrapped_panic(state, -1) {
1
} else {
@@ -365,6 +370,8 @@ pub unsafe extern "C" fn safe_xpcall(state: *mut ffi::lua_State) -> c_int {
}
}
+ ffi::luaL_checkstack(state, 2, ptr::null());
+
let top = ffi::lua_gettop(state);
if top < 2 {
ffi::lua_pushstring(state, cstr!("not enough arguments to xpcall"));
@@ -411,10 +418,11 @@ pub unsafe fn push_wrapped_error(state: *mut ffi::lua_State, err: Error) {
ffi::lua_setmetatable(state, -2);
}
-// 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.
+// 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. Uses 2 stack spaces and does not call
+// lua_checkstack
pub unsafe fn pop_wrapped_error(state: *mut ffi::lua_State) -> Option<Error> {
- if ffi::lua_gettop(state) == 0 || !is_wrapped_error(state, -1) {
+ if !is_wrapped_error(state, -1) {
None
} else {
let err = &*get_userdata::<WrappedError>(state, -1);
@@ -456,16 +464,9 @@ unsafe fn push_wrapped_panic(state: *mut ffi::lua_State, panic: Box<Any + Send>)
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, uses 2 stack spaces and does not call
+// lua_checkstack.
unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
- assert_ne!(
- ffi::lua_checkstack(state, 2),
- 0,
- "somehow not enough stack space to check if a value is a WrappedError"
- );
-
- let index = ffi::lua_absindex(state, index);
-
let userdata = ffi::lua_touserdata(state, index);
if userdata.is_null() {
return false;
@@ -481,16 +482,9 @@ unsafe fn is_wrapped_error(state: *mut ffi::lua_State, index: c_int) -> bool {
res
}
-// Checks if the value at the given index is a WrappedPanic
+// Checks if the value at the given index is a WrappedPanic. Uses 2 stack spaces and does not call
+// lua_checkstack.
unsafe fn is_wrapped_panic(state: *mut ffi::lua_State, index: c_int) -> bool {
- assert_ne!(
- ffi::lua_checkstack(state, 2),
- 0,
- "somehow not enough stack space to check if a value is a wrapped panic"
- );
-
- let index = ffi::lua_absindex(state, index);
-
let userdata = ffi::lua_touserdata(state, index);
if userdata.is_null() {
return false;
@@ -510,6 +504,8 @@ unsafe fn get_error_metatable(state: *mut ffi::lua_State) -> c_int {
static ERROR_METATABLE_REGISTRY_KEY: u8 = 0;
unsafe extern "C" fn error_tostring(state: *mut ffi::lua_State) -> c_int {
+ ffi::luaL_checkstack(state, 2, ptr::null());
+
callback_error(state, || {
if is_wrapped_error(state, -1) {
let error = get_userdata::<WrappedError>(state, -1);