From fd17a01456452ce98fce41e257da9528ca9420a5 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Fri, 29 Nov 2019 13:26:30 +0000 Subject: [PATCH] Add Lua 5.2 support --- .circleci/config.yml | 5 +- Cargo.toml | 3 +- README.md | 2 +- build.rs | 37 +++- src/error.rs | 4 +- src/ffi/compat53.rs | 180 +++++++++++++++--- src/ffi/glue/glue.c | 6 +- src/ffi/lauxlib.rs | 51 +++-- src/ffi/lua.rs | 169 ++++++++++------ src/ffi/luaconf.rs | 1 - src/ffi/lualib.rs | 9 +- src/ffi/mod.rs | 57 +++--- src/lua.rs | 14 +- src/scope.rs | 6 +- src/userdata.rs | 20 +- src/util.rs | 4 +- tests/compile_fail/lua_norefunwindsafe.stderr | 73 ++++--- tests/compile_fail/ref_nounwindsafe.stderr | 85 ++++----- tests/memory.rs | 4 +- tests/tests.rs | 12 +- tests/thread.rs | 2 +- 21 files changed, 501 insertions(+), 243 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index eadc224..383accc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -24,13 +24,16 @@ jobs: name: Install Lua command: | sudo apt-get update - sudo apt-get -y --no-install-recommends install liblua5.1-0-dev libluajit-5.1-dev liblua5.3-dev + sudo apt-get -y --no-install-recommends install liblua5.3-dev liblua5.2-dev liblua5.1-0-dev libluajit-5.1-dev - run: name: Build all targets command: cargo build --all --all-targets - run: name: Run all tests / Lua 5.3 command: cargo test --all --no-default-features --features lua53 + - run: + name: Run all tests / Lua 5.2 + command: cargo test --all --no-default-features --features lua52 - run: name: Run all tests / Lua 5.1 command: cargo test --all --no-default-features --features lua51 diff --git a/Cargo.toml b/Cargo.toml index f9bb13a..970f286 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ keywords = ["lua", "luajit"] categories = ["api-bindings"] license = "MIT" description = """ -High level bindings to Lua 5.1/5.3 (including LuaJIT) +High level bindings to Lua 5.1/5.2/5.3 (including LuaJIT) with support of writing native lua modules in Rust. """ @@ -25,6 +25,7 @@ members = [ [features] default = ["lua53"] lua53 = [] +lua52 = [] lua51 = [] luajit = [] diff --git a/README.md b/README.md index c2e0ea3..3dffaf5 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ [Guided Tour](examples/guided_tour.rs) A fork of [rlua 0.15](https://github.com/kyren/rlua/tree/0.15.3) which provides a high level -interface between Rust and Lua. Unlike `rlua` , `mlua` supports Lua 5.1 (including LuaJIT) and 5.3. +interface between Rust and Lua. Unlike `rlua` , `mlua` supports Lua 5.1 (including LuaJIT), 5.2 and 5.3. The `mlua` goal is to be an easy to use, practical and flexible API between Rust and Lua but *__not__* always 100% safe due to the Lua VM nature. Also, `mlua` provides a way to write native lua modules in Rust. diff --git a/build.rs b/build.rs index 800dc24..e8ad65e 100644 --- a/build.rs +++ b/build.rs @@ -107,14 +107,25 @@ fn main() { // Find lua via pkg-config - #[cfg(not(any(feature = "lua53", feature = "lua51", feature = "luajit")))] - panic!("You must enable one of the features: lua53, lua51, luajit"); + #[cfg(not(any( + feature = "lua53", + feature = "lua52", + feature = "lua51", + feature = "luajit" + )))] + panic!("You must enable one of the features: lua53, lua52, lua51, luajit"); - #[cfg(all(feature = "lua53", any(feature = "lua51", feature = "luajit")))] - panic!("You can enable only one of the features: lua53, lua51, luajit"); + #[cfg(all( + feature = "lua53", + any(feature = "lua52", feature = "lua51", feature = "luajit") + ))] + panic!("You can enable only one of the features: lua53, lua52, lua51, luajit"); + + #[cfg(all(feature = "lua52", any(feature = "lua51", feature = "luajit")))] + panic!("You can enable only one of the features: lua53, lua52, lua51, luajit"); #[cfg(all(feature = "lua51", feature = "luajit"))] - panic!("You can enable only one of the features: lua53, lua51, luajit"); + panic!("You can enable only one of the features: lua53, lua52, lua51, luajit"); #[cfg(feature = "lua53")] { @@ -132,6 +143,22 @@ fn main() { }; } + #[cfg(feature = "lua52")] + { + let mut lua = pkg_config::Config::new() + .range_version((Bound::Included("5.2"), Bound::Excluded("5.3"))) + .probe("lua"); + + if lua.is_err() { + lua = pkg_config::Config::new().probe("lua5.2"); + } + + match lua { + Ok(lua) => build_glue(&lua.include_paths), + Err(_) => panic!("Lua 5.2 not found"), + }; + } + #[cfg(feature = "lua51")] { let mut lua = pkg_config::Config::new() diff --git a/src/error.rs b/src/error.rs index 8431503..7836378 100644 --- a/src/error.rs +++ b/src/error.rs @@ -31,7 +31,7 @@ pub enum Error { /// Lua garbage collector error, aka `LUA_ERRGCMM`. /// /// The Lua VM returns this error when there is an error running a `__gc` metamethod. - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] GarbageCollectorError(StdString), /// A mutable callback has triggered Lua code that has called the same mutable callback again. /// @@ -138,7 +138,7 @@ impl fmt::Display for Error { Error::MemoryError(ref msg) => { write!(fmt, "memory error: {}", msg) } - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] Error::GarbageCollectorError(ref msg) => { write!(fmt, "garbage collector error: {}", msg) } diff --git a/src/ffi/compat53.rs b/src/ffi/compat53.rs index 2b58ebc..c4aa164 100644 --- a/src/ffi/compat53.rs +++ b/src/ffi/compat53.rs @@ -22,27 +22,44 @@ // Based on github.com/keplerproject/lua-compat-5.3 +use std::ffi::CStr; use std::mem; use std::os::raw::{c_char, c_int, c_void}; use std::ptr; use super::lauxlib::{ - luaL_Reg, luaL_callmeta, luaL_checkstack, luaL_checktype, luaL_error, luaL_getmetafield_51, - luaL_getmetatable, luaL_loadbuffer, luaL_newmetatable_51, + luaL_callmeta, luaL_error, luaL_getmetafield_old, luaL_loadbuffer, luaL_newmetatable_old, }; +#[cfg(any(feature = "lua51", feature = "luajit"))] +use super::lauxlib::{luaL_Reg, luaL_checktype, luaL_getmetatable}; + +#[cfg(feature = "lua52")] +use super::lauxlib::{luaL_checkstack, luaL_getsubtable}; + use super::lua::{ - self, lua_CFunction, lua_Debug, lua_Integer, lua_Number, lua_State, lua_call, lua_concat, - lua_createtable, lua_equal, lua_error, lua_getfenv, lua_getfield_51, lua_getinfo, - lua_getmetatable, lua_getstack, lua_gettable_51, lua_gettop, lua_insert, lua_isnumber, - lua_isstring, lua_istable, lua_lessthan, lua_newtable, lua_newuserdata, lua_next, lua_objlen, - lua_pop, lua_pushboolean, lua_pushcclosure, lua_pushcfunction, lua_pushfstring, - lua_pushinteger, lua_pushlightuserdata, lua_pushliteral, lua_pushlstring_51, lua_pushnil, - lua_pushnumber, lua_pushstring_51, lua_pushthread, lua_pushvalue, lua_rawequal, lua_rawget_51, - lua_rawgeti_51, lua_rawset, lua_remove, lua_replace, lua_resume_51, lua_setfenv, lua_setfield, - lua_setglobal, lua_setmetatable, lua_settable, lua_settop, lua_toboolean, lua_tointeger, - lua_tolstring, lua_tonumber, lua_topointer, lua_tostring, lua_touserdata, lua_type, - lua_typename, + self, lua_CFunction, lua_Debug, lua_Integer, lua_Number, lua_State, lua_Writer, lua_call, + lua_createtable, lua_dump_old, lua_error, lua_getfield_old, lua_getstack, lua_gettable_old, + lua_gettop, lua_insert, lua_isstring, lua_istable, lua_newuserdata, lua_pop, lua_pushboolean, + lua_pushcfunction, lua_pushfstring, lua_pushinteger, lua_pushliteral, lua_pushlstring_old, + lua_pushnumber, lua_pushthread, lua_pushvalue, lua_rawget_old, lua_rawgeti_old, lua_rawset, + lua_replace, lua_setfield, lua_setglobal, lua_setmetatable, lua_settable, lua_toboolean, + lua_tointeger, lua_tolstring, lua_tonumber, lua_topointer, lua_tostring, lua_touserdata, + lua_type, lua_typename, +}; + +#[cfg(any(feature = "lua51", feature = "luajit"))] +use super::lua::{ + lua_checkstack, lua_concat, lua_equal, lua_getfenv, lua_getinfo, lua_getmetatable, + lua_isnumber, lua_lessthan, lua_newtable, lua_next, lua_objlen, lua_pushcclosure, + lua_pushlightuserdata, lua_pushnil, lua_pushstring_old, lua_rawequal, lua_remove, + lua_resume_old, lua_setfenv, lua_settop, LUA_OPADD, LUA_OPUNM, +}; + +#[cfg(feature = "lua52")] +use super::lua::{ + lua_absindex, lua_getglobal_old, lua_getuservalue_old, lua_pushstring, lua_rawgetp_old, + lua_rawsetp, lua_tonumberx, }; unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) { @@ -109,6 +126,7 @@ unsafe fn compat53_checkmode( lua::LUA_OK } +#[cfg(any(feature = "lua51", feature = "luajit"))] unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) -> c_int { if level == 0 || lua_istable(L, -1) == 0 { return 0; // not found @@ -137,6 +155,7 @@ unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) -> return 0; // not found } +#[cfg(any(feature = "lua51", feature = "luajit"))] unsafe fn compat53_pushglobalfuncname(L: *mut lua_State, ar: *mut lua_Debug) -> c_int { let top = lua_gettop(L); lua_getinfo(L, cstr!("f"), ar); // push function @@ -151,6 +170,7 @@ unsafe fn compat53_pushglobalfuncname(L: *mut lua_State, ar: *mut lua_Debug) -> } } +#[cfg(any(feature = "lua51", feature = "luajit"))] unsafe fn compat53_pushfuncname(L: *mut lua_State, ar: *mut lua_Debug) { if *(*ar).namewhat != b'\0' as c_char { // is there a name? @@ -199,11 +219,13 @@ unsafe fn compat53_call_lua(L: *mut lua_State, code: &str, nargs: c_int, nret: c // lua ported functions // +#[cfg(any(feature = "lua51", feature = "luajit"))] #[inline(always)] pub fn lua_upvalueindex(i: c_int) -> c_int { lua::LUA_GLOBALSINDEX - i } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_absindex(L: *mut lua_State, mut idx: c_int) -> c_int { if idx < 0 && idx > lua::LUA_REGISTRYINDEX { idx += lua_gettop(L) + 1; @@ -211,6 +233,33 @@ pub unsafe fn lua_absindex(L: *mut lua_State, mut idx: c_int) -> c_int { idx } +#[cfg(any(feature = "lua51", feature = "luajit"))] +static COMPAT53_ARITH_CODE: &'static str = r#" +local op,a,b=... +if op == 0 then return a+b +elseif op == 1 then return a-b +elseif op == 2 then return a*b +elseif op == 3 then return a/b +elseif op == 4 then return a%b +elseif op == 5 then return a^b +elseif op == 6 then return -a +end +"#; + +#[cfg(any(feature = "lua51", feature = "luajit"))] +pub unsafe fn lua_arith(L: *mut lua_State, op: c_int) { + if op < LUA_OPADD || op > LUA_OPUNM { + luaL_error(L, cstr!("invalid 'op' argument for lua_arith")); + } + luaL_checkstack(L, 5, cstr!("not enough stack slots")); + if op == LUA_OPUNM { + lua_pushvalue(L, -1); + } + lua_pushnumber(L, op as lua_Number); + lua_insert(L, -3); + compat53_call_lua(L, COMPAT53_ARITH_CODE, 3, 1); +} + pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) { idx = lua_absindex(L, idx); let n_elems = lua_gettop(L) - idx + 1; @@ -226,6 +275,7 @@ pub unsafe fn lua_rotate(L: *mut lua_State, mut idx: c_int, mut n: c_int) { } } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int) { let abs_to = lua_absindex(L, toidx); luaL_checkstack(L, 1, cstr!("not enough stack slots")); @@ -244,6 +294,7 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int { return 0; } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_tonumberx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Number { let n = lua_tonumber(L, i); if isnum != ptr::null_mut() { @@ -256,6 +307,8 @@ pub unsafe fn lua_tonumberx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> l return n; } +// Implemented for Lua 5.2 as well +// See https://github.com/keplerproject/lua-compat-5.3/issues/40 pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> lua_Integer { let mut ok = 0; let n = lua_tonumberx(L, i, &mut ok); @@ -273,10 +326,12 @@ pub unsafe fn lua_tointegerx(L: *mut lua_State, i: c_int, isnum: *mut c_int) -> return 0; } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize { lua_objlen(L, idx) } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_compare(L: *mut lua_State, mut idx1: c_int, mut idx2: c_int, op: c_int) -> c_int { match op { lua::LUA_OPEQ => lua_equal(L, idx1, idx2), @@ -296,27 +351,44 @@ pub unsafe fn lua_compare(L: *mut lua_State, mut idx1: c_int, mut idx2: c_int, o } } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char { if l == 0 { - lua_pushlstring_51(L, cstr!(""), 0); + lua_pushlstring_old(L, cstr!(""), 0); } else { - lua_pushlstring_51(L, s, l); + lua_pushlstring_old(L, s, l); } lua_tostring(L, -1) } +#[cfg(feature = "lua52")] +pub unsafe fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char { + if l == 0 { + lua_pushlstring_old(L, cstr!(""), 0) + } else { + lua_pushlstring_old(L, s, l) + } +} + +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char { - lua_pushstring_51(L, s); + lua_pushstring_old(L, s); lua_tostring(L, -1) } +#[cfg(feature = "lua52")] +pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int { + lua_getglobal_old(L, var); + lua_type(L, -1) +} + pub unsafe fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int { - lua_gettable_51(L, idx); + lua_gettable_old(L, idx); lua_type(L, -1) } pub unsafe fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int { - lua_getfield_51(L, idx, k); + lua_getfield_old(L, idx, k); lua_type(L, -1) } @@ -329,16 +401,17 @@ pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_i // A new version which returns c_int pub unsafe fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int { - lua_rawget_51(L, idx); + lua_rawget_old(L, idx); lua_type(L, -1) } // A new version which returns c_int pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int { - lua_rawgeti_51(L, idx, n); + lua_rawgeti_old(L, idx, n); lua_type(L, -1) } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int { let abs_i = lua_absindex(L, idx); lua_pushlightuserdata(L, p as *mut c_void); @@ -346,11 +419,24 @@ pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_ lua_type(L, -1) } +#[cfg(feature = "lua52")] +pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int { + lua_rawgetp_old(L, idx, p); + lua_type(L, -1) +} + +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int { lua_getfenv(L, idx); lua_type(L, -1) } +#[cfg(feature = "lua52")] +pub unsafe fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int { + lua_getuservalue_old(L, idx); + lua_type(L, -1) +} + pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) { luaL_checkstack(L, 1, cstr!("not enough stack slots available")); idx = lua_absindex(L, idx); @@ -359,6 +445,7 @@ pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) { lua_settable(L, idx); } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) { let abs_i = lua_absindex(L, idx); luaL_checkstack(L, 1, cstr!("not enough stack slots")); @@ -367,15 +454,27 @@ pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) { lua_rawset(L, abs_i); } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_setuservalue(L: *mut lua_State, idx: c_int) { luaL_checktype(L, -1, lua::LUA_TTABLE); lua_setfenv(L, idx); } -pub unsafe fn lua_resume(L: *mut lua_State, _from: *mut lua_State, narg: c_int) -> c_int { - lua_resume_51(L, narg) +pub unsafe fn lua_dump( + L: *mut lua_State, + writer: lua_Writer, + data: *mut c_void, + _strip: c_int, +) -> c_int { + lua_dump_old(L, writer, data) } +#[cfg(any(feature = "lua51", feature = "luajit"))] +pub unsafe fn lua_resume(L: *mut lua_State, _from: *mut lua_State, narg: c_int) -> c_int { + lua_resume_old(L, narg) +} + +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) { match lua_type(L, idx) { lua::LUA_TSTRING => { @@ -397,7 +496,18 @@ pub unsafe fn lua_len(L: *mut lua_State, idx: c_int) { } } -// TODO: lua_stringtonumber +pub unsafe fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize { + use std::str::FromStr; + + let cs = CStr::from_ptr(s); + if let Ok(rs) = cs.to_str() { + if let Ok(n) = f64::from_str(rs.trim()) { + lua_pushnumber(L, n as lua_Number); + return cs.to_bytes_with_nul().len(); + } + } + 0 +} pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void { use super::glue::LUA_EXTRASPACE; @@ -452,6 +562,7 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void { return _ptr; } +#[cfg(any(feature = "lua51", feature = "luajit"))] #[inline(always)] pub unsafe fn lua_pushglobaltable(L: *mut lua_State) { lua_pushvalue(L, lua::LUA_GLOBALSINDEX); @@ -461,12 +572,24 @@ pub unsafe fn lua_pushglobaltable(L: *mut lua_State) { // lauxlib ported functions // +#[cfg(any(feature = "lua51", feature = "luajit"))] +pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char) { + if lua_checkstack(L, sz + lua::LUA_MINSTACK) == 0 { + if msg != ptr::null() { + luaL_error(L, cstr!("stack overflow (%s)"), msg); + } else { + lua_pushliteral(L, "stack overflow"); + lua_error(L); + } + } +} + pub unsafe fn luaL_checkversion(_L: *mut lua_State) { // Void } pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int { - if luaL_getmetafield_51(L, obj, e) != 0 { + if luaL_getmetafield_old(L, obj, e) != 0 { lua_type(L, -1) } else { lua::LUA_TNIL @@ -474,7 +597,7 @@ pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) } pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int { - if luaL_newmetatable_51(L, tname) != 0 { + if luaL_newmetatable_old(L, tname) != 0 { lua_pushstring(L, tname); lua_setfield(L, -2, cstr!("__name")); 1 @@ -483,6 +606,7 @@ pub unsafe fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_in } } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_loadbufferx( L: *mut lua_State, buff: *const c_char, @@ -501,6 +625,7 @@ pub unsafe fn luaL_loadbufferx( luaL_loadbuffer(L, buff, sz, name) } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer { let mut isnum = 0; luaL_checkstack(L, 1, cstr!("not enough stack slots")); @@ -513,6 +638,7 @@ pub unsafe fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer { res } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_traceback( L: *mut lua_State, L1: *mut lua_State, @@ -590,12 +716,14 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> lua_tolstring(L, -1, len) } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char) { luaL_checkstack(L, 1, cstr!("not enough stack slots")); luaL_getmetatable(L, tname); lua_setmetatable(L, -2); } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_testudata(L: *mut lua_State, i: c_int, tname: *const c_char) -> *mut c_void { let mut p = lua_touserdata(L, i); luaL_checkstack(L, 2, cstr!("not enough stack slots")); @@ -612,6 +740,7 @@ pub unsafe fn luaL_testudata(L: *mut lua_State, i: c_int, tname: *const c_char) return p; } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_setfuncs(L: *mut lua_State, mut l: *const luaL_Reg, nup: c_int) { luaL_checkstack(L, nup + 1, cstr!("too many upvalues")); while (*l).name != ptr::null() { @@ -628,6 +757,7 @@ pub unsafe fn luaL_setfuncs(L: *mut lua_State, mut l: *const luaL_Reg, nup: c_in lua_pop(L, nup); // remove upvalues } +#[cfg(any(feature = "lua51", feature = "luajit"))] pub unsafe fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int { let abs_i = lua_absindex(L, idx); luaL_checkstack(L, 3, cstr!("not enough stack slots")); diff --git a/src/ffi/glue/glue.c b/src/ffi/glue/glue.c index d50bbd9..8c2ade3 100644 --- a/src/ffi/glue/glue.c +++ b/src/ffi/glue/glue.c @@ -230,8 +230,10 @@ int main(int argc, const char **argv) { RS_TYPE("LUA_NUMBER", sizeof(LUA_NUMBER) > sizeof(float) ? "c_double" : "c_float"), RS_TYPE("LUA_INTEGER", rs_int_type(sizeof(LUA_INTEGER))), -#if LUA_VERSION_NUM == 503 +#if LUA_VERSION_NUM >= 502 RS_TYPE("LUA_UNSIGNED", rs_uint_type(sizeof(LUA_UNSIGNED))), +#else + RS_TYPE("LUA_UNSIGNED", rs_uint_type(sizeof(size_t))), #endif // == lua.h ============================================================== @@ -263,6 +265,8 @@ int main(int argc, const char **argv) { RS_STR("LUA_STRLIBNAME", LUA_STRLIBNAME), #if LUA_VERSION_NUM == 503 RS_STR("LUA_UTF8LIBNAME", LUA_UTF8LIBNAME), +#endif +#if LUA_VERSION_NUM >= 502 RS_STR("LUA_BITLIBNAME", LUA_BITLIBNAME), #endif RS_STR("LUA_MATHLIBNAME", LUA_MATHLIBNAME), diff --git a/src/ffi/lauxlib.rs b/src/ffi/lauxlib.rs index 9eb0791..9505440 100644 --- a/src/ffi/lauxlib.rs +++ b/src/ffi/lauxlib.rs @@ -31,11 +31,13 @@ use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State}; #[cfg(feature = "lua53")] pub use super::glue::LUAL_NUMSIZES; +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] +pub use super::compat53::{luaL_getmetafield, luaL_newmetatable, luaL_requiref, luaL_tolstring}; + #[cfg(any(feature = "lua51", feature = "luajit"))] pub use super::compat53::{ - luaL_checkversion, luaL_getmetafield, luaL_getsubtable, luaL_len, luaL_loadbufferx, - luaL_newmetatable, luaL_requiref, luaL_setfuncs, luaL_setmetatable, luaL_testudata, - luaL_tolstring, luaL_traceback, + luaL_checkstack, luaL_checkversion, luaL_getsubtable, luaL_len, luaL_loadbufferx, + luaL_setfuncs, luaL_setmetatable, luaL_testudata, luaL_traceback, }; // extra error code for 'luaL_load' @@ -47,25 +49,30 @@ pub struct luaL_Reg { pub func: lua_CFunction, } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn luaL_checkversion(L: *mut lua_State) { + #[cfg(feature = "lua53")] luaL_checkversion_( L, lua::LUA_VERSION_NUM as lua_Number, LUAL_NUMSIZES as usize, - ) + ); + #[cfg(feature = "lua52")] + luaL_checkversion_(L, lua::LUA_VERSION_NUM as lua_Number); } extern "C" { #[cfg(feature = "lua53")] pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize); + #[cfg(feature = "lua52")] + pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number); #[cfg(feature = "lua53")] pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "luaL_getmetafield"] - pub fn luaL_getmetafield_51(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int; + pub fn luaL_getmetafield_old(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int; pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int; #[cfg(feature = "lua53")] @@ -83,19 +90,20 @@ extern "C" { pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer; pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer; + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char); pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int); pub fn luaL_checkany(L: *mut lua_State, arg: c_int); #[cfg(feature = "lua53")] pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "luaL_newmetatable"] - pub fn luaL_newmetatable_51(L: *mut lua_State, tname: *const c_char) -> c_int; + pub fn luaL_newmetatable_old(L: *mut lua_State, tname: *const c_char) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void; pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void; @@ -110,9 +118,9 @@ extern "C" { lst: *const *const c_char, ) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int; } @@ -124,21 +132,21 @@ extern "C" { pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int; pub fn luaL_unref(L: *mut lua_State, t: c_int, r: c_int); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int; #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn luaL_loadfile(L: *mut lua_State, filename: *const c_char) -> c_int; } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int { luaL_loadfilex(L, f, ptr::null()) } extern "C" { - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_loadbufferx( L: *mut lua_State, buff: *const c_char, @@ -157,7 +165,7 @@ extern "C" { pub fn luaL_newstate() -> *mut lua_State; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer; pub fn luaL_gsub( @@ -167,15 +175,16 @@ extern "C" { r: *const c_char, ) -> *const c_char; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int); + // Skip Lua 5.2 implementation in favor of the compat53 one #[cfg(feature = "lua53")] pub fn luaL_requiref( L: *mut lua_State, @@ -279,7 +288,7 @@ pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) { // luaL_opt would be implemented here but it is undocumented, so it's omitted -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn luaL_loadbuffer( L: *mut lua_State, diff --git a/src/ffi/lua.rs b/src/ffi/lua.rs index 7286841..0841427 100644 --- a/src/ffi/lua.rs +++ b/src/ffi/lua.rs @@ -23,7 +23,7 @@ //! Contains definitions from `lua.h`. -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] use std::os::raw::c_uchar; use std::os::raw::{c_char, c_int, c_void}; use std::ptr; @@ -41,15 +41,23 @@ pub const LUA_SIGNATURE: &'static [u8] = b"\x1bLua"; // option for multiple returns in 'lua_pcall' and 'lua_call' pub const LUA_MULTRET: c_int = -1; -#[cfg(any(feature = "lua51", feature = "luajit"))] +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] pub use super::compat53::{ - lua_absindex, lua_compare, lua_copy, lua_getextraspace, lua_getfield, lua_geti, lua_gettable, - lua_getuservalue, lua_isinteger, lua_len, lua_pushglobaltable, lua_pushlstring, lua_pushstring, - lua_rawget, lua_rawgeti, lua_rawgetp, lua_rawlen, lua_rawsetp, lua_resume, lua_rotate, - lua_seti, lua_setuservalue, lua_tointegerx, lua_tonumberx, lua_upvalueindex, + lua_dump, lua_getextraspace, lua_getfield, lua_geti, lua_gettable, lua_getuservalue, + lua_isinteger, lua_pushlstring, lua_rawget, lua_rawgeti, lua_rawgetp, lua_rotate, lua_seti, + lua_stringtonumber, lua_tointegerx, }; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua51", feature = "luajit"))] +pub use super::compat53::{ + lua_absindex, lua_arith, lua_compare, lua_copy, lua_len, lua_pushglobaltable, lua_pushstring, + lua_rawlen, lua_rawsetp, lua_resume, lua_setuservalue, lua_tonumberx, lua_upvalueindex, +}; + +#[cfg(feature = "lua52")] +pub use super::compat53::lua_getglobal; + +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub fn lua_upvalueindex(i: c_int) -> c_int { LUA_REGISTRYINDEX - i @@ -61,11 +69,11 @@ pub const LUA_YIELD: c_int = 1; pub const LUA_ERRRUN: c_int = 2; pub const LUA_ERRSYNTAX: c_int = 3; pub const LUA_ERRMEM: c_int = 4; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_ERRGCMM: c_int = 5; #[cfg(any(feature = "lua51", feature = "luajit"))] pub const LUA_ERRERR: c_int = 5; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_ERRERR: c_int = 6; pub type lua_State = c_void; @@ -83,18 +91,18 @@ pub const LUA_TFUNCTION: c_int = 6; pub const LUA_TUSERDATA: c_int = 7; pub const LUA_TTHREAD: c_int = 8; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_NUMTAGS: c_int = 9; // minimum stack available to a C function pub const LUA_MINSTACK: c_int = 20; // predefined values in the registry -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_RIDX_MAINTHREAD: lua_Integer = 1; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_RIDX_GLOBALS: lua_Integer = 2; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_RIDX_LAST: lua_Integer = LUA_RIDX_GLOBALS; /// A Lua number, usually equivalent to `f64`. @@ -104,7 +112,6 @@ pub type lua_Number = luaconf::LUA_NUMBER; pub type lua_Integer = luaconf::LUA_INTEGER; // unsigned integer type -#[cfg(feature = "lua53")] pub type lua_Unsigned = luaconf::LUA_UNSIGNED; // type for continuation-function contexts @@ -145,20 +152,20 @@ extern "C" { pub fn lua_version(L: *mut lua_State) -> *const lua_Number; // basic stack manipulation - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_absindex(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_gettop(L: *mut lua_State) -> c_int; pub fn lua_settop(L: *mut lua_State, idx: c_int); pub fn lua_pushvalue(L: *mut lua_State, idx: c_int); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] pub fn lua_remove(L: *mut lua_State, idx: c_int); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] pub fn lua_insert(L: *mut lua_State, idx: c_int); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] pub fn lua_replace(L: *mut lua_State, idx: c_int); #[cfg(feature = "lua53")] pub fn lua_rotate(L: *mut lua_State, idx: c_int, n: c_int); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_copy(L: *mut lua_State, fromidx: c_int, toidx: c_int); pub fn lua_checkstack(L: *mut lua_State, sz: c_int) -> c_int; @@ -176,7 +183,7 @@ extern "C" { #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_tonumber(L: *mut lua_State, idx: c_int) -> lua_Number; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number; #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_tointeger(L: *mut lua_State, idx: c_int) -> lua_Integer; @@ -186,7 +193,7 @@ extern "C" { pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char; #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_objlen(L: *mut lua_State, idx: c_int) -> usize; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize; pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> lua_CFunction; pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void; @@ -195,12 +202,19 @@ extern "C" { } // Comparison and arithmetic functions -#[cfg(feature = "lua53")] pub const LUA_OPADD: c_int = 0; -#[cfg(feature = "lua53")] pub const LUA_OPSUB: c_int = 1; -#[cfg(feature = "lua53")] pub const LUA_OPMUL: c_int = 2; + +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] +pub const LUA_OPDIV: c_int = 3; +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] +pub const LUA_OPMOD: c_int = 4; +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] +pub const LUA_OPPOW: c_int = 5; +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] +pub const LUA_OPUNM: c_int = 6; + #[cfg(feature = "lua53")] pub const LUA_OPMOD: c_int = 3; #[cfg(feature = "lua53")] @@ -225,7 +239,7 @@ pub const LUA_OPUNM: c_int = 12; pub const LUA_OPBNOT: c_int = 13; extern "C" { - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_arith(L: *mut lua_State, op: c_int); } @@ -239,7 +253,7 @@ extern "C" { pub fn lua_rawequal(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int; #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_lessthan(L: *mut lua_State, idx1: c_int, idx2: c_int) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_compare(L: *mut lua_State, idx1: c_int, idx2: c_int, op: c_int) -> c_int; } @@ -251,15 +265,15 @@ extern "C" { #[cfg(feature = "lua53")] pub fn lua_pushlstring(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "lua_pushlstring"] - pub fn lua_pushlstring_51(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char; + pub fn lua_pushlstring_old(L: *mut lua_State, s: *const c_char, l: usize) -> *const c_char; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_pushstring(L: *mut lua_State, s: *const c_char) -> *const c_char; #[cfg(any(feature = "lua51", feature = "luajit"))] #[link_name = "lua_pushstring"] - pub fn lua_pushstring_51(L: *mut lua_State, s: *const c_char) -> *const c_char; + pub fn lua_pushstring_old(L: *mut lua_State, s: *const c_char) -> *const c_char; // TODO: omitted: // lua_pushvfstring @@ -274,49 +288,59 @@ extern "C" { extern "C" { #[cfg(feature = "lua53")] pub fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int; + #[cfg(feature = "lua52")] + #[link_name = "lua_getglobal"] + pub fn lua_getglobal_old(L: *mut lua_State, var: *const c_char); #[cfg(feature = "lua53")] pub fn lua_gettable(L: *mut lua_State, idx: c_int) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "lua_gettable"] - pub fn lua_gettable_51(L: *mut lua_State, idx: c_int) -> c_int; + pub fn lua_gettable_old(L: *mut lua_State, idx: c_int); #[cfg(feature = "lua53")] pub fn lua_getfield(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "lua_getfield"] - pub fn lua_getfield_51(L: *mut lua_State, idx: c_int, k: *const c_char) -> c_int; + pub fn lua_getfield_old(L: *mut lua_State, idx: c_int, k: *const c_char); #[cfg(feature = "lua53")] pub fn lua_geti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int; #[cfg(feature = "lua53")] pub fn lua_rawget(L: *mut lua_State, idx: c_int) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "lua_rawget"] - pub fn lua_rawget_51(L: *mut lua_State, idx: c_int); + pub fn lua_rawget_old(L: *mut lua_State, idx: c_int); #[cfg(feature = "lua53")] pub fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] #[link_name = "lua_rawgeti"] - pub fn lua_rawgeti_51(L: *mut lua_State, idx: c_int, n: lua_Integer); + pub fn lua_rawgeti_old(L: *mut lua_State, idx: c_int, n: lua_Integer); #[cfg(feature = "lua53")] pub fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_int; + #[cfg(feature = "lua52")] + #[link_name = "lua_rawgetp"] + pub fn lua_rawgetp_old(L: *mut lua_State, idx: c_int, p: *const c_void); pub fn lua_createtable(L: *mut lua_State, narr: c_int, nrec: c_int); pub fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void; pub fn lua_getmetatable(L: *mut lua_State, objindex: c_int) -> c_int; + #[cfg(feature = "lua53")] pub fn lua_getuservalue(L: *mut lua_State, idx: c_int) -> c_int; + #[cfg(feature = "lua52")] + #[link_name = "lua_getuservalue"] + pub fn lua_getuservalue_old(L: *mut lua_State, idx: c_int); #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_getfenv(L: *mut lua_State, idx: c_int); } // set functions (stack -> Lua) extern "C" { - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_setglobal(L: *mut lua_State, var: *const c_char); pub fn lua_settable(L: *mut lua_State, idx: c_int); pub fn lua_setfield(L: *mut lua_State, idx: c_int, k: *const c_char); @@ -324,10 +348,10 @@ extern "C" { pub fn lua_seti(L: *mut lua_State, idx: c_int, n: lua_Integer); pub fn lua_rawset(L: *mut lua_State, idx: c_int); pub fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void); pub fn lua_setmetatable(L: *mut lua_State, objindex: c_int) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_setuservalue(L: *mut lua_State, idx: c_int); #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_setfenv(L: *mut lua_State, idx: c_int) -> c_int; @@ -343,6 +367,15 @@ extern "C" { ctx: lua_KContext, k: Option, ); + #[cfg(feature = "lua52")] + pub fn lua_callk( + L: *mut lua_State, + nargs: c_int, + nresults: c_int, + ctx: c_int, + k: Option, + ); + #[cfg(feature = "lua53")] pub fn lua_pcallk( L: *mut lua_State, @@ -352,10 +385,25 @@ extern "C" { ctx: lua_KContext, k: Option, ) -> c_int; + #[cfg(feature = "lua52")] + pub fn lua_pcallk( + L: *mut lua_State, + nargs: c_int, + nresults: c_int, + errfunc: c_int, + ctx: c_int, + k: Option, + ) -> c_int; + + #[cfg(feature = "lua52")] + pub fn lua_getctx(L: *mut lua_State, ctx: *mut c_int) -> c_int; + #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_call(L: *mut lua_State, nargs: c_int, nresults: c_int); #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_pcall(L: *mut lua_State, nargs: c_int, nresults: c_int, errfunc: c_int) -> c_int; + + // TODO pub fn lua_load( L: *mut lua_State, reader: lua_Reader, @@ -363,22 +411,26 @@ extern "C" { chunkname: *const c_char, mode: *const c_char, ) -> c_int; - // FIXME + + #[cfg(feature = "lua53")] pub fn lua_dump( L: *mut lua_State, writer: lua_Writer, data: *mut c_void, strip: c_int, ) -> c_int; + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] + #[link_name = "lua_dump"] + pub fn lua_dump_old(L: *mut lua_State, writer: lua_Writer, data: *mut c_void) -> c_int; } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_call(L: *mut lua_State, n: c_int, r: c_int) { lua_callk(L, n, r, 0, None) } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_pcall(L: *mut lua_State, n: c_int, r: c_int, f: c_int) -> c_int { lua_pcallk(L, n, r, f, 0, None) @@ -393,21 +445,28 @@ extern "C" { ctx: lua_KContext, k: Option, ) -> c_int; + #[cfg(feature = "lua52")] + pub fn lua_yieldk( + L: *mut lua_State, + nresults: c_int, + ctx: c_int, + k: Option, + ) -> c_int; #[cfg(any(feature = "lua51", feature = "luajit"))] pub fn lua_yield(L: *mut lua_State, nresults: c_int) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int) -> c_int; #[cfg(any(feature = "lua51", feature = "luajit"))] #[link_name = "lua_resume"] - pub fn lua_resume_51(L: *mut lua_State, narg: c_int) -> c_int; + pub fn lua_resume_old(L: *mut lua_State, narg: c_int) -> c_int; pub fn lua_status(L: *mut lua_State) -> c_int; #[cfg(feature = "lua53")] pub fn lua_isyieldable(L: *mut lua_State) -> c_int; } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_yield(L: *mut lua_State, n: c_int) -> c_int { lua_yieldk(L, n, 0, None) @@ -422,7 +481,7 @@ pub const LUA_GCCOUNTB: c_int = 4; pub const LUA_GCSTEP: c_int = 5; pub const LUA_GCSETPAUSE: c_int = 6; pub const LUA_GCSETSTEPMUL: c_int = 7; -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] pub const LUA_GCISRUNNING: c_int = 9; extern "C" { @@ -434,7 +493,7 @@ extern "C" { pub fn lua_error(L: *mut lua_State) -> !; pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_concat(L: *mut lua_State, n: c_int); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_len(L: *mut lua_State, idx: c_int); #[cfg(feature = "lua53")] pub fn lua_stringtonumber(L: *mut lua_State, s: *const c_char) -> usize; @@ -450,13 +509,13 @@ pub unsafe fn lua_getextraspace(L: *mut lua_State) -> *mut c_void { L.offset(-super::glue::LUA_EXTRASPACE as isize) as *mut c_void } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number { lua_tonumberx(L, i, ptr::null_mut()) } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer { lua_tointegerx(L, i, ptr::null_mut()) @@ -542,7 +601,7 @@ pub unsafe fn lua_getglobal(L: *mut lua_State, var: *const c_char) -> c_int { lua_getfield(L, LUA_GLOBALSINDEX, var) } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[inline(always)] pub unsafe fn lua_pushglobaltable(L: *mut lua_State) -> c_int { lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) @@ -598,9 +657,9 @@ extern "C" { pub fn lua_getupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char; pub fn lua_setupvalue(L: *mut lua_State, funcindex: c_int, n: c_int) -> *const c_char; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_upvalueid(L: *mut lua_State, fidx: c_int, n: c_int) -> *mut c_void; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn lua_upvaluejoin(L: *mut lua_State, fidx1: c_int, n1: c_int, fidx2: c_int, n2: c_int); pub fn lua_sethook(L: *mut lua_State, func: lua_Hook, mask: c_int, count: c_int); @@ -609,7 +668,7 @@ extern "C" { pub fn lua_gethookcount(L: *mut lua_State) -> c_int; } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[repr(C)] pub struct lua_Debug { pub event: c_int, diff --git a/src/ffi/luaconf.rs b/src/ffi/luaconf.rs index f966b46..6233a8a 100644 --- a/src/ffi/luaconf.rs +++ b/src/ffi/luaconf.rs @@ -26,7 +26,6 @@ pub use super::glue::LUAL_BUFFERSIZE; pub use super::glue::LUA_INTEGER; pub use super::glue::LUA_NUMBER; -#[cfg(feature = "lua53")] pub use super::glue::LUA_UNSIGNED; pub use super::glue::LUA_IDSIZE; diff --git a/src/ffi/lualib.rs b/src/ffi/lualib.rs index b3c4998..6c1a720 100644 --- a/src/ffi/lualib.rs +++ b/src/ffi/lualib.rs @@ -32,12 +32,15 @@ pub use super::glue::{ LUA_STRLIBNAME, LUA_TABLIBNAME, }; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use super::glue::LUA_BITLIBNAME; + #[cfg(feature = "lua53")] -pub use super::glue::{LUA_BITLIBNAME, LUA_UTF8LIBNAME}; +pub use super::glue::LUA_UTF8LIBNAME; extern "C" { pub fn luaopen_base(L: *mut lua_State) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaopen_coroutine(L: *mut lua_State) -> c_int; pub fn luaopen_table(L: *mut lua_State) -> c_int; pub fn luaopen_io(L: *mut lua_State) -> c_int; @@ -45,7 +48,7 @@ extern "C" { pub fn luaopen_string(L: *mut lua_State) -> c_int; #[cfg(feature = "lua53")] pub fn luaopen_utf8(L: *mut lua_State) -> c_int; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn luaopen_bit32(L: *mut lua_State) -> c_int; pub fn luaopen_math(L: *mut lua_State) -> c_int; pub fn luaopen_debug(L: *mut lua_State) -> c_int; diff --git a/src/ffi/mod.rs b/src/ffi/mod.rs index 8a4ecaa..33c191a 100644 --- a/src/ffi/mod.rs +++ b/src/ffi/mod.rs @@ -33,11 +33,11 @@ use std::os::raw::c_int; // C API types pub use self::lua::{ lua_Alloc, lua_CFunction, lua_Debug, lua_Hook, lua_Integer, lua_Number, lua_Reader, lua_State, - lua_Writer, + lua_Unsigned, lua_Writer, }; #[cfg(feature = "lua53")] -pub use self::lua::{lua_KContext, lua_KFunction, lua_Unsigned}; +pub use self::lua::{lua_KContext, lua_KFunction}; #[cfg(any(feature = "lua51", feature = "luajit"))] pub use self::lua::lua_setfenv; @@ -45,6 +45,7 @@ pub use self::lua::lua_setfenv; // C API functions pub use self::lua::{ lua_absindex, + lua_arith, lua_atpanic, lua_call, lua_checkstack, @@ -135,6 +136,7 @@ pub use self::lua::{ lua_setupvalue, lua_setuservalue, lua_status, + lua_stringtonumber, lua_toboolean, lua_tocfunction, lua_tointeger, @@ -153,11 +155,11 @@ pub use self::lua::{ lua_yield, }; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use self::lua::{lua_callk, lua_pcallk, lua_upvalueid, lua_upvaluejoin, lua_yieldk}; + #[cfg(feature = "lua53")] -pub use self::lua::{ - lua_arith, lua_callk, lua_isyieldable, lua_pcallk, lua_stringtonumber, lua_upvalueid, - lua_upvaluejoin, lua_version, lua_yieldk, -}; +pub use self::lua::{lua_isyieldable, lua_version}; // auxiliary library types pub use self::lauxlib::luaL_Reg; @@ -166,16 +168,17 @@ pub use self::lauxlib::luaL_Reg; pub use self::lauxlib::{ luaL_argcheck, luaL_argerror, luaL_callmeta, luaL_checkany, luaL_checkint, luaL_checkinteger, luaL_checklong, luaL_checklstring, luaL_checknumber, luaL_checkoption, luaL_checkstack, - luaL_checkstring, luaL_checktype, luaL_checkudata, luaL_dofile, luaL_dostring, luaL_error, - luaL_getmetafield, luaL_getmetatable, luaL_getsubtable, luaL_gsub, luaL_len, luaL_loadbuffer, - luaL_loadbufferx, luaL_loadfile, luaL_loadstring, luaL_newlib, luaL_newlibtable, - luaL_newmetatable, luaL_newstate, luaL_optint, luaL_optinteger, luaL_optlong, luaL_optlstring, - luaL_optnumber, luaL_optstring, luaL_ref, luaL_requiref, luaL_setfuncs, luaL_setmetatable, - luaL_testudata, luaL_tolstring, luaL_traceback, luaL_typename, luaL_unref, luaL_where, + luaL_checkstring, luaL_checktype, luaL_checkudata, luaL_checkversion, luaL_dofile, + luaL_dostring, luaL_error, luaL_getmetafield, luaL_getmetatable, luaL_getsubtable, luaL_gsub, + luaL_len, luaL_loadbuffer, luaL_loadbufferx, luaL_loadfile, luaL_loadstring, luaL_newlib, + luaL_newlibtable, luaL_newmetatable, luaL_newstate, luaL_optint, luaL_optinteger, luaL_optlong, + luaL_optlstring, luaL_optnumber, luaL_optstring, luaL_ref, luaL_requiref, luaL_setfuncs, + luaL_setmetatable, luaL_testudata, luaL_tolstring, luaL_traceback, luaL_typename, luaL_unref, + luaL_where, }; -#[cfg(feature = "lua53")] -pub use self::lauxlib::{luaL_checkversion, luaL_execresult, luaL_fileresult, luaL_loadfilex}; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use self::lauxlib::{luaL_execresult, luaL_fileresult, luaL_loadfilex}; // lualib.h functions pub use self::lualib::{ @@ -183,24 +186,29 @@ pub use self::lualib::{ luaopen_package, luaopen_string, luaopen_table, }; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use self::lualib::{luaopen_bit32, luaopen_coroutine}; + #[cfg(feature = "lua53")] -pub use self::lualib::{luaopen_bit32, luaopen_coroutine, luaopen_utf8}; +pub use self::lualib::luaopen_utf8; // constants from lua.h pub use self::lua::{ LUA_ERRERR, LUA_ERRMEM, LUA_ERRRUN, LUA_ERRSYNTAX, LUA_GCCOLLECT, LUA_GCCOUNT, LUA_GCCOUNTB, LUA_GCRESTART, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, LUA_GCSTEP, LUA_GCSTOP, LUA_HOOKCALL, LUA_HOOKCOUNT, LUA_HOOKLINE, LUA_HOOKRET, LUA_HOOKTAILCALL, LUA_MASKCALL, LUA_MASKCOUNT, - LUA_MASKLINE, LUA_MASKRET, LUA_MINSTACK, LUA_MULTRET, LUA_OK, LUA_OPEQ, LUA_OPLE, LUA_OPLT, - LUA_REGISTRYINDEX, LUA_TBOOLEAN, LUA_TFUNCTION, LUA_TLIGHTUSERDATA, LUA_TNIL, LUA_TNONE, - LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TTHREAD, LUA_TUSERDATA, LUA_YIELD, + LUA_MASKLINE, LUA_MASKRET, LUA_MINSTACK, LUA_MULTRET, LUA_OK, LUA_OPADD, LUA_OPDIV, LUA_OPEQ, + LUA_OPLE, LUA_OPLT, LUA_OPMOD, LUA_OPMUL, LUA_OPPOW, LUA_OPSUB, LUA_OPUNM, LUA_REGISTRYINDEX, + LUA_TBOOLEAN, LUA_TFUNCTION, LUA_TLIGHTUSERDATA, LUA_TNIL, LUA_TNONE, LUA_TNUMBER, LUA_TSTRING, + LUA_TTABLE, LUA_TTHREAD, LUA_TUSERDATA, LUA_YIELD, }; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use self::lua::{LUA_ERRGCMM, LUA_GCISRUNNING, LUA_RIDX_GLOBALS, LUA_RIDX_MAINTHREAD}; + #[cfg(feature = "lua53")] pub use self::lua::{ - LUA_ERRGCMM, LUA_GCISRUNNING, LUA_OPADD, LUA_OPBAND, LUA_OPBNOT, LUA_OPBOR, LUA_OPBXOR, - LUA_OPDIV, LUA_OPIDIV, LUA_OPMOD, LUA_OPMUL, LUA_OPPOW, LUA_OPSHL, LUA_OPSHR, LUA_OPSUB, - LUA_OPUNM, LUA_RIDX_GLOBALS, LUA_RIDX_MAINTHREAD, + LUA_OPBAND, LUA_OPBNOT, LUA_OPBOR, LUA_OPBXOR, LUA_OPIDIV, LUA_OPSHL, LUA_OPSHR, }; #[cfg(any(feature = "lua51", feature = "luajit"))] @@ -215,8 +223,11 @@ pub use self::lualib::{ LUA_STRLIBNAME, LUA_TABLIBNAME, }; +#[cfg(any(feature = "lua53", feature = "lua52"))] +pub use self::lualib::LUA_BITLIBNAME; + #[cfg(feature = "lua53")] -pub use self::lualib::{LUA_BITLIBNAME, LUA_UTF8LIBNAME}; +pub use self::lualib::LUA_UTF8LIBNAME; // Not actually defined in lua.h / luaconf.h pub const LUA_MAX_UPVALUES: c_int = 255; @@ -226,7 +237,7 @@ mod glue { include!(concat!(env!("OUT_DIR"), "/glue.rs")); } -#[cfg(any(feature = "lua51", feature = "luajit"))] +#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] mod compat53; mod lauxlib; diff --git a/src/lua.rs b/src/lua.rs index 9b8d7d4..0b6d80c 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -72,7 +72,7 @@ impl Lua { let state = ffi::luaL_newstate(); ffi::luaL_requiref(state, cstr!("_G"), ffi::luaopen_base, 1); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] ffi::luaL_requiref(state, cstr!("coroutine"), ffi::luaopen_coroutine, 1); ffi::luaL_requiref(state, cstr!("table"), ffi::luaopen_table, 1); ffi::luaL_requiref(state, cstr!("io"), ffi::luaopen_io, 1); @@ -80,9 +80,13 @@ impl Lua { ffi::luaL_requiref(state, cstr!("string"), ffi::luaopen_string, 1); #[cfg(feature = "lua53")] ffi::luaL_requiref(state, cstr!("utf8"), ffi::luaopen_utf8, 1); + #[cfg(any(feature = "lua53", feature = "lua52"))] + ffi::luaL_requiref(state, cstr!("bit32"), ffi::luaopen_bit32, 1); ffi::luaL_requiref(state, cstr!("math"), ffi::luaopen_math, 1); ffi::luaL_requiref(state, cstr!("package"), ffi::luaopen_package, 1); #[cfg(feature = "lua53")] + ffi::lua_pop(state, 10); + #[cfg(feature = "lua52")] ffi::lua_pop(state, 9); #[cfg(any(feature = "lua51", feature = "luajit"))] ffi::lua_pop(state, 7); @@ -95,7 +99,7 @@ impl Lua { /// Constructs a new Lua instance from the existing state. pub unsafe fn init_from_ptr(state: *mut ffi::lua_State) -> Lua { - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] let main_state = get_main_state(state); #[cfg(any(feature = "lua51", feature = "luajit"))] let main_state = { @@ -195,7 +199,7 @@ impl Lua { } /// Returns true if the garbage collector is currently running automatically. - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] pub fn gc_is_running(&self) -> bool { unsafe { ffi::lua_gc(self.main_state, ffi::LUA_GCISRUNNING, 0) != 0 } } @@ -314,7 +318,7 @@ impl Lua { ffi::LUA_OK => { if let Some(env) = env { self.push_value(env)?; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] ffi::lua_setupvalue(self.state, -2, 1); #[cfg(any(feature = "lua51", feature = "luajit"))] ffi::lua_setfenv(self.state, -2); @@ -505,7 +509,7 @@ impl Lua { unsafe { let _sg = StackGuard::new(self.state); assert_stack(self.state, 2); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] ffi::lua_rawgeti(self.state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS); #[cfg(any(feature = "lua51", feature = "luajit"))] ffi::lua_pushvalue(self.state, ffi::LUA_GLOBALSINDEX); diff --git a/src/scope.rs b/src/scope.rs index aecf38c..ec354af 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -175,7 +175,7 @@ impl<'lua, 'scope> Scope<'lua, 'scope> { assert_stack(lua.state, 1); lua.push_ref(&u.0); ffi::lua_getuservalue(lua.state, -1); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] { ffi::lua_pushinteger(lua.state, 1); ffi::lua_gettable(lua.state, -2); @@ -247,9 +247,9 @@ impl<'lua, 'scope> Scope<'lua, 'scope> { push_userdata(lua.state, ())?; #[cfg(feature = "lua53")] ffi::lua_pushlightuserdata(lua.state, data.as_ptr() as *mut c_void); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] protect_lua_closure(lua.state, 0, 1, |state| { - // Lua 5.1 allows to store only table. Then we will wrap the value. + // Lua 5.2/5.1 allows to store only table. Then we will wrap the value. ffi::lua_createtable(state, 1, 0); ffi::lua_pushinteger(state, 1); ffi::lua_pushlightuserdata(state, data.as_ptr() as *mut c_void); diff --git a/src/userdata.rs b/src/userdata.rs index 15c200e..18da3b4 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -29,18 +29,25 @@ pub enum MetaMethod { Pow, /// The unary minus (`-`) operator. Unm, + #[cfg(feature = "lua53")] /// The floor division (//) operator. IDiv, + #[cfg(feature = "lua53")] /// The bitwise AND (&) operator. BAnd, + #[cfg(feature = "lua53")] /// The bitwise OR (|) operator. BOr, + #[cfg(feature = "lua53")] /// The bitwise XOR (binary ~) operator. BXor, + #[cfg(feature = "lua53")] /// The bitwise NOT (unary ~) operator. BNot, + #[cfg(feature = "lua53")] /// The bitwise left shift (<<) operator. Shl, + #[cfg(feature = "lua53")] /// The bitwise right shift (>>) operator. Shr, /// The string concatenation operator `..`. @@ -75,12 +82,19 @@ impl MetaMethod { MetaMethod::Mod => b"__mod", MetaMethod::Pow => b"__pow", MetaMethod::Unm => b"__unm", + #[cfg(feature = "lua53")] MetaMethod::IDiv => b"__idiv", + #[cfg(feature = "lua53")] MetaMethod::BAnd => b"__band", + #[cfg(feature = "lua53")] MetaMethod::BOr => b"__bor", + #[cfg(feature = "lua53")] MetaMethod::BXor => b"__bxor", + #[cfg(feature = "lua53")] MetaMethod::BNot => b"__bnot", + #[cfg(feature = "lua53")] MetaMethod::Shl => b"__shl", + #[cfg(feature = "lua53")] MetaMethod::Shr => b"__shr", MetaMethod::Concat => b"__concat", MetaMethod::Len => b"__len", @@ -333,9 +347,9 @@ impl<'lua> AnyUserData<'lua> { /// [`get_user_value`]: #method.get_user_value pub fn set_user_value>(&self, v: V) -> Result<()> { let lua = self.0.lua; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] let v = { - // Lua 5.1 allows to store only table. Then we will wrap the value. + // Lua 5.2/5.1 allows to store only table. Then we will wrap the value. let t = lua.create_table()?; t.raw_set(1, v)?; crate::Value::Table(t) @@ -364,7 +378,7 @@ impl<'lua> AnyUserData<'lua> { ffi::lua_getuservalue(lua.state, -1); lua.pop_value() }; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] return crate::Table::from_lua(res, lua)?.get(1); #[cfg(feature = "lua53")] V::from_lua(res, lua) diff --git a/src/util.rs b/src/util.rs index d8b9c50..b3cf022 100644 --- a/src/util.rs +++ b/src/util.rs @@ -205,7 +205,7 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error { Error::RuntimeError(err_string) } ffi::LUA_ERRMEM => Error::MemoryError(err_string), - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] ffi::LUA_ERRGCMM => Error::GarbageCollectorError(err_string), _ => mlua_panic!("unrecognized lua error code"), } @@ -453,7 +453,7 @@ pub unsafe fn set_main_state(state: *mut ffi::lua_State) { // Does not call lua_checkstack, uses 1 stack space. pub unsafe fn get_main_state(state: *mut ffi::lua_State) -> *mut ffi::lua_State { - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_MAINTHREAD); #[cfg(any(feature = "lua51", feature = "luajit"))] { diff --git a/tests/compile_fail/lua_norefunwindsafe.stderr b/tests/compile_fail/lua_norefunwindsafe.stderr index 5bdd274..8a1309f 100644 --- a/tests/compile_fail/lua_norefunwindsafe.stderr +++ b/tests/compile_fail/lua_norefunwindsafe.stderr @@ -1,43 +1,40 @@ error[E0277]: the type `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/lua_norefunwindsafe.rs:7:5 - | -7 | catch_unwind(|| lua.create_table().unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` - = note: required by `std::panic::catch_unwind` + --> $DIR/lua_norefunwindsafe.rs:7:5 + | +7 | catch_unwind(|| lua.create_table().unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` error[E0277]: the type `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/lua_norefunwindsafe.rs:7:5 - | -7 | catch_unwind(|| lua.create_table().unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` - = note: required because it appears within the type `std::cell::RefCell` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `std::sync::Arc>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` - = note: required by `std::panic::catch_unwind` + --> $DIR/lua_norefunwindsafe.rs:7:5 + | +7 | catch_unwind(|| lua.create_table().unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` + = note: required because it appears within the type `std::cell::RefCell` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `std::sync::Arc>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` error[E0277]: the type `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/lua_norefunwindsafe.rs:7:5 - | -7 | catch_unwind(|| lua.create_table().unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` - = note: required because it appears within the type `std::cell::Cell` - = note: required because it appears within the type `std::cell::RefCell` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `std::sync::Arc>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` - = note: required by `std::panic::catch_unwind` + --> $DIR/lua_norefunwindsafe.rs:7:5 + | +7 | catch_unwind(|| lua.create_table().unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` + = note: required because it appears within the type `std::cell::Cell` + = note: required because it appears within the type `std::cell::RefCell` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `std::sync::Arc>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/lua_norefunwindsafe.rs:7:18: 7:48 lua:&mlua::lua::Lua]` diff --git a/tests/compile_fail/ref_nounwindsafe.stderr b/tests/compile_fail/ref_nounwindsafe.stderr index 4047f3d..644a2d8 100644 --- a/tests/compile_fail/ref_nounwindsafe.stderr +++ b/tests/compile_fail/ref_nounwindsafe.stderr @@ -1,49 +1,46 @@ error[E0277]: the type `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/ref_nounwindsafe.rs:8:5 - | -8 | catch_unwind(move || table.set("a", "b").unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `mlua::types::LuaRef<'_>` - = note: required because it appears within the type `mlua::table::Table<'_>` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` - = note: required by `std::panic::catch_unwind` + --> $DIR/ref_nounwindsafe.rs:8:5 + | +8 | catch_unwind(move || table.set("a", "b").unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell<()>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell<()>` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `mlua::types::LuaRef<'_>` + = note: required because it appears within the type `mlua::table::Table<'_>` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` error[E0277]: the type `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/ref_nounwindsafe.rs:8:5 - | -8 | catch_unwind(move || table.set("a", "b").unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` - = note: required because it appears within the type `std::cell::RefCell` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `std::sync::Arc>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `mlua::types::LuaRef<'_>` - = note: required because it appears within the type `mlua::table::Table<'_>` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` - = note: required by `std::panic::catch_unwind` + --> $DIR/ref_nounwindsafe.rs:8:5 + | +8 | catch_unwind(move || table.set("a", "b").unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` + = note: required because it appears within the type `std::cell::RefCell` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `std::sync::Arc>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `mlua::types::LuaRef<'_>` + = note: required because it appears within the type `mlua::table::Table<'_>` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` error[E0277]: the type `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - --> $DIR/ref_nounwindsafe.rs:8:5 - | -8 | catch_unwind(move || table.set("a", "b").unwrap()); - | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary - | - = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` - = note: required because it appears within the type `std::cell::Cell` - = note: required because it appears within the type `std::cell::RefCell` - = note: required because it appears within the type `std::marker::PhantomData>` - = note: required because it appears within the type `std::sync::Arc>` - = note: required because it appears within the type `mlua::lua::Lua` - = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` - = note: required because it appears within the type `mlua::types::LuaRef<'_>` - = note: required because it appears within the type `mlua::table::Table<'_>` - = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` - = note: required by `std::panic::catch_unwind` + --> $DIR/ref_nounwindsafe.rs:8:5 + | +8 | catch_unwind(move || table.set("a", "b").unwrap()); + | ^^^^^^^^^^^^ `std::cell::UnsafeCell` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary + | + = help: within `mlua::lua::Lua`, the trait `std::panic::RefUnwindSafe` is not implemented for `std::cell::UnsafeCell` + = note: required because it appears within the type `std::cell::Cell` + = note: required because it appears within the type `std::cell::RefCell` + = note: required because it appears within the type `std::marker::PhantomData>` + = note: required because it appears within the type `std::sync::Arc>` + = note: required because it appears within the type `mlua::lua::Lua` + = note: required because of the requirements on the impl of `std::panic::UnwindSafe` for `&mlua::lua::Lua` + = note: required because it appears within the type `mlua::types::LuaRef<'_>` + = note: required because it appears within the type `mlua::table::Table<'_>` + = note: required because it appears within the type `[closure@$DIR/tests/compile_fail/ref_nounwindsafe.rs:8:18: 8:54 table:mlua::table::Table<'_>]` diff --git a/tests/memory.rs b/tests/memory.rs index e3f8063..7c141cd 100644 --- a/tests/memory.rs +++ b/tests/memory.rs @@ -17,7 +17,7 @@ use mlua::{Lua, Result, UserData}; fn test_gc_control() -> Result<()> { let lua = Lua::new(); - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] { assert!(lua.gc_is_running()); lua.gc_stop(); @@ -42,7 +42,7 @@ fn test_gc_control() -> Result<()> { Ok(()) } -#[cfg(feature = "lua53")] +#[cfg(any(feature = "lua53", feature = "lua52"))] #[test] fn test_gc_error() { use mlua::Error; diff --git a/tests/tests.rs b/tests/tests.rs index 6477204..2e71dc1 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -194,8 +194,8 @@ fn test_error() -> Result<()> { end, 3) local function handler(err) - if string.match(_VERSION, ' 5%.1$') then - -- Special case for Lua 5.1 + if string.match(_VERSION, ' 5%.1$') or string.match(_VERSION, ' 5%.2$') then + -- Special case for Lua 5.1/5.2 local caps = string.match(err, ': (%d+)$') if caps then err = caps @@ -402,7 +402,7 @@ fn test_num_conversion() -> Result<()> { assert_eq!(lua.load("1.0").eval::()?, 1.0); #[cfg(feature = "lua53")] assert_eq!(lua.load("1.0").eval::()?, "1.0"); - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))] assert_eq!(lua.load("1.0").eval::()?, "1"); assert_eq!(lua.load("1.5").eval::()?, 1); @@ -434,7 +434,7 @@ fn test_pcall_xpcall() -> Result<()> { assert!(lua.load("xpcall()").exec().is_err()); assert!(lua.load("xpcall(function() end)").exec().is_err()); - // Lua 5.3 / LuaJIT compatible version of xpcall + // Lua 5.3/5.2 / LuaJIT compatible version of xpcall #[cfg(feature = "lua51")] lua.load( r#" @@ -477,7 +477,7 @@ fn test_pcall_xpcall() -> Result<()> { assert_eq!(globals.get::<_, String>("pcall_error")?, "testerror"); assert_eq!(globals.get::<_, bool>("xpcall_statusr")?, false); - #[cfg(any(feature = "lua53", feature = "luajit"))] + #[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit"))] assert_eq!( globals.get::<_, std::string::String>("xpcall_error")?, "testerror" @@ -810,7 +810,7 @@ fn context_thread() -> Result<()> { ) .into_function()?; - #[cfg(feature = "lua53")] + #[cfg(any(feature = "lua53", feature = "lua52"))] f.call::<_, ()>(lua.current_thread())?; #[cfg(any(feature = "lua51", feature = "luajit"))] diff --git a/tests/thread.rs b/tests/thread.rs index 24f3b10..3344b7c 100644 --- a/tests/thread.rs +++ b/tests/thread.rs @@ -111,7 +111,7 @@ fn coroutine_from_closure() -> Result<()> { let thrd_main = lua.create_function(|_, ()| Ok(()))?; lua.globals().set("main", thrd_main)?; - #[cfg(any(feature = "lua53", feature = "luajit"))] + #[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit"))] let thrd: Thread = lua.load("coroutine.create(main)").eval()?; #[cfg(feature = "lua51")] let thrd: Thread = lua