Skip to content

Commit da52659

Browse files
committed
mlua-sys: Add Lua 5.5 support
1 parent 39a7d3b commit da52659

File tree

10 files changed

+888
-24
lines changed

10 files changed

+888
-24
lines changed

mlua-sys/Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ license = "MIT"
1212
links = "lua"
1313
build = "build/main.rs"
1414
description = """
15-
Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
15+
Low level (FFI) bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
1616
"""
1717

1818
[package.metadata.docs.rs]
19-
features = ["lua54", "vendored"]
19+
features = ["lua55", "vendored"]
2020
rustdoc-args = ["--cfg", "docsrs"]
2121

2222
[features]
23+
lua55 = []
2324
lua54 = []
2425
lua53 = []
2526
lua52 = []
@@ -34,12 +35,13 @@ external = []
3435
module = []
3536

3637
[dependencies]
38+
libc = "0.2"
3739

3840
[build-dependencies]
3941
cc = "1.0"
4042
cfg-if = "1.0"
4143
pkg-config = "0.3.17"
42-
lua-src = { version = ">= 548.1.0, < 548.2.0", optional = true }
44+
lua-src = { version = ">= 550.0.0, < 550.1.0", optional = true }
4345
luajit-src = { version = ">= 210.6.0, < 210.7.0", optional = true }
4446
luau0-src = { version = "0.17.0", optional = true }
4547

mlua-sys/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
# mlua-sys
22

3-
Low level (FFI) bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and [Luau].
3+
Low level (FFI) bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including [LuaJIT]) and [Luau].
44

55
Intended to be consumed by the [mlua] crate.
66

7+
[LuaJIT]: https://github.com/LuaJIT/LuaJIT
78
[Luau]: https://github.com/luau-lang/luau
89
[mlua]: https://crates.io/crates/mlua

mlua-sys/build/find_normal.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,16 @@ pub fn probe_lua() {
3131

3232
// Find using `pkg-config`
3333

34+
#[cfg(feature = "lua55")]
35+
let (incl_bound, excl_bound, alt_probe, ver) = ("5.5", "5.6", ["lua5.5", "lua-5.5", "lua55"], "5.5");
3436
#[cfg(feature = "lua54")]
35-
let (incl_bound, excl_bound, alt_probe, ver) =
36-
("5.4", "5.5", ["lua5.4", "lua-5.4", "lua54"], "5.4");
37+
let (incl_bound, excl_bound, alt_probe, ver) = ("5.4", "5.5", ["lua5.4", "lua-5.4", "lua54"], "5.4");
3738
#[cfg(feature = "lua53")]
38-
let (incl_bound, excl_bound, alt_probe, ver) =
39-
("5.3", "5.4", ["lua5.3", "lua-5.3", "lua53"], "5.3");
39+
let (incl_bound, excl_bound, alt_probe, ver) = ("5.3", "5.4", ["lua5.3", "lua-5.3", "lua53"], "5.3");
4040
#[cfg(feature = "lua52")]
41-
let (incl_bound, excl_bound, alt_probe, ver) =
42-
("5.2", "5.3", ["lua5.2", "lua-5.2", "lua52"], "5.2");
41+
let (incl_bound, excl_bound, alt_probe, ver) = ("5.2", "5.3", ["lua5.2", "lua-5.2", "lua52"], "5.2");
4342
#[cfg(feature = "lua51")]
44-
let (incl_bound, excl_bound, alt_probe, ver) =
45-
("5.1", "5.2", ["lua5.1", "lua-5.1", "lua51"], "5.1");
43+
let (incl_bound, excl_bound, alt_probe, ver) = ("5.1", "5.2", ["lua5.1", "lua-5.1", "lua51"], "5.1");
4644
#[cfg(feature = "luajit")]
4745
let (incl_bound, excl_bound, alt_probe, ver) = ("2.0.4", "2.2", [], "JIT");
4846

@@ -54,9 +52,7 @@ pub fn probe_lua() {
5452

5553
if lua.is_err() {
5654
for pkg in alt_probe {
57-
lua = pkg_config::Config::new()
58-
.cargo_metadata(true)
59-
.probe(pkg);
55+
lua = pkg_config::Config::new().cargo_metadata(true).probe(pkg);
6056

6157
if lua.is_ok() {
6258
break;

mlua-sys/build/find_vendored.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#![allow(dead_code)]
22

33
pub fn probe_lua() {
4+
#[cfg(feature = "lua55")]
5+
let artifacts = lua_src::Build::new().build(lua_src::Lua55);
6+
47
#[cfg(feature = "lua54")]
58
let artifacts = lua_src::Build::new().build(lua_src::Lua54);
69

mlua-sys/build/main.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
cfg_if::cfg_if! {
2-
if #[cfg(all(feature = "lua54", not(any(feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
2+
if #[cfg(all(feature = "lua55", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
33
include!("main_inner.rs");
4-
} else if #[cfg(all(feature = "lua53", not(any(feature = "lua54", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
4+
} else if #[cfg(all(feature = "lua54", not(any(feature = "lua55", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
55
include!("main_inner.rs");
6-
} else if #[cfg(all(feature = "lua52", not(any(feature = "lua54", feature = "lua53", feature = "lua51", feature = "luajit", feature = "luau"))))] {
6+
} else if #[cfg(all(feature = "lua53", not(any(feature = "lua55", feature = "lua54", feature = "lua52", feature = "lua51", feature = "luajit", feature = "luau"))))] {
77
include!("main_inner.rs");
8-
} else if #[cfg(all(feature = "lua51", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit", feature = "luau"))))] {
8+
} else if #[cfg(all(feature = "lua52", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua51", feature = "luajit", feature = "luau"))))] {
99
include!("main_inner.rs");
10-
} else if #[cfg(all(feature = "luajit", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luau"))))] {
10+
} else if #[cfg(all(feature = "lua51", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "luajit", feature = "luau"))))] {
1111
include!("main_inner.rs");
12-
} else if #[cfg(all(feature = "luau", not(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit"))))] {
12+
} else if #[cfg(all(feature = "luajit", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luau"))))] {
13+
include!("main_inner.rs");
14+
} else if #[cfg(all(feature = "luau", not(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52", feature = "lua51", feature = "luajit"))))] {
1315
include!("main_inner.rs");
1416
} else {
1517
fn main() {
16-
compile_error!("You can enable only one of the features: lua54, lua53, lua52, lua51, luajit, luajit52, luau");
18+
compile_error!("You can enable only one of the features: lua55, lua54, lua53, lua52, lua51, luajit, luajit52, luau");
1719
}
1820
}
1921
}

