Skip to content

Commit 77d7d5d

Browse files
committed
Add initial Lua 5.5 support
1 parent ee9232e commit 77d7d5d

File tree

22 files changed

+286
-114
lines changed

22 files changed

+286
-114
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ keywords = ["lua", "luajit", "luau", "async", "scripting"]
1111
categories = ["api-bindings", "asynchronous"]
1212
license = "MIT"
1313
description = """
14-
High level bindings to Lua 5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
14+
High level bindings to Lua 5.5/5.4/5.3/5.2/5.1 (including LuaJIT) and Luau
1515
with async/await features and support of writing native Lua modules in Rust.
1616
"""
1717

@@ -26,6 +26,7 @@ members = [
2626
]
2727

2828
[features]
29+
lua55 = ["ffi/lua55"]
2930
lua54 = ["ffi/lua54"]
3031
lua53 = ["ffi/lua53"]
3132
lua52 = ["ffi/lua52"]

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
`mlua` is a set of bindings to the [Lua](https://www.lua.org) programming language for Rust with a goal of providing a
2121
_safe_ (as much as possible), high level, easy to use, practical and flexible API.
2222

23-
Started as an `rlua` fork, `mlua` supports Lua 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and [Luau] and allows writing native Lua modules in Rust as well as using Lua in a standalone mode.
23+
Started as an `rlua` fork, `mlua` supports Lua 5.5, 5.4, 5.3, 5.2, 5.1 (including LuaJIT) and [Luau] and allows writing native Lua modules in Rust as well as using Lua in a standalone mode.
2424

2525
`mlua` is tested on Windows/macOS/Linux including module mode in [GitHub Actions] on `x86_64` platforms and cross-compilation to `aarch64` (other targets are also supported).
2626

@@ -36,6 +36,7 @@ WebAssembly (WASM) is supported through the `wasm32-unknown-emscripten` target f
3636
`mlua` uses feature flags to reduce the number of dependencies and compiled code, and allow choosing only the required set of features.
3737
Below is a list of the available feature flags. By default `mlua` does not enable any features.
3838

39+
* `lua55`: enable Lua [5.5] support
3940
* `lua54`: enable Lua [5.4] support
4041
* `lua53`: enable Lua [5.3] support
4142
* `lua52`: enable Lua [5.2] support
@@ -55,6 +56,7 @@ Below is a list of the available feature flags. By default `mlua` does not enabl
5556
* `anyhow`: enable `anyhow::Error` conversion into Lua
5657
* `userdata-wrappers`: opt into `impl UserData` for `Rc<T>`/`Arc<T>`/`Rc<RefCell<T>>`/`Arc<Mutex<T>>` where `T: UserData`
5758

59+
[5.5]: https://www.lua.org/manual/5.5/manual.html
5860
[5.4]: https://www.lua.org/manual/5.4/manual.html
5961
[5.3]: https://www.lua.org/manual/5.3/manual.html
6062
[5.2]: https://www.lua.org/manual/5.2/manual.html

src/debug.rs

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,10 @@ impl<'a> Debug<'a> {
159159

160160
/// Corresponds to the `t` "what" mask. Returns true if the hook is in a function tail call,
161161
/// false otherwise.
162-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
162+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
163163
#[cfg_attr(
164164
docsrs,
165-
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52")))
165+
doc(cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52")))
166166
)]
167167
pub fn is_tail_call(&self) -> bool {
168168
unsafe {
@@ -191,9 +191,9 @@ impl<'a> Debug<'a> {
191191
#[cfg(not(feature = "luau"))]
192192
let stack = DebugStack {
193193
num_ups: (*self.ar).nups as _,
194-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
194+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
195195
num_params: (*self.ar).nparams as _,
196-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
196+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
197197
is_vararg: (*self.ar).isvararg != 0,
198198
};
199199
#[cfg(feature = "luau")]
@@ -248,17 +248,41 @@ pub struct DebugStack {
248248
/// Number of upvalues.
249249
pub num_ups: u8,
250250
/// Number of parameters.
251-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
251+
#[cfg(any(
252+
feature = "lua55",
253+
feature = "lua54",
254+
feature = "lua53",
255+
feature = "lua52",
256+
feature = "luau"
257+
))]
252258
#[cfg_attr(
253259
docsrs,
254-
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau")))
260+
doc(cfg(any(
261+
feature = "lua55",
262+
feature = "lua54",
263+
feature = "lua53",
264+
feature = "lua52",
265+
feature = "luau"
266+
)))
255267
)]
256268
pub num_params: u8,
257269
/// Whether the function is a vararg function.
258-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
270+
#[cfg(any(
271+
feature = "lua55",
272+
feature = "lua54",
273+
feature = "lua53",
274+
feature = "lua52",
275+
feature = "luau"
276+
))]
259277
#[cfg_attr(
260278
docsrs,
261-
doc(cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau")))
279+
doc(cfg(any(
280+
feature = "lua55",
281+
feature = "lua54",
282+
feature = "lua53",
283+
feature = "lua52",
284+
feature = "luau"
285+
)))
262286
)]
263287
pub is_vararg: bool,
264288
}

