Remove `stack_guard` function and instead just use StackGuard directly

This commit is contained in:
kyren 2018-03-12 13:13:44 -04:00
parent 7b2f7a2932
commit ee23f199f0
8 changed files with 526 additions and 562 deletions

View File

@ -170,9 +170,7 @@ fn create_registry_values(c: &mut Criterion) {
}
fn create_userdata(c: &mut Criterion) {
struct UserData {
i: i64,
}
struct UserData(i64);
impl LuaUserData for UserData {}
c.bench_function("create userdata 10", |b| {
@ -182,7 +180,7 @@ fn create_userdata(c: &mut Criterion) {
{
let table: LuaTable = lua.create_table().unwrap();
for i in 1..11 {
table.set(i, UserData { i }).unwrap();
table.set(i, UserData(i)).unwrap();
}
}
lua

View File

@ -4,7 +4,7 @@ use std::os::raw::c_int;
use ffi;
use error::{Error, Result};
use util::{check_stack, check_stack_err, error_traceback, pop_error, protect_lua_closure,
stack_guard};
StackGuard};
use types::LuaRef;
use value::{FromLuaMulti, MultiValue, ToLuaMulti};
@ -63,10 +63,12 @@ impl<'lua> Function<'lua> {
/// ```
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self, args: A) -> Result<R> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let args = args.to_lua_multi(lua)?;
let nargs = args.len() as c_int;
unsafe {
let _sg = StackGuard::new(lua.state);
check_stack_err(lua.state, nargs + 3)?;
ffi::lua_pushcfunction(lua.state, error_traceback);
@ -87,7 +89,6 @@ impl<'lua> Function<'lua> {
}
ffi::lua_pop(lua.state, 1);
R::from_lua_multi(results, lua)
})
}
}
@ -144,8 +145,7 @@ impl<'lua> Function<'lua> {
}
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let args = args.to_lua_multi(lua)?;
let nargs = args.len() as c_int;
@ -153,6 +153,8 @@ impl<'lua> Function<'lua> {
return Err(Error::BindError);
}
unsafe {
let _sg = StackGuard::new(lua.state);
check_stack_err(lua.state, nargs + 5)?;
lua.push_ref(&self.0);
ffi::lua_pushinteger(lua.state, nargs as ffi::lua_Integer);
@ -165,7 +167,6 @@ impl<'lua> Function<'lua> {
})?;
Ok(Function(lua.pop_ref()))
})
}
}
}

View File