mlua-sys/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! Low level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau.
1+
//! Low level bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau.
22
33
#![allow(non_camel_case_types, non_snake_case)]
44
#![allow(clippy::missing_safety_doc)]
@@ -8,6 +8,9 @@
88

99
use std::os::raw::c_int;
1010

11+
#[cfg(any(feature = "lua55", doc))]
12+
pub use lua55::*;
13+
1114
#[cfg(any(feature = "lua54", doc))]
1215
pub use lua54::*;
1316

@@ -23,7 +26,7 @@ pub use lua51::*;
2326
#[cfg(any(feature = "luau", doc))]
2427
pub use luau::*;
2528

26-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
29+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
2730
#[doc(hidden)]
2831
pub const LUA_MAX_UPVALUES: c_int = 255;
2932

@@ -87,6 +90,10 @@ pub const SYS_MIN_ALIGN: usize = if cfg!(any(
8790
#[macro_use]
8891
mod macros;
8992

93+
#[cfg(any(feature = "lua55", doc))]
94+
#[cfg_attr(docsrs, doc(cfg(feature = "lua55")))]
95+
pub mod lua55;
96+
9097
#[cfg(any(feature = "lua54", doc))]
9198
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
9299
pub mod lua54;

mlua-sys/src/lua55/lauxlib.rs

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
//! Contains definitions from `lauxlib.h`.
2+
3+
use std::os::raw::{c_char, c_int, c_uint, c_void};
4+
use std::ptr;
5+
6+
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
7+
8+
// Extra error code for 'luaL_loadfilex'
9+
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
10+
11+
// Key, in the registry, for table of loaded modules
12+
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
13+
14+
// Key, in the registry, for table of preloaded loaders
15+
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
16+
17+
#[repr(C)]
18+
pub struct luaL_Reg {
19+
pub name: *const c_char,
20+
pub func: lua_CFunction,
21+
}
22+
23+
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
24+
unsafe extern "C-unwind" {
25+
pub fn luaL_checkversion_(L: *mut lua_State, ver: lua_Number, sz: usize);
26+
27+
pub fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
28+
pub fn luaL_callmeta(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int;
29+
pub fn luaL_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char;
30+
pub fn luaL_argerror(L: *mut lua_State, arg: c_int, extramsg: *const c_char) -> c_int;
31+
pub fn luaL_checklstring(L: *mut lua_State, arg: c_int, l: *mut usize) -> *const c_char;
32+
pub fn luaL_optlstring(L: *mut lua_State, arg: c_int, def: *const c_char, l: *mut usize)
33+
-> *const c_char;
34+
pub fn luaL_checknumber(L: *mut lua_State, arg: c_int) -> lua_Number;
35+
pub fn luaL_optnumber(L: *mut lua_State, arg: c_int, def: lua_Number) -> lua_Number;
36+
pub fn luaL_checkinteger(L: *mut lua_State, arg: c_int) -> lua_Integer;
37+
pub fn luaL_optinteger(L: *mut lua_State, arg: c_int, def: lua_Integer) -> lua_Integer;
38+
39+
pub fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char);
40+
pub fn luaL_checktype(L: *mut lua_State, arg: c_int, t: c_int);
41+
pub fn luaL_checkany(L: *mut lua_State, arg: c_int);
42+
43+
pub fn luaL_newmetatable(L: *mut lua_State, tname: *const c_char) -> c_int;
44+
pub fn luaL_setmetatable(L: *mut lua_State, tname: *const c_char);
45+
pub fn luaL_testudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
46+
pub fn luaL_checkudata(L: *mut lua_State, ud: c_int, tname: *const c_char) -> *mut c_void;
47+
48+
pub fn luaL_where(L: *mut lua_State, lvl: c_int);
49+
pub fn luaL_error(L: *mut lua_State, fmt: *const c_char, ...) -> c_int;
50+
51+
pub fn luaL_checkoption(
52+
L: *mut lua_State,
53+
arg: c_int,
54+
def: *const c_char,
55+
lst: *const *const c_char,
56+
) -> c_int;
57+
58+
pub fn luaL_fileresult(L: *mut lua_State, stat: c_int, fname: *const c_char) -> c_int;
59+
pub fn luaL_execresult(L: *mut lua_State, stat: c_int) -> c_int;
60+
pub fn luaL_alloc(L: *mut lua_State, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
61+
}
62+
63+
// Pre-defined references
64+
pub const LUA_NOREF: c_int = -2;
65+
pub const LUA_REFNIL: c_int = -1;
66+
67+
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
68+
unsafe extern "C-unwind" {
69+
pub fn luaL_ref(L: *mut lua_State, t: c_int) -> c_int;
70+
pub fn luaL_unref(L: *mut lua_State, t: c_int, r#ref: c_int);
71+
72+
pub fn luaL_loadfilex(L: *mut lua_State, filename: *const c_char, mode: *const c_char) -> c_int;
73+
}
74+
75+
#[inline(always)]
76+
pub unsafe fn luaL_loadfile(L: *mut lua_State, f: *const c_char) -> c_int {
77+
luaL_loadfilex(L, f, ptr::null())
78+
}
79+
80+
#[cfg_attr(all(windows, raw_dylib), link(name = "lua55", kind = "raw-dylib"))]
81+
unsafe extern "C-unwind" {
82+
pub fn luaL_loadbufferx(
83+
L: *mut lua_State,
84+
buff: *const c_char,
85+
sz: usize,
86+
name: *const c_char,
87+
mode: *const c_char,
88+
) -> c_int;
89+
pub fn luaL_loadstring(L: *mut lua_State, s: *const c_char) -> c_int;
90+
91+
pub fn luaL_newstate() -> *mut lua_State;
92+
93+
#[link_name = "luaL_makeseed"]
94+
pub fn luaL_makeseed_(L: *mut lua_State) -> c_uint;
95+
96+
pub fn luaL_len(L: *mut lua_State, idx: c_int) -> lua_Integer;
97+
98+
// TODO: luaL_addgsub
99+
100+
pub fn luaL_gsub(
101+
L: *mut lua_State,
102+
s: *const c_char,
103+
p: *const c_char,
104+
r: *const c_char,
105+
) -> *const c_char;
106+
107+
pub fn luaL_setfuncs(L: *mut lua_State, l: *const luaL_Reg, nup: c_int);
108+
109+
pub fn luaL_getsubtable(L: *mut lua_State, idx: c_int, fname: *const c_char) -> c_int;
110+
111+
pub fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const c_char, level: c_int);
112+
113+
pub fn luaL_requiref(L: *mut lua_State, modname: *const c_char, openf: lua_CFunction, glb: c_int);
114+
}
115+
116+
//
117+
// Some useful macros (implemented as Rust functions)
118+
//
119+
120+
// TODO: luaL_newlibtable, luaL_newlib
121+
122+
#[inline(always)]
123+
pub unsafe fn luaL_argcheck(L: *mut lua_State, cond: c_int, arg: c_int, extramsg: *const c_char) {
124+
if cond == 0 {
125+
luaL_argerror(L, arg, extramsg);
126+
}
127+
}
128+
129+
#[inline(always)]
130+
pub unsafe fn luaL_checkstring(L: *mut lua_State, n: c_int) -> *const c_char {
131+
luaL_checklstring(L, n, ptr::null_mut())
132+
}
133+
134+
#[inline(always)]
135+
pub unsafe fn luaL_optstring(L: *mut lua_State, n: c_int, d: *const c_char) -> *const c_char {
136+
luaL_optlstring(L, n, d, ptr::null_mut())
137+
}
138+
139+
#[inline(always)]
140+
pub unsafe fn luaL_typename(L: *mut lua_State, i: c_int) -> *const c_char {
141+
lua::lua_typename(L, lua::lua_type(L, i))
142+
}
143+
144+
#[inline(always)]
145+
pub unsafe fn luaL_dofile(L: *mut lua_State, filename: *const c_char) -> c_int {
146+
let status = luaL_loadfile(L, filename);
147+
if status == 0 {
148+
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
149+
} else {
150+
status
151+
}
152+
}
153+
154+
#[inline(always)]
155+
pub unsafe fn luaL_dostring(L: *mut lua_State, s: *const c_char) -> c_int {
156+
let status = luaL_loadstring(L, s);
157+
if status == 0 {
158+
lua::lua_pcall(L, 0, lua::LUA_MULTRET, 0)
159+
} else {
160+
status
161+
}
162+
}
163+
164+
#[inline(always)]
165+
pub unsafe fn luaL_getmetatable(L: *mut lua_State, n: *const c_char) {
166+
lua::lua_getfield(L, lua::LUA_REGISTRYINDEX, n);
167+
}
168+
169+
// luaL_opt would be implemented here but it is undocumented, so it's omitted
170+
171+
#[inline(always)]
172+
pub unsafe fn luaL_loadbuffer(L: *mut lua_State, s: *const c_char, sz: usize, n: *const c_char) -> c_int {
173+
luaL_loadbufferx(L, s, sz, n, ptr::null())
174+
}
175+
176+
pub unsafe fn luaL_loadbufferenv(
177+
L: *mut lua_State,
178+
data: *const c_char,
179+
size: usize,
180+
name: *const c_char,
181+
mode: *const c_char,
182+
mut env: c_int,
183+
) -> c_int {
184+
if env != 0 {
185+
env = lua::lua_absindex(L, env);
186+
}
187+
let status = luaL_loadbufferx(L, data, size, name, mode);
188+
if status == lua::LUA_OK && env != 0 {
189+
lua::lua_pushvalue(L, env);
190+
lua::lua_setupvalue(L, -2, 1);
191+
}
192+
status
193+
}
194+
195+
pub unsafe fn luaL_makeseed(L: *mut lua_State) -> c_uint {
196+
#[cfg(macos)]
197+
return libc::arc4random();
198+
#[cfg(linux)]
199+
{
200+
let mut seed = 0u32;
201+
let buf = &mut seed as *mut _ as *mut c_void;
202+
if libc::getrandom(buf, 4, libc::GRND_NONBLOCK) == 4 {
203+
return seed;
204+
}
205+
}
206+
luaL_makeseed_(L)
207+
}
208+
209+
//
210+
// TODO: Generic Buffer Manipulation
211+
//

0 commit comments

Comments
 (0)