src/function.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ impl Function {
276276

277277
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
278278
ffi::lua_getfenv(state, -1);
279-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
279+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
280280
for i in 1..=255 {
281281
// Traverse upvalues until we find the _ENV one
282282
match ffi::lua_getupvalue(state, -1, i) {
@@ -316,7 +316,7 @@ impl Function {
316316
lua.push_ref(&env.0);
317317
ffi::lua_setfenv(state, -2);
318318
}
319-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
319+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
320320
for i in 1..=255 {
321321
match ffi::lua_getupvalue(state, -1, i) {
322322
s if s.is_null() => return Ok(false),
@@ -400,11 +400,14 @@ impl Function {
400400
_state: *mut ffi::lua_State,
401401
buf: *const c_void,
402402
buf_len: usize,
403-
data: *mut c_void,
403+
data_ptr: *mut c_void,
404404
) -> c_int {
405-
let data = &mut *(data as *mut Vec<u8>);
406-
let buf = slice::from_raw_parts(buf as *const u8, buf_len);
407-
data.extend_from_slice(buf);
405+
// If `data` is null, then it's a signal that write is finished.
406+
if !data_ptr.is_null() && buf_len > 0 {
407+
let data = &mut *(data_ptr as *mut Vec<u8>);
408+
let buf = slice::from_raw_parts(buf as *const u8, buf_len);
409+
data.extend_from_slice(buf);
410+
}
408411
0
409412
}
410413

src/memory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl MemoryState {
8383
}
8484

8585
// Does nothing apart from calling `f()`, we don't need to bypass any limits
86-
#[cfg(any(feature = "lua52", feature = "lua53", feature = "lua54"))]
86+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
8787
#[inline]
8888
pub(crate) unsafe fn relax_limit_with(_state: *mut ffi::lua_State, f: impl FnOnce()) {
8989
f();

src/state.rs

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ pub(crate) struct LuaGuard(ArcReentrantMutexGuard<RawLua>);
7373
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7474
pub enum GCMode {
7575
Incremental,
76-
#[cfg(feature = "lua54")]
77-
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
76+
#[cfg(any(feature = "lua55", feature = "lua54"))]
77+
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
7878
Generational,
7979
}
8080

@@ -249,7 +249,7 @@ impl Lua {
249249
ffi::luaL_loadstring as _,
250250
ffi::luaL_openlibs as _,
251251
]);
252-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
252+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
253253
{
254254
_symbols.push(ffi::lua_getglobal as _);
255255
_symbols.push(ffi::lua_setglobal as _);
@@ -382,7 +382,7 @@ impl Lua {
382382
#[cfg(not(feature = "luau"))]
383383
#[cfg_attr(docsrs, doc(cfg(not(feature = "luau"))))]
384384
pub fn preload_module(&self, modname: &str, func: Function) -> Result<()> {
385-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
385+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
386386
let preload = unsafe {
387387
self.exec_raw::<Option<Table>>((), |state| {
388388
ffi::lua_getfield(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_PRELOAD_TABLE);
@@ -814,8 +814,8 @@ impl Lua {
814814
}
815815

816816
/// Sets the warning function to be used by Lua to emit warnings.
817-
#[cfg(feature = "lua54")]
818-
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
817+
#[cfg(any(feature = "lua55", feature = "lua54"))]
818+
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
819819
pub fn set_warning_function<F>(&self, callback: F)
820820
where
821821
F: Fn(&Lua, &str, bool) -> Result<()> + MaybeSend + 'static,
@@ -847,8 +847,8 @@ impl Lua {
847847
/// Removes warning function previously set by `set_warning_function`.
848848
///
849849
/// This function has no effect if a warning function was not previously set.
850-
#[cfg(feature = "lua54")]
851-
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
850+
#[cfg(any(feature = "lua55", feature = "lua54"))]
851+
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
852852
pub fn remove_warning_function(&self) {
853853
let lua = self.lock();
854854
unsafe {
@@ -861,8 +861,8 @@ impl Lua {
861861
///
862862
/// A message in a call with `incomplete` set to `true` should be continued in
863863
/// another call to this function.
864-
#[cfg(feature = "lua54")]
865-
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
864+
#[cfg(any(feature = "lua55", feature = "lua54"))]
865+
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
866866
pub fn warning(&self, msg: impl AsRef<str>, incomplete: bool) {
867867
let msg = msg.as_ref();
868868
let mut bytes = vec![0; msg.len() + 1];
@@ -954,7 +954,13 @@ impl Lua {
954954
}
955955

956956
/// Returns `true` if the garbage collector is currently running automatically.
957-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52", feature = "luau"))]
957+
#[cfg(any(
958+
feature = "lua55",
959+
feature = "lua54",
960+
feature = "lua53",
961+
feature = "lua52",
962+
feature = "luau"
963+
))]
958964
pub fn gc_is_running(&self) -> bool {
959965
let lua = self.lock();
960966
unsafe { ffi::lua_gc(lua.main_state(), ffi::LUA_GCISRUNNING, 0) != 0 }
@@ -1019,8 +1025,12 @@ impl Lua {
10191025
let lua = self.lock();
10201026
let state = lua.main_state();
10211027
unsafe {
1022-
#[cfg(not(feature = "luau"))]
1028+
#[cfg(feature = "lua55")]
1029+
return ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPPAUSE, pause);
1030+
1031+
#[cfg(not(any(feature = "lua55", feature = "luau")))]
10231032
return ffi::lua_gc(state, ffi::LUA_GCSETPAUSE, pause);
1033+
10241034
#[cfg(feature = "luau")]
10251035
return ffi::lua_gc(state, ffi::LUA_GCSETGOAL, pause);
10261036
}
@@ -1034,7 +1044,18 @@ impl Lua {
10341044
/// [documentation]: https://www.lua.org/manual/5.4/manual.html#2.5
10351045
pub fn gc_set_step_multiplier(&self, step_multiplier: c_int) -> c_int {
10361046
let lua = self.lock();
1037-
unsafe { ffi::lua_gc(lua.main_state(), ffi::LUA_GCSETSTEPMUL, step_multiplier) }
1047+
unsafe {
1048+
#[cfg(feature = "lua55")]
1049+
return ffi::lua_gc(
1050+
lua.main_state(),
1051+
ffi::LUA_GCPARAM,
1052+
ffi::LUA_GCPSTEPMUL,
1053+
step_multiplier,
1054+
);
1055+
1056+
#[cfg(not(feature = "lua55"))]
1057+
return ffi::lua_gc(lua.main_state(), ffi::LUA_GCSETSTEPMUL, step_multiplier);
1058+
}
10381059
}
10391060

10401061
/// Changes the collector to incremental mode with the given parameters.
@@ -1073,12 +1094,19 @@ impl Lua {
10731094
#[cfg(not(feature = "luau"))]
10741095
let _ = step_size; // Ignored
10751096

1076-
GCMode::Incremental
1097+
return GCMode::Incremental;
10771098
}
10781099

1100+
#[cfg(feature = "lua55")]
1101+
let prev_mode = unsafe {
1102+
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPPAUSE, pause);
1103+
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPSTEPMUL, step_multiplier);
1104+
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPSTEPSIZE, step_size);
1105+
ffi::lua_gc(state, ffi::LUA_GCINC)
1106+
};
10791107
#[cfg(feature = "lua54")]
10801108
let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCINC, pause, step_multiplier, step_size) };
1081-
#[cfg(feature = "lua54")]
1109+
#[cfg(any(feature = "lua55", feature = "lua54"))]
10821110
match prev_mode {
10831111
ffi::LUA_GCINC => GCMode::Incremental,
10841112
ffi::LUA_GCGEN => GCMode::Generational,
@@ -1092,11 +1120,19 @@ impl Lua {
10921120
/// can be found in the Lua 5.4 [documentation][lua_doc].
10931121
///
10941122
/// [lua_doc]: https://www.lua.org/manual/5.4/manual.html#2.5.2
1095-
#[cfg(feature = "lua54")]
1096-
#[cfg_attr(docsrs, doc(cfg(feature = "lua54")))]
1123+
#[cfg(any(feature = "lua55", feature = "lua54"))]
1124+
#[cfg_attr(docsrs, doc(cfg(any(feature = "lua55", feature = "lua54"))))]
10971125
pub fn gc_gen(&self, minor_multiplier: c_int, major_multiplier: c_int) -> GCMode {
10981126
let lua = self.lock();
10991127
let state = lua.main_state();
1128+
#[cfg(feature = "lua55")]
1129+
let prev_mode = unsafe {
1130+
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPMINORMUL, minor_multiplier);
1131+
ffi::lua_gc(state, ffi::LUA_GCPARAM, ffi::LUA_GCPMINORMAJOR, major_multiplier);
1132+
// TODO: LUA_GCPMAJORMINOR
1133+
ffi::lua_gc(state, ffi::LUA_GCGEN)
1134+
};
1135+
#[cfg(not(feature = "lua55"))]
11001136
let prev_mode = unsafe { ffi::lua_gc(state, ffi::LUA_GCGEN, minor_multiplier, major_multiplier) };
11011137
match prev_mode {
11021138
ffi::LUA_GCGEN => GCMode::Generational,
@@ -1317,7 +1353,12 @@ impl Lua {
13171353
/// This function is unsafe because provides a way to execute unsafe C function.
13181354
pub unsafe fn create_c_function(&self, func: ffi::lua_CFunction) -> Result<Function> {
13191355
let lua = self.lock();
1320-
if cfg!(any(feature = "lua54", feature = "lua53", feature = "lua52")) {
1356+
if cfg!(any(
1357+
feature = "lua55",
1358+
feature = "lua54",
1359+
feature = "lua53",
1360+
feature = "lua52"
1361+
)) {
13211362
ffi::lua_pushcfunction(lua.ref_thread(), func);
13221363
return Ok(Function(lua.pop_ref_thread()));
13231364
}
@@ -1578,7 +1619,7 @@ impl Lua {
15781619
unsafe {
15791620
let _sg = StackGuard::new(state);
15801621
assert_stack(state, 1);
1581-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
1622+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
15821623
ffi::lua_rawgeti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
15831624
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
15841625
ffi::lua_pushvalue(state, ffi::LUA_GLOBALSINDEX);
@@ -1610,7 +1651,7 @@ impl Lua {
16101651

16111652
lua.push_ref(&globals.0);
16121653

1613-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
1654+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
16141655
ffi::lua_rawseti(state, ffi::LUA_REGISTRYINDEX, ffi::LUA_RIDX_GLOBALS);
16151656
#[cfg(any(feature = "lua51", feature = "luajit", feature = "luau"))]
16161657
ffi::lua_replace(state, ffi::LUA_GLOBALSINDEX);
@@ -2210,7 +2251,7 @@ impl Lua {
22102251
})?,
22112252
)?;
22122253

2213-
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
2254+
#[cfg(any(feature = "lua55", feature = "lua54", feature = "lua53", feature = "lua52"))]
22142255
let searchers: Table = package.get("searchers")?;
22152256
#[cfg(any(feature = "lua51", feature = "luajit"))]
22162257
let searchers: Table = package.get("loaders")?;

src/state/extra.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub(crate) struct ExtraData {
7777
pub(super) hook_callback: Option<crate::types::HookCallback>,
7878
#[cfg(not(feature = "luau"))]
7979
pub(super) hook_triggers: crate::debug::HookTriggers,
80-
#[cfg(feature = "lua54")]
80+
#[cfg(any(feature = "lua55", feature = "lua54"))]
8181
pub(super) warn_callback: Option<crate::types::WarnCallback>,
8282
#[cfg(feature = "luau")]
8383
pub(super) interrupt_callback: Option<crate::types::InterruptCallback>,
@@ -182,7 +182,7 @@ impl ExtraData {
182182
hook_callback: None,
183183
#[cfg(not(feature = "luau"))]
184184
hook_triggers: Default::default(),
185-
#[cfg(feature = "lua54")]
185+
#[cfg(any(feature = "lua55", feature = "lua54"))]
186186
warn_callback: None,
187187
#[cfg(feature = "luau")]
188188
interrupt_callback: None,

0 commit comments

Comments
 (0)