Add luajit52 support (LuaJIT with partial compatibility with Lua 5.2)

This commit is contained in:
Alex Orlenko 2021-11-04 12:25:20 +00:00
parent 0741db7565
commit 806f0bcef4
No known key found for this signature in database
GPG key ID: 4C150C250863B96D
8 changed files with 86 additions and 28 deletions

View file

@ -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"

View file

@ -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])

View file

@ -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();

View file

@ -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"))]

View file

@ -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<StdString> 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")]

View file

@ -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",

View file

@ -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();

View file

@ -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::<Function>()?;
assert_eq!(lua.load("userdata1 - userdata2").eval::<MyUserData>()?.0, 4);
assert_eq!(lua.load("userdata1:get()").eval::<i64>()?, 7);
assert_eq!(lua.load("userdata2.inner").eval::<i64>()?, 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")?;