@ -14,8 +14,8 @@ use ffi;
use error::{Error, Result};
use util::{callback_error, check_stack, check_stack_err, gc_guard, get_userdata,
get_wrapped_error, init_error_metatables, pop_error, protect_lua, protect_lua_closure,
push_string, push_userdata, push_wrapped_error, safe_pcall, safe_xpcall, stack_guard,
take_userdata, userdata_destructor};
push_string, push_userdata, push_wrapped_error, safe_pcall, safe_xpcall, take_userdata,
userdata_destructor, StackGuard};
use value::{FromLua, FromLuaMulti, MultiValue, Nil, ToLua, ToLuaMulti, Value};
use types::{Callback, Integer, LightUserData, LuaRef, Number, RefType, RegistryKey};
use string::String;
@ -102,7 +102,7 @@ impl Lua {
/// Equivalent to Lua's `load` function.
pub fn load(&self, source: &str, name: Option<&str>) -> Result<Function> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 1);
match if let Some(name) = name {
@ -129,7 +129,6 @@ impl Lua {
ffi::LUA_OK => Ok(Function(self.pop_ref())),
err => Err(pop_error(self.state, err)),
}
})
}
}
@ -167,18 +166,17 @@ impl Lua {
/// Pass a `&str` slice to Lua, creating and returning an interned Lua string.
pub fn create_string(&self, s: &str) -> Result<String> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4);
push_string(self.state, s)?;
Ok(String(self.pop_ref()))
})
}
}
/// Creates and returns a new table.
pub fn create_table(&self) -> Result<Table> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 3);
unsafe extern "C" fn new_table(state: *mut ffi::lua_State) -> c_int {
ffi::lua_newtable(state);
@ -186,7 +184,6 @@ impl Lua {
}
protect_lua(self.state, 0, new_table)?;
Ok(Table(self.pop_ref()))
})
}
}
@ -198,8 +195,9 @@ impl Lua {
I: IntoIterator<Item = (K, V)>,
{
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 5);
unsafe extern "C" fn new_table(state: *mut ffi::lua_State) -> c_int {
ffi::lua_newtable(state);
1
@ -216,7 +214,6 @@ impl Lua {
protect_lua(self.state, 3, raw_set)?;
}
Ok(Table(self.pop_ref()))
})
}
}
@ -322,7 +319,7 @@ impl Lua {
/// Equivalent to `coroutine.create`.
pub fn create_thread<'lua>(&'lua self, func: Function<'lua>) -> Result<Thread<'lua>> {
unsafe {
stack_guard(self.state, move || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
let thread_state =
@ -331,7 +328,6 @@ impl Lua {
ffi::lua_xmove(self.state, thread_state, 1);
Ok(Thread(self.pop_ref()))
})
}
}
@ -346,11 +342,10 @@ impl Lua {
/// Returns a handle to the global environment.
pub fn globals(&self) -> Table {
unsafe {
stack_guard(self.state, move || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
ffi::lua_rawgeti(self.state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
Table(self.pop_ref())
})
}
}
@ -392,13 +387,13 @@ impl Lua {
match v {
Value::String(s) => Ok(s),
v => unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4);
let ty = v.type_name();
self.push_value(v);
let s = protect_lua_closure(self.state, 1, 1, |state| {
ffi::lua_tostring(state, -1)
})?;
let s =
protect_lua_closure(self.state, 1, 1, |state| ffi::lua_tostring(state, -1))?;
if s.is_null() {
Err(Error::FromLuaConversionError {
from: ty,
@ -408,7 +403,6 @@ impl Lua {
} else {
Ok(String(self.pop_ref()))
}
})
},
}
}
@ -421,8 +415,9 @@ impl Lua {
match v {
Value::Integer(i) => Ok(i),
v => unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
let ty = v.type_name();
self.push_value(v);
let mut isint = 0;
@ -436,7 +431,6 @@ impl Lua {
} else {
Ok(i)
}
})
},
}
}
@ -449,8 +443,9 @@ impl Lua {
match v {
Value::Number(n) => Ok(n),
v => unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
let ty = v.type_name();
self.push_value(v);
let mut isnum = 0;
@ -464,7 +459,6 @@ impl Lua {
} else {
Ok(n)
}
})
},
}
}
@ -502,7 +496,7 @@ impl Lua {
t: T,
) -> Result<()> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 5);
push_string(self.state, name)?;
@ -513,7 +507,6 @@ impl Lua {
0
}
protect_lua(self.state, 2, set_registry)
})
}
}
@ -525,7 +518,7 @@ impl Lua {
/// [`set_named_registry_value`]: #method.set_named_registry_value
pub fn named_registry_value<'lua, T: FromLua<'lua>>(&'lua self, name: &str) -> Result<T> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4);
push_string(self.state, name)?;
@ -536,7 +529,6 @@ impl Lua {
protect_lua(self.state, 1, get_registry)?;
T::from_lua(self.pop_value(), self)
})
}
}
@ -555,7 +547,7 @@ impl Lua {
/// state.
pub fn create_registry_value<'lua, T: ToLua<'lua>>(&'lua self, t: T) -> Result<RegistryKey> {
unsafe {
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
self.push_value(t.to_lua(self)?);
@ -567,7 +559,6 @@ impl Lua {
registry_id,
unref_list: (*self.extra()).registry_unref_list.clone(),
})
})
}
}
@ -583,15 +574,15 @@ impl Lua {
return Err(Error::MismatchedRegistryKey);
}
stack_guard(self.state, || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 2);
ffi::lua_rawgeti(
self.state,
ffi::LUA_REGISTRYINDEX,
key.registry_id as ffi::lua_Integer,
);
T::from_lua(self.pop_value(), self)
})
}
}
@ -883,11 +874,11 @@ impl Lua {
}
}
stack_guard(self.state, move || {
if let Some(table_id) = (*self.extra()).registered_userdata.get(&TypeId::of::<T>()) {
return Ok(*table_id);
}
let _sg = StackGuard::new(self.state);
check_stack(self.state, 6);
let mut methods = UserDataMethods {
@ -988,7 +979,6 @@ impl Lua {
.registered_userdata
.insert(TypeId::of::<T>(), id);
Ok(id)
})
}
unsafe fn create_lua(load_debug: bool) -> Lua {
@ -1125,7 +1115,7 @@ impl Lua {
}
unsafe {
stack_guard(self.state, move || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4);
push_userdata::<Callback>(self.state, func)?;
@ -1142,7 +1132,6 @@ impl Lua {
})?;
Ok(Function(self.pop_ref()))
})
}
}
@ -1151,7 +1140,7 @@ impl Lua {
T: UserData,
{
unsafe {
stack_guard(self.state, move || {
let _sg = StackGuard::new(self.state);
check_stack(self.state, 4);
push_userdata::<RefCell<T>>(self.state, RefCell::new(data))?;
@ -1165,7 +1154,6 @@ impl Lua {
ffi::lua_setmetatable(self.state, -2);
Ok(AnyUserData(self.pop_ref()))
})
}
}
@ -1290,7 +1278,7 @@ impl<'scope> Scope<'scope> {
let f_destruct = f.0.clone();
destructors.push(Box::new(move || {
let state = f_destruct.lua.state;
stack_guard(state, || {
let _sg = StackGuard::new(state);
check_stack(state, 2);
f_destruct.lua.push_ref(&f_destruct);
@ -1302,7 +1290,6 @@ impl<'scope> Scope<'scope> {
ffi::lua_pop(state, 1);
Box::new(ud)
})
}));
Ok(f)
}
@ -1348,11 +1335,10 @@ impl<'scope> Scope<'scope> {
let u_destruct = u.0.clone();
destructors.push(Box::new(move || {
let state = u_destruct.lua.state;
stack_guard(state, || {
let _sg = StackGuard::new(state);
check_stack(state, 1);
u_destruct.lua.push_ref(&u_destruct);
Box::new(take_userdata::<RefCell<T>>(state))
})
}));
Ok(u)
}

View File

@ -2,7 +2,7 @@ use std::{slice, str};
use ffi;
use error::{Error, Result};
use util::{check_stack, stack_guard};
use util::{check_stack, StackGuard};
use types::LuaRef;
/// Handle to an internal Lua string.
@ -69,8 +69,9 @@ impl<'lua> String<'lua> {
pub fn as_bytes_with_nul(&self) -> &[u8] {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
rlua_assert!(
ffi::lua_type(lua.state, -1) == ffi::LUA_TSTRING,
@ -83,7 +84,6 @@ impl<'lua> String<'lua> {
let data = ffi::lua_tolstring(lua.state, -1, &mut size);
slice::from_raw_parts(data as *const u8, size + 1)
})
}
}
}

View File

@ -3,7 +3,7 @@ use std::os::raw::c_int;
use ffi;
use error::Result;
use util::{check_stack, protect_lua, protect_lua_closure, stack_guard};
use util::{check_stack, protect_lua, protect_lua_closure, StackGuard};
use types::{Integer, LuaRef, RefType};
use value::{FromLua, ToLua};
@ -52,8 +52,9 @@ impl<'lua> Table<'lua> {
pub fn set<K: ToLua<'lua>, V: ToLua<'lua>>(&self, key: K, value: V) -> Result<()> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 6);
lua.push_ref(&self.0);
lua.push_value(key.to_lua(lua)?);
lua.push_value(value.to_lua(lua)?);
@ -63,7 +64,6 @@ impl<'lua> Table<'lua> {
1
}
protect_lua(lua.state, 3, set_table)
})
}
}
@ -98,8 +98,9 @@ impl<'lua> Table<'lua> {
pub fn get<K: ToLua<'lua>, V: FromLua<'lua>>(&self, key: K) -> Result<V> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 5);
lua.push_ref(&self.0);
lua.push_value(key.to_lua(lua)?);
@ -110,7 +111,6 @@ impl<'lua> Table<'lua> {
protect_lua(lua.state, 2, get_table)?;
V::from_lua(lua.pop_value(), lua)
})
}
}
@ -118,8 +118,9 @@ impl<'lua> Table<'lua> {
pub fn contains_key<K: ToLua<'lua>>(&self, key: K) -> Result<bool> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 5);
lua.push_ref(&self.0);
lua.push_value(key.to_lua(lua)?);
@ -131,7 +132,6 @@ impl<'lua> Table<'lua> {
let has = ffi::lua_isnil(lua.state, -1) == 0;
Ok(has)
})
}
}
@ -139,8 +139,9 @@ impl<'lua> Table<'lua> {
pub fn raw_set<K: ToLua<'lua>, V: ToLua<'lua>>(&self, key: K, value: V) -> Result<()> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 6);
lua.push_ref(&self.0);
lua.push_value(key.to_lua(lua)?);
lua.push_value(value.to_lua(lua)?);
@ -152,7 +153,6 @@ impl<'lua> Table<'lua> {
protect_lua(lua.state, 3, raw_set)?;
Ok(())
})
}
}
@ -160,14 +160,14 @@ impl<'lua> Table<'lua> {
pub fn raw_get<K: ToLua<'lua>, V: FromLua<'lua>>(&self, key: K) -> Result<V> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 3);
lua.push_ref(&self.0);
lua.push_value(key.to_lua(lua)?);
ffi::lua_rawget(lua.state, -2);
let res = V::from_lua(lua.pop_value(), lua)?;
Ok(res)
})
}
}
@ -179,11 +179,10 @@ impl<'lua> Table<'lua> {
pub fn len(&self) -> Result<Integer> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 4);
lua.push_ref(&self.0);
protect_lua_closure(lua.state, 1, 0, |state| ffi::luaL_len(state, -1))
})
}
}
@ -191,12 +190,11 @@ impl<'lua> Table<'lua> {
pub fn raw_len(&self) -> Integer {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
let len = ffi::lua_rawlen(lua.state, -1);
len as Integer
})
}
}
@ -206,7 +204,7 @@ impl<'lua> Table<'lua> {
pub fn get_metatable(&self) -> Option<Table<'lua>> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
if ffi::lua_getmetatable(lua.state, -1) == 0 {
@ -215,7 +213,6 @@ impl<'lua> Table<'lua> {
let table = Table(lua.pop_ref());
Some(table)
}
})
}
}
@ -226,7 +223,7 @@ impl<'lua> Table<'lua> {
pub fn set_metatable(&self, metatable: Option<Table<'lua>>) {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, move || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
if let Some(metatable) = metatable {
@ -235,7 +232,6 @@ impl<'lua> Table<'lua> {
ffi::lua_pushnil(lua.state);
}
ffi::lua_setmetatable(lua.state, -2);
})
}
}
@ -359,7 +355,7 @@ where
let lua = self.table.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 6);
lua.push_ref(&self.table);
@ -383,7 +379,6 @@ where
}
Err(e) => Some(Err(e)),
}
})
}
} else {
None
@ -413,13 +408,12 @@ where
let lua = self.table.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 5);
lua.push_ref(&self.table);
match protect_lua_closure(lua.state, 1, 1, |state| {
ffi::lua_geti(state, -1, index)
}) {
match protect_lua_closure(lua.state, 1, 1, |state| ffi::lua_geti(state, -1, index))
{
Ok(ffi::LUA_TNIL) => None,
Ok(_) => {
let value = lua.pop_value();
@ -428,7 +422,6 @@ where
}
Err(err) => Some(Err(err)),
}
})
}
} else {
None

View File

@ -2,7 +2,7 @@ use std::os::raw::c_int;
use ffi;
use error::{Error, Result};
use util::{check_stack, check_stack_err, error_traceback, pop_error, stack_guard};
use util::{check_stack, check_stack_err, error_traceback, pop_error, StackGuard};
use types::LuaRef;
use value::{FromLuaMulti, MultiValue, ToLuaMulti};
@ -78,7 +78,7 @@ impl<'lua> Thread<'lua> {
{
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
@ -116,7 +116,6 @@ impl<'lua> Thread<'lua> {
results.push_front(lua.pop_value());
}
R::from_lua_multi(results, lua)
})
}
}
@ -124,7 +123,7 @@ impl<'lua> Thread<'lua> {
pub fn status(&self) -> ThreadStatus {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 1);
lua.push_ref(&self.0);
@ -139,7 +138,6 @@ impl<'lua> Thread<'lua> {
} else {
ThreadStatus::Unresumable
}
})
}
}
}

