From 806f0bcef4fbedb7f486f3bd3d03ba0ba3bd8a65 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Thu, 4 Nov 2021 12:25:20 +0000 Subject: [PATCH] Add luajit52 support (LuaJIT with partial compatibility with Lua 5.2) --- Cargo.toml | 3 ++- README.md | 1 + build/find_vendored.rs | 8 +++++++- build/main.rs | 20 +++++++++++++++----- src/userdata.rs | 28 ++++++++++++++++++++++------ src/util.rs | 9 +++++++-- tests/tests.rs | 11 ++++++++--- tests/userdata.rs | 34 ++++++++++++++++++++++++---------- 8 files changed, 86 insertions(+), 28 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index cbd4b7e..4107d6c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,7 @@ lua53 = [] lua52 = [] lua51 = [] luajit = [] +luajit52 = ["luajit"] vendored = ["lua-src", "luajit-src"] module = ["mlua_derive"] async = ["futures-core", "futures-task", "futures-util"] @@ -56,7 +57,7 @@ erased-serde = { version = "0.3", optional = true } cc = { version = "1.0" } pkg-config = { version = "0.3.17" } lua-src = { version = ">= 540.0.0, < 550.0.0", optional = true } -luajit-src = { version = ">= 210.1.2, < 220.0.0", optional = true } +luajit-src = { version = ">= 210.3.1, < 220.0.0", optional = true } [dev-dependencies] rustyline = "8.0" diff --git a/README.md b/README.md index 4bf5df4..68a7b71 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Below is a list of the available feature flags. By default `mlua` does not enabl * `lua52`: activate Lua [5.2] support * `lua51`: activate Lua [5.1] support * `luajit`: activate [LuaJIT] support +* `luajit52`: activate [LuaJIT] support with partial compatibility with Lua 5.2 * `vendored`: build static Lua(JIT) library from sources during `mlua` compilation using [lua-src] or [luajit-src] crates * `module`: enable module mode (building loadable `cdylib` library for Lua) * `async`: enable async/await support (any executor can be used, eg. [tokio] or [async-std]) diff --git a/build/find_vendored.rs b/build/find_vendored.rs index 25ed510..46b87d3 100644 --- a/build/find_vendored.rs +++ b/build/find_vendored.rs @@ -10,7 +10,13 @@ pub fn probe_lua() -> PathBuf { #[cfg(feature = "lua51")] let artifacts = lua_src::Build::new().build(lua_src::Lua51); #[cfg(feature = "luajit")] - let artifacts = luajit_src::Build::new().build(); + let artifacts = { + let mut builder = luajit_src::Build::new(); + if cfg!(feature = "luajit52") { + builder.lua52compat(true); + } + builder.build() + }; #[cfg(not(feature = "module"))] artifacts.print_cargo_metadata(); diff --git a/build/main.rs b/build/main.rs index c17f11c..833766d 100644 --- a/build/main.rs +++ b/build/main.rs @@ -201,7 +201,9 @@ fn main() { feature = "lua51", feature = "luajit" )))] - compile_error!("You must enable one of the features: lua54, lua53, lua52, lua51, luajit"); + compile_error!( + "You must enable one of the features: lua54, lua53, lua52, lua51, luajit, luajit52" + ); #[cfg(all( feature = "lua54", @@ -212,19 +214,27 @@ fn main() { feature = "luajit" ) ))] - compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit"); + compile_error!( + "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52" + ); #[cfg(all( feature = "lua53", any(feature = "lua52", feature = "lua51", feature = "luajit") ))] - compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit"); + compile_error!( + "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52" + ); #[cfg(all(feature = "lua52", any(feature = "lua51", feature = "luajit")))] - compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit"); + compile_error!( + "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52" + ); #[cfg(all(feature = "lua51", feature = "luajit"))] - compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit"); + compile_error!( + "You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52" + ); // We don't support "vendored module" mode on windows #[cfg(all(feature = "vendored", feature = "module", target_os = "windows"))] diff --git a/src/userdata.rs b/src/userdata.rs index fce6973..43e4a08 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -102,7 +102,13 @@ pub enum MetaMethod { /// This is not an operator, but it will be called by the built-in `pairs` function. /// /// Requires `feature = "lua54/lua53/lua52"` - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", doc))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52", + doc + ))] Pairs, /// The `__ipairs` metamethod. /// @@ -111,7 +117,7 @@ pub enum MetaMethod { /// Requires `feature = "lua52"` /// /// [`ipairs`]: https://www.lua.org/manual/5.2/manual.html#pdf-ipairs - #[cfg(any(feature = "lua52", doc))] + #[cfg(any(feature = "lua52", feature = "luajit52", doc))] IPairs, /// The `__close` metamethod. /// @@ -188,9 +194,14 @@ impl MetaMethod { MetaMethod::Call => "__call", MetaMethod::ToString => "__tostring", - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] MetaMethod::Pairs => "__pairs", - #[cfg(feature = "lua52")] + #[cfg(any(feature = "lua52", feature = "luajit52"))] MetaMethod::IPairs => "__ipairs", #[cfg(feature = "lua54")] @@ -250,9 +261,14 @@ impl From for MetaMethod { "__call" => MetaMethod::Call, "__tostring" => MetaMethod::ToString, - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] "__pairs" => MetaMethod::Pairs, - #[cfg(feature = "lua52")] + #[cfg(any(feature = "lua52", feature = "luajit52"))] "__ipairs" => MetaMethod::IPairs, #[cfg(feature = "lua54")] diff --git a/src/util.rs b/src/util.rs index c16c826..c028758 100644 --- a/src/util.rs +++ b/src/util.rs @@ -842,9 +842,14 @@ pub unsafe fn init_error_registry(state: *mut ffi::lua_State) -> Result<()> { "__newindex", "__call", "__tostring", - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] "__pairs", - #[cfg(any(feature = "lua53", feature = "lua52"))] + #[cfg(any(feature = "lua53", feature = "lua52", feature = "luajit52"))] "__ipairs", #[cfg(feature = "lua54")] "__close", diff --git a/tests/tests.rs b/tests/tests.rs index 7973cb0..4d76adb 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -1077,17 +1077,22 @@ fn test_context_thread() -> Result<()> { ) .into_function()?; - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] f.call::<_, ()>(lua.current_thread())?; - #[cfg(any(feature = "lua51", feature = "luajit"))] + #[cfg(any(feature = "lua51", all(feature = "luajit", not(feature = "luajit52"))))] f.call::<_, ()>(Nil)?; Ok(()) } #[test] -#[cfg(any(feature = "lua51", feature = "luajit"))] +#[cfg(any(feature = "lua51", all(feature = "luajit", not(feature = "luajit52"))))] fn test_context_thread_51() -> Result<()> { let lua = Lua::new(); diff --git a/tests/userdata.rs b/tests/userdata.rs index 65a3fb2..958da92 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -111,7 +111,12 @@ fn test_metamethods() -> Result<()> { Err("no such custom index".to_lua_err()) } }); - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] methods.add_meta_method(MetaMethod::Pairs, |lua, data, ()| { use std::iter::FromIterator; let stateless_iter = lua.create_function(|_, (data, i): (MyUserData, i64)| { @@ -136,11 +141,16 @@ fn test_metamethods() -> Result<()> { 10 ); - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] - let pairs_it = { - lua.load( + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] + let pairs_it = lua + .load( r#" - function pairs_it() + function() local r = 0 for i, v in pairs(userdata1) do r = r + v @@ -149,17 +159,21 @@ fn test_metamethods() -> Result<()> { end "#, ) - .exec()?; - globals.get::<_, Function>("pairs_it")? - }; + .eval::()?; assert_eq!(lua.load("userdata1 - userdata2").eval::()?.0, 4); assert_eq!(lua.load("userdata1:get()").eval::()?, 7); assert_eq!(lua.load("userdata2.inner").eval::()?, 3); - #[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))] - assert_eq!(pairs_it.call::<_, i64>(())?, 28); assert!(lua.load("userdata2.nonexist_field").eval::<()>().is_err()); + #[cfg(any( + feature = "lua54", + feature = "lua53", + feature = "lua52", + feature = "luajit52" + ))] + assert_eq!(pairs_it.call::<_, i64>(())?, 28); + let userdata2: Value = globals.get("userdata2")?; let userdata3: Value = globals.get("userdata3")?;