From b16f3895a0d14b1ef80c9c0f07b97f990f124c32 Mon Sep 17 00:00:00 2001 From: Peter Marheine Date: Wed, 6 Dec 2023 21:09:25 +1100 Subject: [PATCH 1/2] lua54: use changed return type for lua_rawlen Lua 5.4 changed lua_rawlen to return lua_Unsigned, versus size_t in earlier versions. Change the C API signature to match, and add a wrapper function with the same name that maintains a stable Rust API by casting to usize. --- mlua-sys/src/lua54/lua.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mlua-sys/src/lua54/lua.rs b/mlua-sys/src/lua54/lua.rs index 66633bb3..7eab2af2 100644 --- a/mlua-sys/src/lua54/lua.rs +++ b/mlua-sys/src/lua54/lua.rs @@ -149,13 +149,20 @@ extern "C-unwind" { pub fn lua_tointegerx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer; pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_tolstring(L: *mut lua_State, idx: c_int, len: *mut usize) -> *const c_char; - pub fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize; + #[link_name = "lua_rawlen"] + fn lua_rawlen_(L: *mut lua_State, idx: c_int) -> lua_Unsigned; pub fn lua_tocfunction(L: *mut lua_State, idx: c_int) -> Option; pub fn lua_touserdata(L: *mut lua_State, idx: c_int) -> *mut c_void; pub fn lua_tothread(L: *mut lua_State, idx: c_int) -> *mut lua_State; pub fn lua_topointer(L: *mut lua_State, idx: c_int) -> *const c_void; } +// lua_rawlen's return type changed from size_t to lua_Unsigned int in Lua 5.4. +// This adapts the crate API to the new Lua ABI. +pub unsafe fn lua_rawlen(L: *mut lua_State, idx: c_int) -> usize { + lua_rawlen_(L, idx) as usize +} + // // Comparison and arithmetic functions // From e3f34f319cc9eb5cc4f87074a313f98c1dff70ca Mon Sep 17 00:00:00 2001 From: Peter Marheine Date: Wed, 6 Dec 2023 21:16:52 +1100 Subject: [PATCH 2/2] Correct C return type for lua_error The definition of lua_error in all of Lua 5.1 through 5.4 says lua_error returns int, but the Rust definition of the same function treats it as void (because it's known not to return). This causes link-time errors when building for wasm targets because the wasm linker is aware of function return types and errors out if they differ between definition and declaration. --- mlua-sys/src/lua51/lua.rs | 11 ++++++++++- mlua-sys/src/lua52/lua.rs | 11 ++++++++++- mlua-sys/src/lua53/lua.rs | 11 ++++++++++- mlua-sys/src/lua54/lua.rs | 11 ++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/mlua-sys/src/lua51/lua.rs b/mlua-sys/src/lua51/lua.rs index 925e9c7f..5cd351d8 100644 --- a/mlua-sys/src/lua51/lua.rs +++ b/mlua-sys/src/lua51/lua.rs @@ -228,13 +228,22 @@ extern "C-unwind" { // #[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))] extern "C-unwind" { - pub fn lua_error(L: *mut lua_State) -> !; + #[link_name = "lua_error"] + fn lua_error_(L: *mut lua_State) -> c_int; pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_concat(L: *mut lua_State, n: c_int); pub fn lua_getallocf(L: *mut lua_State, ud: *mut *mut c_void) -> lua_Alloc; pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void); } +// lua_error does not return but is declared to return int, and Rust translates +// ! to void which can cause link-time errors if the platform linker is aware +// of return types and requires they match (for example: wasm does this). +pub unsafe fn lua_error(L: *mut lua_State) -> ! { + lua_error_(L); + unreachable!(); +} + // // Some useful macros (implemented as Rust functions) // diff --git a/mlua-sys/src/lua52/lua.rs b/mlua-sys/src/lua52/lua.rs index 760140b7..d668d678 100644 --- a/mlua-sys/src/lua52/lua.rs +++ b/mlua-sys/src/lua52/lua.rs @@ -308,7 +308,8 @@ extern "C-unwind" { // // Miscellaneous functions // - pub fn lua_error(L: *mut lua_State) -> !; + #[link_name = "lua_error"] + fn lua_error_(L: *mut lua_State) -> c_int; pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_concat(L: *mut lua_State, n: c_int); pub fn lua_len(L: *mut lua_State, idx: c_int); @@ -316,6 +317,14 @@ extern "C-unwind" { pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void); } +// lua_error does not return but is declared to return int, and Rust translates +// ! to void which can cause link-time errors if the platform linker is aware +// of return types and requires they match (for example: wasm does this). +pub unsafe fn lua_error(L: *mut lua_State) -> ! { + lua_error_(L); + unreachable!(); +} + // // Some useful macros (implemented as Rust functions) // diff --git a/mlua-sys/src/lua53/lua.rs b/mlua-sys/src/lua53/lua.rs index d918de48..393ff3c7 100644 --- a/mlua-sys/src/lua53/lua.rs +++ b/mlua-sys/src/lua53/lua.rs @@ -314,7 +314,8 @@ extern "C-unwind" { // // Miscellaneous functions // - pub fn lua_error(L: *mut lua_State) -> !; + #[link_name = "lua_error"] + fn lua_error_(L: *mut lua_State) -> c_int; pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_concat(L: *mut lua_State, n: c_int); pub fn lua_len(L: *mut lua_State, idx: c_int); @@ -323,6 +324,14 @@ extern "C-unwind" { pub fn lua_setallocf(L: *mut lua_State, f: lua_Alloc, ud: *mut c_void); } +// lua_error does not return but is declared to return int, and Rust translates +// ! to void which can cause link-time errors if the platform linker is aware +// of return types and requires they match (for example: wasm does this). +pub unsafe fn lua_error(L: *mut lua_State) -> ! { + lua_error_(L); + unreachable!(); +} + // // Some useful macros (implemented as Rust functions) // diff --git a/mlua-sys/src/lua54/lua.rs b/mlua-sys/src/lua54/lua.rs index 7eab2af2..b1348661 100644 --- a/mlua-sys/src/lua54/lua.rs +++ b/mlua-sys/src/lua54/lua.rs @@ -343,7 +343,8 @@ extern "C-unwind" { // // Miscellaneous functions // - pub fn lua_error(L: *mut lua_State) -> !; + #[link_name = "lua_error"] + fn lua_error_(L: *mut lua_State) -> c_int; pub fn lua_next(L: *mut lua_State, idx: c_int) -> c_int; pub fn lua_concat(L: *mut lua_State, n: c_int); pub fn lua_len(L: *mut lua_State, idx: c_int); @@ -355,6 +356,14 @@ extern "C-unwind" { pub fn lua_closeslot(L: *mut lua_State, idx: c_int); } +// lua_error does not return but is declared to return int, and Rust translates +// ! to void which can cause link-time errors if the platform linker is aware +// of return types and requires they match (for example: wasm does this). +pub unsafe fn lua_error(L: *mut lua_State) -> ! { + lua_error_(L); + unreachable!(); +} + // // Some useful macros (implemented as Rust functions) //