View File

@ -5,7 +5,7 @@ use std::string::String as StdString;
use ffi;
use error::{Error, Result};
use util::{check_stack, get_userdata, stack_guard};
use util::{check_stack, get_userdata, StackGuard};
use types::{Callback, LuaRef};
use value::{FromLua, FromLuaMulti, ToLua, ToLuaMulti};
use lua::Lua;
@ -415,7 +415,7 @@ impl<'lua> AnyUserData<'lua> {
{
unsafe {
let lua = self.0.lua;
stack_guard(lua.state, move || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 3);
lua.push_ref(&self.0);
@ -437,7 +437,6 @@ impl<'lua> AnyUserData<'lua> {
let res = func(&*get_userdata::<RefCell<T>>(lua.state, -3));
res
}
})
}
}
@ -449,13 +448,12 @@ impl<'lua> AnyUserData<'lua> {
pub fn set_user_value<V: ToLua<'lua>>(&self, v: V) -> Result<()> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 2);
lua.push_ref(&self.0);
lua.push_value(v.to_lua(lua)?);
ffi::lua_setuservalue(lua.state, -2);
Ok(())
})
}
}
@ -465,13 +463,12 @@ impl<'lua> AnyUserData<'lua> {
pub fn get_user_value<V: FromLua<'lua>>(&self) -> Result<V> {
let lua = self.0.lua;
unsafe {
stack_guard(lua.state, || {
let _sg = StackGuard::new(lua.state);
check_stack(lua.state, 3);
lua.push_ref(&self.0);
ffi::lua_getuservalue(lua.state, -1);
let res = V::from_lua(lua.pop_value(), lua)?;
Ok(res)
})
}
}
}

View File

@ -57,15 +57,6 @@ impl Drop for StackGuard {
}
}
// Run an operation on a lua_State and restores the stack state at the end, using `StackGuard`.
pub unsafe fn stack_guard<F, R>(state: *mut ffi::lua_State, op: F) -> R
where
F: FnOnce() -> R,
{
let _stack_guard = StackGuard::new(state);
op()
}
// Call a function that calls into the Lua API and may trigger a Lua error (longjmp) in a safe way.
// Wraps the inner function in a call to `lua_pcall`, so the inner function only has access to a
// limited lua stack. `nargs` is the same as the the parameter to `lua_pcall`, and `nresults` is