Always ensure LUA_MINSTACK available stack spaces on callback
Otherwise, cleanly error with an appropriate stack error. Part of an effort to ensure that it should not be possible to trigger a stack space assert.
This commit is contained in:
parent
4b6809c766
commit
0d5e45e800
|
@ -53,6 +53,7 @@ pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXSTACK - 1000;
|
|||
pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1;
|
||||
pub const LUA_RIDX_GLOBALS: lua_Integer = 2;
|
||||
pub const LUA_IDSIZE: c_int = 60;
|
||||
pub const LUA_MINSTACK: c_int = 20;
|
||||
// Not actually defined in lua.h / luaconf.h
|
||||
pub const LUA_MAX_UPVALUES: c_int = 255;
|
||||
|
||||
|
|
24
src/lua.rs
24
src/lua.rs
|
@ -1013,15 +1013,13 @@ impl Lua {
|
|||
ref_stack_slots: Default::default(),
|
||||
};
|
||||
|
||||
let args = lua.setup_callback_stack_slots();
|
||||
|
||||
let args = lua.setup_callback_stack()?;
|
||||
let func = get_userdata::<Callback>(state, ffi::lua_upvalueindex(1));
|
||||
|
||||
let results = (*func)(&lua, args)?;
|
||||
let nresults = results.len() as c_int;
|
||||
|
||||
check_stack_err(state, nresults)?;
|
||||
|
||||
for r in results {
|
||||
lua.push_value(r);
|
||||
}
|
||||
|
@ -1175,8 +1173,9 @@ impl Lua {
|
|||
}
|
||||
|
||||
// Set up the stack slot area in a callback, returning all arguments on the stack as a
|
||||
// MultiValue
|
||||
fn setup_callback_stack_slots<'lua>(&'lua self) -> MultiValue<'lua> {
|
||||
// MultiValue. Also ensures that at least LUA_MINSTACK extra stack slots are available for use
|
||||
// in the callback.
|
||||
fn setup_callback_stack<'lua>(&'lua self) -> Result<MultiValue<'lua>> {
|
||||
unsafe {
|
||||
check_stack(self.state, 2);
|
||||
|
||||
|
@ -1243,15 +1242,19 @@ impl Lua {
|
|||
args.push_front(Value::Thread(Thread(make_ref())));
|
||||
}
|
||||
|
||||
_ => rlua_panic!("LUA_TNONE in setup_callback_stack_slots"),
|
||||
_ => rlua_panic!("LUA_TNONE in setup_callback_stack"),
|
||||
}
|
||||
}
|
||||
|
||||
if nargs < REF_STACK_SIZE {
|
||||
check_stack(self.state, REF_STACK_SIZE - nargs);
|
||||
check_stack_err(self.state, REF_STACK_SIZE - nargs + ffi::LUA_MINSTACK)?;
|
||||
ffi::lua_settop(self.state, REF_STACK_SIZE);
|
||||
args
|
||||
Ok(args)
|
||||
} else if nargs > REF_STACK_SIZE {
|
||||
if nargs - REF_STACK_SIZE < ffi::LUA_MINSTACK {
|
||||
check_stack_err(self.state, ffi::LUA_MINSTACK - (nargs - REF_STACK_SIZE))?;
|
||||
}
|
||||
|
||||
// If the total number of arguments exceeds the ref stack area, pop off the rest of
|
||||
// the arguments as normal.
|
||||
let mut extra_args = Vec::new();
|
||||
|
@ -1260,9 +1263,10 @@ impl Lua {
|
|||
extra_args.push(self.pop_value());
|
||||
}
|
||||
extra_args.extend(args.into_vec_rev());
|
||||
MultiValue::from_vec_rev(extra_args)
|
||||
Ok(MultiValue::from_vec_rev(extra_args))
|
||||
} else {
|
||||
args
|
||||
check_stack_err(self.state, ffi::LUA_MINSTACK)?;
|
||||
Ok(args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue