summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkyren <kerriganw@gmail.com>2017-12-03 20:29:41 -0500
committerkyren <kerriganw@gmail.com>2017-12-03 20:29:41 -0500
commitc95f591935edb4128dcd6be8d14cbb2f32b21413 (patch)
tree4496e01778279f7ec487adc9fe844b55d19cc52f
parent37a3145ced50077bf81e4076ba2a3b486af5ba6e (diff)
downloadmlua-c95f591935edb4128dcd6be8d14cbb2f32b21413.zip
remove specific protected functions in favor of generic protect_lua_call
-rw-r--r--src/lib.rs1
-rw-r--r--src/protected_ffi.rs336
-rw-r--r--src/table.rs53
-rw-r--r--src/util.rs53
4 files changed, 31 insertions, 412 deletions
diff --git a/src/lib.rs b/src/lib.rs
index eb95718..d5af254 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -43,7 +43,6 @@
extern crate libc;
mod ffi;
-mod protected_ffi;
mod error;
#[macro_use]
mod macros;
diff --git a/src/protected_ffi.rs b/src/protected_ffi.rs
deleted file mode 100644
index 9ddf691..0000000
--- a/src/protected_ffi.rs
+++ /dev/null
@@ -1,336 +0,0 @@
-#![allow(unused)]
-
-use std::os::raw::{c_char, c_int, c_void};
-use std::{mem, ptr};
-
-use ffi;
-
-// Protected version of lua_gettable, uses 3 stack spaces, does not call checkstack.
-pub unsafe fn pgettable(
- state: *mut ffi::lua_State,
- index: c_int,
- msgh: c_int,
-) -> Result<c_int, c_int> {
- unsafe extern "C" fn gettable(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_gettable(state, -2);
- 1
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, gettable);
- ffi::lua_pushvalue(state, table_index);
- ffi::lua_pushvalue(state, -3);
- ffi::lua_remove(state, -4);
-
- let ret = ffi::lua_pcall(state, 2, 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(ffi::lua_type(state, -1))
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_settable, uses 4 stack spaces, does not call checkstack.
-pub unsafe fn psettable(
- state: *mut ffi::lua_State,
- index: c_int,
- msgh: c_int,
-) -> Result<(), c_int> {
- unsafe extern "C" fn settable(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_settable(state, -3);
- 0
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, settable);
- ffi::lua_pushvalue(state, table_index);
- ffi::lua_pushvalue(state, -4);
- ffi::lua_pushvalue(state, -4);
- ffi::lua_remove(state, -5);
- ffi::lua_remove(state, -5);
-
- let ret = ffi::lua_pcall(state, 3, 0, msgh);
- if ret == ffi::LUA_OK {
- Ok(())
- } else {
- Err(ret)
- }
-}
-
-// Protected version of luaL_len, uses 2 stack spaces, does not call checkstack.
-pub unsafe fn plen(
- state: *mut ffi::lua_State,
- index: c_int,
- msgh: c_int,
-) -> Result<ffi::lua_Integer, c_int> {
- unsafe extern "C" fn len(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_pushinteger(state, ffi::luaL_len(state, -1));
- 1
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, len);
- ffi::lua_pushvalue(state, table_index);
-
- let ret = ffi::lua_pcall(state, 1, 1, msgh);
- if ret == ffi::LUA_OK {
- let len = ffi::lua_tointeger(state, -1);
- ffi::lua_pop(state, 1);
- Ok(len)
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_geti, uses 3 stack spaces, does not call checkstack.
-pub unsafe fn pgeti(
- state: *mut ffi::lua_State,
- index: c_int,
- i: ffi::lua_Integer,
- msgh: c_int,
-) -> Result<c_int, c_int> {
- unsafe extern "C" fn geti(state: *mut ffi::lua_State) -> c_int {
- let i = ffi::lua_tointeger(state, -1);
- ffi::lua_geti(state, -2, i);
- 1
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, geti);
- ffi::lua_pushvalue(state, table_index);
- ffi::lua_pushinteger(state, i);
-
- let ret = ffi::lua_pcall(state, 2, 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(ffi::lua_type(state, -1))
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_next, uses 3 stack spaces, does not call checkstack.
-pub unsafe fn pnext(state: *mut ffi::lua_State, index: c_int, msgh: c_int) -> Result<c_int, c_int> {
- unsafe extern "C" fn next(state: *mut ffi::lua_State) -> c_int {
- if ffi::lua_next(state, -2) == 0 {
- 0
- } else {
- 2
- }
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, next);
- ffi::lua_pushvalue(state, table_index);
- ffi::lua_pushvalue(state, -3);
- ffi::lua_remove(state, -4);
-
- let stack_start = ffi::lua_gettop(state) - 3;
- let ret = ffi::lua_pcall(state, 2, ffi::LUA_MULTRET, msgh);
- if ret == ffi::LUA_OK {
- let nresults = ffi::lua_gettop(state) - stack_start;
- if nresults == 0 {
- Ok(0)
- } else {
- Ok(1)
- }
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_newtable, uses 1 stack space, does not call checkstack.
-pub unsafe fn pnewtable(state: *mut ffi::lua_State, msgh: c_int) -> Result<(), c_int> {
- unsafe extern "C" fn newtable(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_newtable(state);
- 1
- }
-
- ffi::lua_pushcfunction(state, newtable);
-
- let ret = ffi::lua_pcall(state, 0, 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(())
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_newthread, uses 1 stack space, does not call checkstack.
-pub unsafe fn pnewthread(
- state: *mut ffi::lua_State,
- msgh: c_int,
-) -> Result<*mut ffi::lua_State, c_int> {
- unsafe extern "C" fn newthread(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_newthread(state);
- 1
- }
-
- ffi::lua_pushcfunction(state, newthread);
-
- let ret = ffi::lua_pcall(state, 0, 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(ffi::lua_tothread(state, -1))
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_newuserdata, uses 2 stack spaces, does not call checkstack.
-pub unsafe fn pnewuserdata(
- state: *mut ffi::lua_State,
- size: usize,
- msgh: c_int,
-) -> Result<*mut c_void, c_int> {
- unsafe extern "C" fn newuserdata(state: *mut ffi::lua_State) -> c_int {
- let size = ffi::lua_touserdata(state, -1) as usize;
- ffi::lua_newuserdata(state, size);
- 1
- }
-
- ffi::lua_pushcfunction(state, newuserdata);
- ffi::lua_pushlightuserdata(state, size as *mut c_void);
-
- let ret = ffi::lua_pcall(state, 1, 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(ffi::lua_touserdata(state, -1))
- } else {
- Err(ret)
- }
-}
-
-// Protected version of lua_pushcclosure, uses 2 extra stack spaces, does not call checkstack.
-pub unsafe fn ppushcclosure(
- state: *mut ffi::lua_State,
- function: ffi::lua_CFunction,
- n: c_int,
- msgh: c_int,
-) -> Result<(), c_int> {
- unsafe extern "C" fn pushcclosure(state: *mut ffi::lua_State) -> c_int {
- let function: ffi::lua_CFunction = mem::transmute(ffi::lua_touserdata(state, -2));
- let n = ffi::lua_touserdata(state, -1) as c_int;
- ffi::lua_pop(state, 2);
- ffi::lua_pushcclosure(state, function, n);
- 1
- }
-
- if n == 0 {
- ffi::lua_pushcclosure(state, function, 0);
- Ok(())
- } else {
- ffi::lua_pushlightuserdata(state, function as *mut c_void);
- ffi::lua_pushlightuserdata(state, n as *mut c_void);
-
- let ret = ffi::lua_pcall(state, n.checked_add(2).unwrap(), 1, msgh);
- if ret == ffi::LUA_OK {
- Ok(())
- } else {
- Err(ret)
- }
- }
-}
-
-pub unsafe fn ppushlstring(
- state: *mut ffi::lua_State,
- s: *const c_char,
- len: usize,
- msgh: c_int,
-) -> Result<*const c_char, c_int> {
- unsafe extern "C" fn pushlstring(state: *mut ffi::lua_State) -> c_int {
- let s = ffi::lua_touserdata(state, -2) as *const c_char;
- let len = ffi::lua_touserdata(state, -1) as usize;
- ffi::lua_pushlstring(state, s, len);
- 1
- }
-
- ffi::lua_pushlightuserdata(state, s as *mut c_void);
- ffi::lua_pushlightuserdata(state, len as *mut c_void);
-
- let ret = ffi::lua_pcall(state, 2, 1, msgh);
- if ret == ffi::LUA_OK {
- // ffi::lua_tostring does not cause memory errors if the value is already a string
- Ok(ffi::lua_tostring(state, -1))
- } else {
- Err(ret)
- }
-}
-
-pub unsafe fn prawset(state: *mut ffi::lua_State, index: c_int, msgh: c_int) -> Result<(), c_int> {
- unsafe extern "C" fn rawset(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_rawset(state, -3);
- 0
- }
-
- let table_index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, rawset);
- ffi::lua_pushvalue(state, table_index);
- ffi::lua_pushvalue(state, -4);
- ffi::lua_pushvalue(state, -4);
- ffi::lua_remove(state, -5);
- ffi::lua_remove(state, -5);
-
- let ret = ffi::lua_pcall(state, 3, 0, msgh);
- if ret == ffi::LUA_OK {
- Ok(())
- } else {
- Err(ret)
- }
-}
-
-pub unsafe fn ptolstring(
- state: *mut ffi::lua_State,
- index: c_int,
- len: *mut usize,
- msgh: c_int,
-) -> Result<*const c_char, c_int> {
- unsafe extern "C" fn tolstring(state: *mut ffi::lua_State) -> c_int {
- let len = ffi::lua_touserdata(state, -2) as *mut usize;
- ffi::lua_tolstring(state, -1, len);
- 1
- }
-
- let index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, tolstring);
- ffi::lua_pushlightuserdata(state, len as *mut c_void);
- ffi::lua_pushvalue(state, index);
-
- let ret = ffi::lua_pcall(state, 2, 1, msgh);
- if ret == ffi::LUA_OK {
- ffi::lua_replace(state, index);
- // ffi::lua_tostring does not cause memory errors if the value is already a string
- Ok(ffi::lua_tostring(state, index))
- } else {
- Err(ret)
- }
-}
-
-pub unsafe fn ptostring(
- state: *mut ffi::lua_State,
- index: c_int,
- msgh: c_int,
-) -> Result<*const c_char, c_int> {
- unsafe extern "C" fn tostring(state: *mut ffi::lua_State) -> c_int {
- ffi::lua_tolstring(state, -1, ptr::null_mut());
- 1
- }
-
- let index = ffi::lua_absindex(state, index);
-
- ffi::lua_pushcfunction(state, tostring);
- ffi::lua_pushvalue(state, index);
-
- let ret = ffi::lua_pcall(state, 1, 1, msgh);
- if ret == ffi::LUA_OK {
- ffi::lua_replace(state, index);
- // ffi::lua_tostring does not cause memory errors if the value is already a string
- Ok(ffi::lua_tostring(state, index))
- } else {
- Err(ret)
- }
-}
diff --git a/src/table.rs b/src/table.rs
index cfd83d1..7da679f 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -52,13 +52,13 @@ impl<'lua> Table<'lua> {
let lua = self.0.lua;
unsafe {
stack_err_guard(lua.state, 0, || {
- check_stack(lua.state, 8);
+ check_stack(lua.state, 6);
lua.push_ref(lua.state, &self.0);
lua.push_value(lua.state, key.to_lua(lua)?);
lua.push_value(lua.state, value.to_lua(lua)?);
- psettable(lua.state, -3)?;
- ffi::lua_pop(lua.state, 1);
- Ok(())
+ protect_lua_call(lua.state, 3, 0, |state| {
+ ffi::lua_settable(state, -3);
+ })
})
}
}
@@ -95,13 +95,13 @@ impl<'lua> Table<'lua> {
let lua = self.0.lua;
unsafe {
stack_err_guard(lua.state, 0, || {
- check_stack(lua.state, 6);
+ check_stack(lua.state, 5);
lua.push_ref(lua.state, &self.0);
lua.push_value(lua.state, key.to_lua(lua)?);
- pgettable(lua.state, -2)?;
- let res = lua.pop_value(lua.state);
- ffi::lua_pop(lua.state, 1);
- V::from_lua(res, lua)
+ protect_lua_call(lua.state, 2, 1, |state| {
+ ffi::lua_gettable(state, -2)
+ })?;
+ V::from_lua(lua.pop_value(lua.state), lua)
})
}
}
@@ -111,12 +111,14 @@ impl<'lua> Table<'lua> {
let lua = self.0.lua;
unsafe {
stack_err_guard(lua.state, 0, || {
- check_stack(lua.state, 6);
+ check_stack(lua.state, 5);
lua.push_ref(lua.state, &self.0);
lua.push_value(lua.state, key.to_lua(lua)?);
- pgettable(lua.state, -2)?;
+ protect_lua_call(lua.state, 2, 1, |state| {
+ ffi::lua_gettable(state, -2)
+ })?;
let has = ffi::lua_isnil(lua.state, -1) == 0;
- ffi::lua_pop(lua.state, 2);
+ ffi::lua_pop(lua.state, 1);
Ok(has)
})
}
@@ -163,11 +165,11 @@ impl<'lua> Table<'lua> {
let lua = self.0.lua;
unsafe {
stack_err_guard(lua.state, 0, || {
- check_stack(lua.state, 5);
+ check_stack(lua.state, 4);
lua.push_ref(lua.state, &self.0);
- let len = plen(lua.state, -1)?;
- ffi::lua_pop(lua.state, 1);
- Ok(len)
+ protect_lua_call(lua.state, 1, 0, |state| {
+ ffi::luaL_len(state, -1)
+ })
})
}
}
@@ -349,12 +351,18 @@ where
unsafe {
stack_guard(lua.state, 0, || {
- check_stack(lua.state, 6);
+ check_stack(lua.state, 5);
lua.push_ref(lua.state, &self.table);
lua.push_ref(lua.state, &next_key);
- match pnext(lua.state, -2) {
+ match protect_lua_call(lua.state, 2, ffi::LUA_MULTRET, |state| {
+ if ffi::lua_next(state, -2) == 0 {
+ 0
+ } else {
+ 1
+ }
+ }) {
Ok(0) => {
ffi::lua_pop(lua.state, 1);
None
@@ -405,17 +413,18 @@ where
unsafe {
stack_guard(lua.state, 0, || {
- check_stack(lua.state, 5);
+ check_stack(lua.state, 4);
lua.push_ref(lua.state, &self.table);
- match pgeti(lua.state, -1, index) {
+ match protect_lua_call(lua.state, 1, 1, |state| {
+ ffi::lua_geti(state, -1, index)
+ }) {
Ok(ffi::LUA_TNIL) => {
- ffi::lua_pop(lua.state, 2);
+ ffi::lua_pop(lua.state, 1);
None
}
Ok(_) => {
let value = lua.pop_value(lua.state);
- ffi::lua_pop(lua.state, 1);
self.index = Some(index + 1);
Some(V::from_lua(value, lua))
}
diff --git a/src/util.rs b/src/util.rs
index 6f07e74..bb3468b 100644
--- a/src/util.rs
+++ b/src/util.rs
@@ -145,59 +145,6 @@ pub unsafe fn protect_lua_call<F, R>(state: *mut ffi::lua_State, nargs: c_int, n
}
}
-// Protected version of lua_gettable, uses 4 stack spaces, does not call checkstack.
-pub unsafe fn pgettable(state: *mut ffi::lua_State, index: c_int) -> Result<c_int> {
- ffi::lua_pushvalue(state, index);
- ffi::lua_insert(state, -2);
- protect_lua_call(state, 2, 1, |state| {
- ffi::lua_gettable(state, -2)
- })
-}
-
-// Protected version of lua_settable, uses 5 stack spaces, does not call checkstack.
-pub unsafe fn psettable(state: *mut ffi::lua_State, index: c_int) -> Result<()> {
- ffi::lua_pushvalue(state, index);
- ffi::lua_insert(state, -3);
- protect_lua_call(state, 3, 0, |state| {
- ffi::lua_settable(state, -3);
- })
-}
-
-// Protected version of luaL_len, uses 4 stack spaces, does not call checkstack.
-pub unsafe fn plen(state: *mut ffi::lua_State, index: c_int) -> Result<ffi::lua_Integer> {
- ffi::lua_pushvalue(state, index);
- protect_lua_call(state, 1, 0, |state| {
- ffi::luaL_len(state, -1)
- })
-}
-
-// Protected version of lua_geti, uses 4 stack spaces, does not call checkstack.
-pub unsafe fn pgeti(
- state: *mut ffi::lua_State,
- index: c_int,
- i: ffi::lua_Integer,
-) -> Result<c_int> {
- ffi::lua_pushvalue(state, index);
- protect_lua_call(state, 1, 1, |state| {
- ffi::lua_geti(state, -1, i)
- })
-}
-
-// Protected version of lua_next, uses 4 stack spaces, does not call checkstack.
-pub unsafe fn pnext(state: *mut ffi::lua_State, index: c_int) -> Result<c_int> {
- ffi::lua_pushvalue(state, index);
- ffi::lua_insert(state, -2);
- protect_lua_call(state, 2, ffi::LUA_MULTRET, |state| {
- if ffi::lua_next(state, -2) == 0 {
- ffi::lua_remove(state, -1);
- 0
- } else {
- ffi::lua_remove(state, -3);
- 1
- }
- })
-}
-
// 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.