summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benches/benchmark.rs6
-rw-r--r--src/function.rs93
-rw-r--r--src/lua.rs566
-rw-r--r--src/string.rs28
-rw-r--r--src/table.rs243
-rw-r--r--src/thread.rs90
-rw-r--r--src/userdata.rs65
-rw-r--r--src/util.rs9
8 files changed, 532 insertions, 568 deletions
diff --git a/benches/benchmark.rs b/benches/benchmark.rs
index f3d0e9f..9a1f083 100644
--- a/benches/benchmark.rs
+++ b/benches/benchmark.rs
@@ -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
diff --git a/src/function.rs b/src/function.rs
index 0f97dac..f4484d9 100644
--- a/src/function.rs
+++ b/src/function.rs
@@ -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,31 +63,32 @@ impl<'lua> Function<'lua> {
/// ```
pub fn call<A: ToLuaMulti<'lua>, R: FromLuaMulti<'lua>>(&self, args: A) -> Result<R> {
let lua = self.0.lua;
+
+ let args = args.to_lua_multi(lua)?;
+ let nargs = args.len() as c_int;
+
unsafe {
- stack_guard(lua.state, || {
- let args = args.to_lua_multi(lua)?;
- let nargs = args.len() as c_int;
- check_stack_err(lua.state, nargs + 3)?;
-
- ffi::lua_pushcfunction(lua.state, error_traceback);
- let stack_start = ffi::lua_gettop(lua.state);
- lua.push_ref(&self.0);
- for arg in args {
- lua.push_value(arg);
- }
- let ret = ffi::lua_pcall(lua.state, nargs, ffi::LUA_MULTRET, stack_start);
- if ret != ffi::LUA_OK {
- return Err(pop_error(lua.state, ret));
- }
- let nresults = ffi::lua_gettop(lua.state) - stack_start;
- let mut results = MultiValue::new();
- check_stack(lua.state, 2);
- for _ in 0..nresults {
- results.push_front(lua.pop_value());
- }
- ffi::lua_pop(lua.state, 1);
- R::from_lua_multi(results, lua)
- })
+ let _sg = StackGuard::new(lua.state);
+ check_stack_err(lua.state, nargs + 3)?;
+
+ ffi::lua_pushcfunction(lua.state, error_traceback);
+ let stack_start = ffi::lua_gettop(lua.state);
+ lua.push_ref(&self.0);
+ for arg in args {
+ lua.push_value(arg);
+ }
+ let ret = ffi::lua_pcall(lua.state, nargs, ffi::LUA_MULTRET, stack_start);
+ if ret != ffi::LUA_OK {
+ return Err(pop_error(lua.state, ret));
+ }
+ let nresults = ffi::lua_gettop(lua.state) - stack_start;
+ let mut results = MultiValue::new();
+ check_stack(lua.state, 2);
+ for _ in 0..nresults {
+ results.push_front(lua.pop_value());
+ }
+ ffi::lua_pop(lua.state, 1);
+ R::from_lua_multi(results, lua)
}
}
@@ -144,28 +145,28 @@ impl<'lua> Function<'lua> {
}
let lua = self.0.lua;
+
+ let args = args.to_lua_multi(lua)?;
+ let nargs = args.len() as c_int;
+
+ if nargs + 2 > ffi::LUA_MAX_UPVALUES {
+ return Err(Error::BindError);
+ }
+
unsafe {
- stack_guard(lua.state, || {
- let args = args.to_lua_multi(lua)?;
- let nargs = args.len() as c_int;
-
- if nargs + 2 > ffi::LUA_MAX_UPVALUES {
- return Err(Error::BindError);
- }
-
- check_stack_err(lua.state, nargs + 5)?;
- lua.push_ref(&self.0);
- ffi::lua_pushinteger(lua.state, nargs as ffi::lua_Integer);
- for arg in args {
- lua.push_value(arg);
- }
-
- protect_lua_closure(lua.state, nargs + 2, 1, |state| {
- ffi::lua_pushcclosure(state, bind_call_impl, nargs + 2);
- })?;
-
- Ok(Function(lua.pop_ref()))
- })
+ 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);
+ for arg in args {
+ lua.push_value(arg);
+ }
+
+ protect_lua_closure(lua.state, nargs + 2, 1, |state| {
+ ffi::lua_pushcclosure(state, bind_call_impl, nargs + 2);
+ })?;
+
+ Ok(Function(lua.pop_ref()))
}
}
}
diff --git a/src/lua.rs b/src/lua.rs
index 767f507..cef2779 100644
--- a/src/lua.rs
+++ b/src/lua.rs
@@ -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,34 +102,33 @@ impl Lua {
/// Equivalent to Lua's `load` function.
pub fn load(&self, source: &str, name: Option<&str>) -> Result<Function> {
unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 1);
-
- match if let Some(name) = name {
- let name =
- CString::new(name.to_owned()).map_err(|e| Error::ToLuaConversionError {
- from: "&str",
- to: "string",
- message: Some(e.to_string()),
- })?;
- ffi::luaL_loadbuffer(
- self.state,
- source.as_ptr() as *const c_char,
- source.len(),
- name.as_ptr(),
- )
- } else {
- ffi::luaL_loadbuffer(
- self.state,
- source.as_ptr() as *const c_char,
- source.len(),
- ptr::null(),
- )
- } {
- ffi::LUA_OK => Ok(Function(self.pop_ref())),
- err => Err(pop_error(self.state, err)),
- }
- })
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 1);
+
+ match if let Some(name) = name {
+ let name =
+ CString::new(name.to_owned()).map_err(|e| Error::ToLuaConversionError {
+ from: "&str",
+ to: "string",
+ message: Some(e.to_string()),
+ })?;
+ ffi::luaL_loadbuffer(
+ self.state,
+ source.as_ptr() as *const c_char,
+ source.len(),
+ name.as_ptr(),
+ )
+ } else {
+ ffi::luaL_loadbuffer(
+ self.state,
+ source.as_ptr() as *const c_char,
+ source.len(),
+ ptr::null(),
+ )
+ } {
+ ffi::LUA_OK => Ok(Function(self.pop_ref())),
+ err => Err(pop_error(self.state, err)),
+ }
}
}
@@ -167,26 +166,24 @@ 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, || {
- check_stack(self.state, 4);
- push_string(self.state, s)?;
- Ok(String(self.pop_ref()))
- })
+ 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, || {
- check_stack(self.state, 3);
- unsafe extern "C" fn new_table(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_newtable(state);
- 1
- }
- protect_lua(self.state, 0, new_table)?;
- Ok(Table(self.pop_ref()))
- })
+ 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);
+ 1
+ }
+ protect_lua(self.state, 0, new_table)?;
+ Ok(Table(self.pop_ref()))
}
}
@@ -198,25 +195,25 @@ impl Lua {
I: IntoIterator<Item = (K, V)>,
{
unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 5);
- unsafe extern "C" fn new_table(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_newtable(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
+ }
+ protect_lua(self.state, 0, new_table)?;
+
+ for (k, v) in cont {
+ self.push_value(k.to_lua(self)?);
+ self.push_value(v.to_lua(self)?);
+ unsafe extern "C" fn raw_set(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_rawset(state, -3);
1
}
- protect_lua(self.state, 0, new_table)?;
-
- for (k, v) in cont {
- self.push_value(k.to_lua(self)?);
- self.push_value(v.to_lua(self)?);
- unsafe extern "C" fn raw_set(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_rawset(state, -3);
- 1
- }
- protect_lua(self.state, 3, raw_set)?;
- }
- Ok(Table(self.pop_ref()))
- })
+ protect_lua(self.state, 3, raw_set)?;
+ }
+ Ok(Table(self.pop_ref()))
}
}
@@ -322,16 +319,15 @@ 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 || {
- check_stack(self.state, 2);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 2);
- let thread_state =
- protect_lua_closure(self.state, 0, 1, |state| ffi::lua_newthread(state))?;
- self.push_ref(&func.0);
- ffi::lua_xmove(self.state, thread_state, 1);
+ let thread_state =
+ protect_lua_closure(self.state, 0, 1, |state| ffi::lua_newthread(state))?;
+ self.push_ref(&func.0);
+ ffi::lua_xmove(self.state, thread_state, 1);
- Ok(Thread(self.pop_ref()))
- })
+ 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 || {
- check_stack(self.state, 2);
- ffi::lua_rawgeti(self.state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
- Table(self.pop_ref())
- })
+ 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,23 +387,22 @@ impl Lua {
match v {
Value::String(s) => Ok(s),
v => unsafe {
- stack_guard(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)
- })?;
- if s.is_null() {
- Err(Error::FromLuaConversionError {
- from: ty,
- to: "String",
- message: Some("expected string or number".to_string()),
- })
- } else {
- Ok(String(self.pop_ref()))
- }
- })
+ 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))?;
+ if s.is_null() {
+ Err(Error::FromLuaConversionError {
+ from: ty,
+ to: "String",
+ message: Some("expected string or number".to_string()),
+ })
+ } else {
+ Ok(String(self.pop_ref()))
+ }
},
}
}
@@ -421,22 +415,22 @@ impl Lua {
match v {
Value::Integer(i) => Ok(i),
v => unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 2);
- let ty = v.type_name();
- self.push_value(v);
- let mut isint = 0;
- let i = ffi::lua_tointegerx(self.state, -1, &mut isint);
- if isint == 0 {
- Err(Error::FromLuaConversionError {
- from: ty,
- to: "integer",
- message: None,
- })
- } else {
- Ok(i)
- }
- })
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 2);
+
+ let ty = v.type_name();
+ self.push_value(v);
+ let mut isint = 0;
+ let i = ffi::lua_tointegerx(self.state, -1, &mut isint);
+ if isint == 0 {
+ Err(Error::FromLuaConversionError {
+ from: ty,
+ to: "integer",
+ message: None,
+ })
+ } else {
+ Ok(i)
+ }
},
}
}
@@ -449,22 +443,22 @@ impl Lua {
match v {
Value::Number(n) => Ok(n),
v => unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 2);
- let ty = v.type_name();
- self.push_value(v);
- let mut isnum = 0;
- let n = ffi::lua_tonumberx(self.state, -1, &mut isnum);
- if isnum == 0 {
- Err(Error::FromLuaConversionError {
- from: ty,
- to: "number",
- message: Some("number or string coercible to number".to_string()),
- })
- } else {
- Ok(n)
- }
- })
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 2);
+
+ let ty = v.type_name();
+ self.push_value(v);
+ let mut isnum = 0;
+ let n = ffi::lua_tonumberx(self.state, -1, &mut isnum);
+ if isnum == 0 {
+ Err(Error::FromLuaConversionError {
+ from: ty,
+ to: "number",
+ message: Some("number or string coercible to number".to_string()),
+ })
+ } else {
+ Ok(n)
+ }
},
}
}
@@ -502,18 +496,17 @@ impl Lua {
t: T,
) -> Result<()> {
unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 5);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 5);
- push_string(self.state, name)?;
- self.push_value(t.to_lua(self)?);
+ push_string(self.state, name)?;
+ self.push_value(t.to_lua(self)?);
- unsafe extern "C" fn set_registry(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_rawset(state, ffi::LUA_REGISTRYINDEX);
- 0
- }
- protect_lua(self.state, 2, set_registry)
- })
+ unsafe extern "C" fn set_registry(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_rawset(state, ffi::LUA_REGISTRYINDEX);
+ 0
+ }
+ protect_lua(self.state, 2, set_registry)
}
}
@@ -525,18 +518,17 @@ 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, || {
- check_stack(self.state, 4);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 4);
- push_string(self.state, name)?;
- unsafe extern "C" fn get_registry(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_rawget(state, ffi::LUA_REGISTRYINDEX);
- 1
- }
- protect_lua(self.state, 1, get_registry)?;
+ push_string(self.state, name)?;
+ unsafe extern "C" fn get_registry(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_rawget(state, ffi::LUA_REGISTRYINDEX);
+ 1
+ }
+ protect_lua(self.state, 1, get_registry)?;
- T::from_lua(self.pop_value(), self)
- })
+ T::from_lua(self.pop_value(), self)
}
}
@@ -555,18 +547,17 @@ impl Lua {
/// state.
pub fn create_registry_value<'lua, T: ToLua<'lua>>(&'lua self, t: T) -> Result<RegistryKey> {
unsafe {
- stack_guard(self.state, || {
- check_stack(self.state, 2);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 2);
- self.push_value(t.to_lua(self)?);
- let registry_id = gc_guard(self.state, || {
- ffi::luaL_ref(self.state, ffi::LUA_REGISTRYINDEX)
- });
+ self.push_value(t.to_lua(self)?);
+ let registry_id = gc_guard(self.state, || {
+ ffi::luaL_ref(self.state, ffi::LUA_REGISTRYINDEX)
+ });
- Ok(RegistryKey {
- registry_id,
- unref_list: (*self.extra()).registry_unref_list.clone(),
- })
+ Ok(RegistryKey {
+ registry_id,
+ unref_list: (*self.extra()).registry_unref_list.clone(),
})
}
}
@@ -583,15 +574,15 @@ impl Lua {
return Err(Error::MismatchedRegistryKey);
}
- stack_guard(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)
- })
+ 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,112 +874,111 @@ impl Lua {
}
}
- stack_guard(self.state, move || {
- if let Some(table_id) = (*self.extra()).registered_userdata.get(&TypeId::of::<T>()) {
- return Ok(*table_id);
- }
+ 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);
- check_stack(self.state, 6);
+ let mut methods = UserDataMethods {
+ methods: HashMap::new(),
+ meta_methods: HashMap::new(),
+ _type: PhantomData,
+ };
+ T::add_methods(&mut methods);
+
+ protect_lua_closure(self.state, 0, 1, |state| {
+ ffi::lua_newtable(state);
+ })?;
- let mut methods = UserDataMethods {
- methods: HashMap::new(),
- meta_methods: HashMap::new(),
- _type: PhantomData,
- };
- T::add_methods(&mut methods);
+ let has_methods = !methods.methods.is_empty();
+ if has_methods {
+ push_string(self.state, "__index")?;
protect_lua_closure(self.state, 0, 1, |state| {
ffi::lua_newtable(state);
})?;
- let has_methods = !methods.methods.is_empty();
+ for (k, m) in methods.methods {
+ push_string(self.state, &k)?;
+ self.push_value(Value::Function(self.create_callback_function(m)?));
+ protect_lua_closure(self.state, 3, 1, |state| {
+ ffi::lua_rawset(state, -3);
+ })?;
+ }
+
+ protect_lua_closure(self.state, 3, 1, |state| {
+ ffi::lua_rawset(state, -3);
+ })?;
+ }
- if has_methods {
+ for (k, m) in methods.meta_methods {
+ if k == MetaMethod::Index && has_methods {
push_string(self.state, "__index")?;
- protect_lua_closure(self.state, 0, 1, |state| {
- ffi::lua_newtable(state);
+ ffi::lua_pushvalue(self.state, -1);
+ ffi::lua_gettable(self.state, -3);
+ self.push_value(Value::Function(self.create_callback_function(m)?));
+ protect_lua_closure(self.state, 2, 1, |state| {
+ ffi::lua_pushcclosure(state, meta_index_impl, 2);
})?;
- for (k, m) in methods.methods {
- push_string(self.state, &k)?;
- self.push_value(Value::Function(self.create_callback_function(m)?));
- protect_lua_closure(self.state, 3, 1, |state| {
- ffi::lua_rawset(state, -3);
- })?;
- }
-
+ protect_lua_closure(self.state, 3, 1, |state| {
+ ffi::lua_rawset(state, -3);
+ })?;
+ } else {
+ let name = match k {
+ MetaMethod::Add => "__add",
+ MetaMethod::Sub => "__sub",
+ MetaMethod::Mul => "__mul",
+ MetaMethod::Div => "__div",
+ MetaMethod::Mod => "__mod",
+ MetaMethod::Pow => "__pow",
+ MetaMethod::Unm => "__unm",
+ MetaMethod::IDiv => "__idiv",
+ MetaMethod::BAnd => "__band",
+ MetaMethod::BOr => "__bor",
+ MetaMethod::BXor => "__bxor",
+ MetaMethod::BNot => "__bnot",
+ MetaMethod::Shl => "__shl",
+ MetaMethod::Shr => "__shr",
+ MetaMethod::Concat => "__concat",
+ MetaMethod::Len => "__len",
+ MetaMethod::Eq => "__eq",
+ MetaMethod::Lt => "__lt",
+ MetaMethod::Le => "__le",
+ MetaMethod::Index => "__index",
+ MetaMethod::NewIndex => "__newindex",
+ MetaMethod::Call => "__call",
+ MetaMethod::ToString => "__tostring",
+ };
+ push_string(self.state, name)?;
+ self.push_value(Value::Function(self.create_callback_function(m)?));
protect_lua_closure(self.state, 3, 1, |state| {
ffi::lua_rawset(state, -3);
})?;
}
+ }
- for (k, m) in methods.meta_methods {
- if k == MetaMethod::Index && has_methods {
- push_string(self.state, "__index")?;
- ffi::lua_pushvalue(self.state, -1);
- ffi::lua_gettable(self.state, -3);
- self.push_value(Value::Function(self.create_callback_function(m)?));
- protect_lua_closure(self.state, 2, 1, |state| {
- ffi::lua_pushcclosure(state, meta_index_impl, 2);
- })?;
-
- protect_lua_closure(self.state, 3, 1, |state| {
- ffi::lua_rawset(state, -3);
- })?;
- } else {
- let name = match k {
- MetaMethod::Add => "__add",
- MetaMethod::Sub => "__sub",
- MetaMethod::Mul => "__mul",
- MetaMethod::Div => "__div",
- MetaMethod::Mod => "__mod",
- MetaMethod::Pow => "__pow",
- MetaMethod::Unm => "__unm",
- MetaMethod::IDiv => "__idiv",
- MetaMethod::BAnd => "__band",
- MetaMethod::BOr => "__bor",
- MetaMethod::BXor => "__bxor",
- MetaMethod::BNot => "__bnot",
- MetaMethod::Shl => "__shl",
- MetaMethod::Shr => "__shr",
- MetaMethod::Concat => "__concat",
- MetaMethod::Len => "__len",
- MetaMethod::Eq => "__eq",
- MetaMethod::Lt => "__lt",
- MetaMethod::Le => "__le",
- MetaMethod::Index => "__index",
- MetaMethod::NewIndex => "__newindex",
- MetaMethod::Call => "__call",
- MetaMethod::ToString => "__tostring",
- };
- push_string(self.state, name)?;
- self.push_value(Value::Function(self.create_callback_function(m)?));
- protect_lua_closure(self.state, 3, 1, |state| {
- ffi::lua_rawset(state, -3);
- })?;
- }
- }
-
- push_string(self.state, "__gc")?;
- ffi::lua_pushcfunction(self.state, userdata_destructor::<RefCell<T>>);
- protect_lua_closure(self.state, 3, 1, |state| {
- ffi::lua_rawset(state, -3);
- })?;
+ push_string(self.state, "__gc")?;
+ ffi::lua_pushcfunction(self.state, userdata_destructor::<RefCell<T>>);
+ protect_lua_closure(self.state, 3, 1, |state| {
+ ffi::lua_rawset(state, -3);
+ })?;
- push_string(self.state, "__metatable")?;
- ffi::lua_pushboolean(self.state, 0);
- protect_lua_closure(self.state, 3, 1, |state| {
- ffi::lua_rawset(state, -3);
- })?;
+ push_string(self.state, "__metatable")?;
+ ffi::lua_pushboolean(self.state, 0);
+ protect_lua_closure(self.state, 3, 1, |state| {
+ ffi::lua_rawset(state, -3);
+ })?;
- let id = gc_guard(self.state, || {
- ffi::luaL_ref(self.state, ffi::LUA_REGISTRYINDEX)
- });
- (*self.extra())
- .registered_userdata
- .insert(TypeId::of::<T>(), id);
- Ok(id)
- })
+ let id = gc_guard(self.state, || {
+ ffi::luaL_ref(self.state, ffi::LUA_REGISTRYINDEX)
+ });
+ (*self.extra())
+ .registered_userdata
+ .insert(TypeId::of::<T>(), id);
+ Ok(id)
}
unsafe fn create_lua(load_debug: bool) -> Lua {
@@ -1125,24 +1115,23 @@ impl Lua {
}
unsafe {
- stack_guard(self.state, move || {
- check_stack(self.state, 4);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 4);
- push_userdata::<Callback>(self.state, func)?;
+ push_userdata::<Callback>(self.state, func)?;
- ffi::lua_pushlightuserdata(
- self.state,
- &FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
- );
- ffi::lua_rawget(self.state, ffi::LUA_REGISTRYINDEX);
- ffi::lua_setmetatable(self.state, -2);
+ ffi::lua_pushlightuserdata(
+ self.state,
+ &FUNCTION_METATABLE_REGISTRY_KEY as *const u8 as *mut c_void,
+ );
+ ffi::lua_rawget(self.state, ffi::LUA_REGISTRYINDEX);
+ ffi::lua_setmetatable(self.state, -2);
- protect_lua_closure(self.state, 1, 1, |state| {
- ffi::lua_pushcclosure(state, callback_call_impl, 1);
- })?;
+ protect_lua_closure(self.state, 1, 1, |state| {
+ ffi::lua_pushcclosure(state, callback_call_impl, 1);
+ })?;
- Ok(Function(self.pop_ref()))
- })
+ Ok(Function(self.pop_ref()))
}
}
@@ -1151,21 +1140,20 @@ impl Lua {
T: UserData,
{
unsafe {
- stack_guard(self.state, move || {
- check_stack(self.state, 4);
+ let _sg = StackGuard::new(self.state);
+ check_stack(self.state, 4);
- push_userdata::<RefCell<T>>(self.state, RefCell::new(data))?;
+ push_userdata::<RefCell<T>>(self.state, RefCell::new(data))?;
- ffi::lua_rawgeti(
- self.state,
- ffi::LUA_REGISTRYINDEX,
- self.userdata_metatable::<T>()? as ffi::lua_Integer,
- );
+ ffi::lua_rawgeti(
+ self.state,
+ ffi::LUA_REGISTRYINDEX,
+ self.userdata_metatable::<T>()? as ffi::lua_Integer,
+ );
- ffi::lua_setmetatable(self.state, -2);
+ ffi::lua_setmetatable(self.state, -2);
- Ok(AnyUserData(self.pop_ref()))
- })
+ Ok(AnyUserData(self.pop_ref()))
}
}
@@ -1290,19 +1278,18 @@ impl<'scope> Scope<'scope> {
let f_destruct = f.0.clone();
destructors.push(Box::new(move || {
let state = f_destruct.lua.state;
- stack_guard(state, || {
- check_stack(state, 2);
- f_destruct.lua.push_ref(&f_destruct);
+ let _sg = StackGuard::new(state);
+ check_stack(state, 2);
+ f_destruct.lua.push_ref(&f_destruct);
- ffi::lua_getupvalue(state, -1, 1);
- let ud = take_userdata::<Callback>(state);
+ ffi::lua_getupvalue(state, -1, 1);
+ let ud = take_userdata::<Callback>(state);
- ffi::lua_pushnil(state);
- ffi::lua_setupvalue(state, -2, 1);
+ ffi::lua_pushnil(state);
+ ffi::lua_setupvalue(state, -2, 1);
- ffi::lua_pop(state, 1);
- Box::new(ud)
- })
+ 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, || {
- check_stack(state, 1);
- u_destruct.lua.push_ref(&u_destruct);
- Box::new(take_userdata::<RefCell<T>>(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)
}
diff --git a/src/string.rs b/src/string.rs
index d854b16..1610f3e 100644
--- a/src/string.rs
+++ b/src/string.rs
@@ -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,21 +69,21 @@ impl<'lua> String<'lua> {
pub fn as_bytes_with_nul(&self) -> &[u8] {
let lua = self.0.lua;
unsafe {
- stack_guard(lua.state, || {
- check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- rlua_assert!(
- ffi::lua_type(lua.state, -1) == ffi::LUA_TSTRING,
- "string ref is not string type"
- );
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 1);
- let mut size = 0;
- // This will not trigger a 'm' error, because the reference is guaranteed to be of
- // string type
- let data = ffi::lua_tolstring(lua.state, -1, &mut size);
+ lua.push_ref(&self.0);
+ rlua_assert!(
+ ffi::lua_type(lua.state, -1) == ffi::LUA_TSTRING,
+ "string ref is not string type"
+ );
- slice::from_raw_parts(data as *const u8, size + 1)
- })
+ let mut size = 0;
+ // This will not trigger a 'm' error, because the reference is guaranteed to be of
+ // string type
+ let data = ffi::lua_tolstring(lua.state, -1, &mut size);
+
+ slice::from_raw_parts(data as *const u8, size + 1)
}
}
}
diff --git a/src/table.rs b/src/table.rs
index 693e017..3c36a11 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -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,18 +52,18 @@ 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, || {
- check_stack(lua.state, 6);
- lua.push_ref(&self.0);
- lua.push_value(key.to_lua(lua)?);
- lua.push_value(value.to_lua(lua)?);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 6);
- unsafe extern "C" fn set_table(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_settable(state, -3);
- 1
- }
- protect_lua(lua.state, 3, set_table)
- })
+ lua.push_ref(&self.0);
+ lua.push_value(key.to_lua(lua)?);
+ lua.push_value(value.to_lua(lua)?);
+
+ unsafe extern "C" fn set_table(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_settable(state, -3);
+ 1
+ }
+ protect_lua(lua.state, 3, set_table)
}
}
@@ -98,19 +98,19 @@ 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, || {
- check_stack(lua.state, 5);
- lua.push_ref(&self.0);
- lua.push_value(key.to_lua(lua)?);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 5);
- unsafe extern "C" fn get_table(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_gettable(state, -2);
- 1
- }
- protect_lua(lua.state, 2, get_table)?;
+ lua.push_ref(&self.0);
+ lua.push_value(key.to_lua(lua)?);
- V::from_lua(lua.pop_value(), lua)
- })
+ unsafe extern "C" fn get_table(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_gettable(state, -2);
+ 1
+ }
+ protect_lua(lua.state, 2, get_table)?;
+
+ V::from_lua(lua.pop_value(), lua)
}
}
@@ -118,20 +118,20 @@ 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, || {
- check_stack(lua.state, 5);
- lua.push_ref(&self.0);
- lua.push_value(key.to_lua(lua)?);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 5);
- unsafe extern "C" fn get_table(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_gettable(state, -2);
- 1
- }
- protect_lua(lua.state, 2, get_table)?;
+ lua.push_ref(&self.0);
+ lua.push_value(key.to_lua(lua)?);
- let has = ffi::lua_isnil(lua.state, -1) == 0;
- Ok(has)
- })
+ unsafe extern "C" fn get_table(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_gettable(state, -2);
+ 1
+ }
+ protect_lua(lua.state, 2, get_table)?;
+
+ let has = ffi::lua_isnil(lua.state, -1) == 0;
+ Ok(has)
}
}
@@ -139,20 +139,20 @@ 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, || {
- check_stack(lua.state, 6);
- lua.push_ref(&self.0);
- lua.push_value(key.to_lua(lua)?);
- lua.push_value(value.to_lua(lua)?);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 6);
- unsafe extern "C" fn raw_set(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_rawset(state, -3);
- 0
- }
- protect_lua(lua.state, 3, raw_set)?;
+ lua.push_ref(&self.0);
+ lua.push_value(key.to_lua(lua)?);
+ lua.push_value(value.to_lua(lua)?);
+
+ unsafe extern "C" fn raw_set(state: *mut ffi::lua_State) -> c_int {
+ ffi::lua_rawset(state, -3);
+ 0
+ }
+ protect_lua(lua.state, 3, raw_set)?;
- Ok(())
- })
+ 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, || {
- 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)
- })
+ 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, || {
- check_stack(lua.state, 4);
- lua.push_ref(&self.0);
- protect_lua_closure(lua.state, 1, 0, |state| ffi::luaL_len(state, -1))
- })
+ 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, || {
- check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- let len = ffi::lua_rawlen(lua.state, -1);
- len as Integer
- })
+ 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,16 +204,15 @@ impl<'lua> Table<'lua> {
pub fn get_metatable(&self) -> Option<Table<'lua>> {
let lua = self.0.lua;
unsafe {
- stack_guard(lua.state, || {
- check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- if ffi::lua_getmetatable(lua.state, -1) == 0 {
- None
- } else {
- let table = Table(lua.pop_ref());
- Some(table)
- }
- })
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 1);
+ lua.push_ref(&self.0);
+ if ffi::lua_getmetatable(lua.state, -1) == 0 {
+ None
+ } else {
+ let table = Table(lua.pop_ref());
+ Some(table)
+ }
}
}
@@ -226,16 +223,15 @@ impl<'lua> Table<'lua> {
pub fn set_metatable(&self, metatable: Option<Table<'lua>>) {
let lua = self.0.lua;
unsafe {
- stack_guard(lua.state, move || {
- check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- if let Some(metatable) = metatable {
- lua.push_ref(&metatable.0);
- } else {
- ffi::lua_pushnil(lua.state);
- }
- ffi::lua_setmetatable(lua.state, -2);
- })
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 1);
+ lua.push_ref(&self.0);
+ if let Some(metatable) = metatable {
+ lua.push_ref(&metatable.0);
+ } else {
+ ffi::lua_pushnil(lua.state);
+ }
+ ffi::lua_setmetatable(lua.state, -2);
}
}
@@ -359,31 +355,30 @@ where
let lua = self.table.lua;
unsafe {
- stack_guard(lua.state, || {
- check_stack(lua.state, 6);
-
- lua.push_ref(&self.table);
- lua.push_ref(&next_key);
-
- match protect_lua_closure(lua.state, 2, ffi::LUA_MULTRET, |state| {
- ffi::lua_next(state, -2) != 0
- }) {
- Ok(false) => None,
- Ok(true) => {
- ffi::lua_pushvalue(lua.state, -2);
- let key = lua.pop_value();
- let value = lua.pop_value();
- self.next_key = Some(lua.pop_ref());
-
- Some((|| {
- let key = K::from_lua(key, lua)?;
- let value = V::from_lua(value, lua)?;
- Ok((key, value))
- })())
- }
- Err(e) => Some(Err(e)),
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 6);
+
+ lua.push_ref(&self.table);
+ lua.push_ref(&next_key);
+
+ match protect_lua_closure(lua.state, 2, ffi::LUA_MULTRET, |state| {
+ ffi::lua_next(state, -2) != 0
+ }) {
+ Ok(false) => None,
+ Ok(true) => {
+ ffi::lua_pushvalue(lua.state, -2);
+ let key = lua.pop_value();
+ let value = lua.pop_value();
+ self.next_key = Some(lua.pop_ref());
+
+ Some((|| {
+ let key = K::from_lua(key, lua)?;
+ let value = V::from_lua(value, lua)?;
+ Ok((key, value))
+ })())
}
- })
+ Err(e) => Some(Err(e)),
+ }
}
} else {
None
@@ -413,22 +408,20 @@ where
let lua = self.table.lua;
unsafe {
- stack_guard(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)
- }) {
- Ok(ffi::LUA_TNIL) => None,
- Ok(_) => {
- let value = lua.pop_value();
- self.index = Some(index + 1);
- Some(V::from_lua(value, lua))
- }
- Err(err) => Some(Err(err)),
+ 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))
+ {
+ Ok(ffi::LUA_TNIL) => None,
+ Ok(_) => {
+ let value = lua.pop_value();
+ self.index = Some(index + 1);
+ Some(V::from_lua(value, lua))
}
- })
+ Err(err) => Some(Err(err)),
+ }
}
} else {
None
diff --git a/src/thread.rs b/src/thread.rs
index 7174240..cb87873 100644
--- a/src/thread.rs
+++ b/src/thread.rs
@@ -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,45 +78,44 @@ impl<'lua> Thread<'lua> {
{
let lua = self.0.lua;
unsafe {
- stack_guard(lua.state, || {
- check_stack(lua.state, 1);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- let thread_state = ffi::lua_tothread(lua.state, -1);
+ lua.push_ref(&self.0);
+ let thread_state = ffi::lua_tothread(lua.state, -1);
- let status = ffi::lua_status(thread_state);
- if status != ffi::LUA_YIELD && ffi::lua_gettop(thread_state) == 0 {
- return Err(Error::CoroutineInactive);
- }
+ let status = ffi::lua_status(thread_state);
+ if status != ffi::LUA_YIELD && ffi::lua_gettop(thread_state) == 0 {
+ return Err(Error::CoroutineInactive);
+ }
- ffi::lua_pop(lua.state, 1);
+ ffi::lua_pop(lua.state, 1);
- let args = args.to_lua_multi(lua)?;
- let nargs = args.len() as c_int;
- check_stack_err(lua.state, nargs)?;
- check_stack_err(thread_state, nargs + 1)?;
+ let args = args.to_lua_multi(lua)?;
+ let nargs = args.len() as c_int;
+ check_stack_err(lua.state, nargs)?;
+ check_stack_err(thread_state, nargs + 1)?;
- for arg in args {
- lua.push_value(arg);
- }
- ffi::lua_xmove(lua.state, thread_state, nargs);
+ for arg in args {
+ lua.push_value(arg);
+ }
+ ffi::lua_xmove(lua.state, thread_state, nargs);
- let ret = ffi::lua_resume(thread_state, lua.state, nargs);
- if ret != ffi::LUA_OK && ret != ffi::LUA_YIELD {
- error_traceback(thread_state);
- return Err(pop_error(thread_state, ret));
- }
+ let ret = ffi::lua_resume(thread_state, lua.state, nargs);
+ if ret != ffi::LUA_OK && ret != ffi::LUA_YIELD {
+ error_traceback(thread_state);
+ return Err(pop_error(thread_state, ret));
+ }
- let nresults = ffi::lua_gettop(thread_state);
- let mut results = MultiValue::new();
- ffi::lua_xmove(thread_state, lua.state, nresults);
+ let nresults = ffi::lua_gettop(thread_state);
+ let mut results = MultiValue::new();
+ ffi::lua_xmove(thread_state, lua.state, nresults);
- check_stack(lua.state, 2);
- for _ in 0..nresults {
- results.push_front(lua.pop_value());
- }
- R::from_lua_multi(results, lua)
- })
+ check_stack(lua.state, 2);
+ for _ in 0..nresults {
+ results.push_front(lua.pop_value());
+ }
+ R::from_lua_multi(results, lua)
}
}
@@ -124,22 +123,21 @@ impl<'lua> Thread<'lua> {
pub fn status(&self) -> ThreadStatus {
let lua = self.0.lua;
unsafe {
- stack_guard(lua.state, || {
- check_stack(lua.state, 1);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 1);
- lua.push_ref(&self.0);
- let thread_state = ffi::lua_tothread(lua.state, -1);
- ffi::lua_pop(lua.state, 1);
+ lua.push_ref(&self.0);
+ let thread_state = ffi::lua_tothread(lua.state, -1);
+ ffi::lua_pop(lua.state, 1);
- let status = ffi::lua_status(thread_state);
- if status != ffi::LUA_OK && status != ffi::LUA_YIELD {
- ThreadStatus::Error
- } else if status == ffi::LUA_YIELD || ffi::lua_gettop(thread_state) > 0 {
- ThreadStatus::Resumable
- } else {
- ThreadStatus::Unresumable
- }
- })
+ let status = ffi::lua_status(thread_state);
+ if status != ffi::LUA_OK && status != ffi::LUA_YIELD {
+ ThreadStatus::Error
+ } else if status == ffi::LUA_YIELD || ffi::lua_gettop(thread_state) > 0 {
+ ThreadStatus::Resumable
+ } else {
+ ThreadStatus::Unresumable
+ }
}
}
}
diff --git a/src/userdata.rs b/src/userdata.rs
index c0383c0..be8fb32 100644
--- a/src/userdata.rs
+++ b/src/userdata.rs
@@ -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,29 +415,28 @@ impl<'lua> AnyUserData<'lua> {
{
unsafe {
let lua = self.0.lua;
- stack_guard(lua.state, move || {
- check_stack(lua.state, 3);
+ let _sg = StackGuard::new(lua.state);
+ check_stack(lua.state, 3);
- lua.push_ref(&self.0);
+ lua.push_ref(&self.0);
- rlua_assert!(
- ffi::lua_getmetatable(lua.state, -1) != 0,
- "AnyUserData missing metatable"
- );
+ rlua_assert!(
+ ffi::lua_getmetatable(lua.state, -1) != 0,
+ "AnyUserData missing metatable"
+ );
- ffi::lua_rawgeti(
- lua.state,
- ffi::LUA_REGISTRYINDEX,
- lua.userdata_metatable::<T>()? as ffi::lua_Integer,
- );
+ ffi::lua_rawgeti(
+ lua.state,
+ ffi::LUA_REGISTRYINDEX,
+ lua.userdata_metatable::<T>()? as ffi::lua_Integer,
+ );
- if ffi::lua_rawequal(lua.state, -1, -2) == 0 {
- Err(Error::UserDataTypeMismatch)
- } else {
- let res = func(&*get_userdata::<RefCell<T>>(lua.state, -3));
- res
- }
- })
+ if ffi::lua_rawequal(lua.state, -1, -2) == 0 {
+ Err(Error::UserDataTypeMismatch)
+ } else {
+ 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, || {
- check_stack(lua.state, 2);
- lua.push_ref(&self.0);
- lua.push_value(v.to_lua(lua)?);
- ffi::lua_setuservalue(lua.state, -2);
- Ok(())
- })
+ 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, || {
- 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)
- })
+ 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)
}
}
}
diff --git a/src/util.rs b/src/util.rs
index 724fde8..f7dc17f 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -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