Compare commits

..

13 Commits

Author SHA1 Message Date
Alex Orlenko 31efd0cf72 v0.10.5 2025-05-24 12:41:05 +01:00
Alex Orlenko 6b79e4cd76 Update CHANGELOG 2025-05-24 12:41:04 +01:00
Alex Orlenko ee2da72685 Revert default chunk name change 2025-05-24 12:40:58 +01:00
Alex Orlenko 6180a528a7 Revert = prefix from __mlua_async_poll 2025-05-24 12:30:32 +01:00
Alex Orlenko 69ef08d4d2 Switch back to Luau userdata destructors defined in mlua-sys v0.6 2025-05-24 11:35:25 +01:00
Alex Orlenko f7f04d5180 Revert mlua-sys to v0.6.8 2025-05-24 10:43:28 +01:00
Alex Orlenko e10623d658 Update __mlua_index/__mlua_newindex chunk names 2025-05-24 10:22:33 +01:00
Alex Orlenko c3ab89ba66 Fix tests 2025-05-24 10:22:26 +01:00
Alex Orlenko fa500639f0 Generate doc for lua_module macro using doc cfg instead of docsrs 2025-05-24 10:22:20 +01:00
Alex Orlenko 3d2574a855 Revert "Use c string literal where appropriate"
This reverts commit 46e949c184.
2025-05-24 10:19:19 +01:00
Alex Orlenko 003935db47 Revert "Change Lua library name constants from &str to *const c_char."
This reverts commit 272cfdb89b.
2025-05-24 10:18:55 +01:00
Alex Orlenko fbed171f90 Revert "Support 52-bit integers for Luau"
This reverts commit ef8b8e11ec.
2025-05-24 10:18:16 +01:00
Alex Orlenko 298d48f708 Update error message for UserDataRef 2025-05-06 10:24:53 +01:00
46 changed files with 378 additions and 548 deletions
+2 -2
View File
@@ -129,8 +129,8 @@ jobs:
- name: Run compile tests (macos lua54)
if: ${{ matrix.os == 'macos-latest' && matrix.lua == 'lua54' }}
run: |
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored" -- --ignored
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored,async,send,serialize,macros" -- --ignored
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored" --tests -- --ignored
TRYBUILD=overwrite cargo test --features "${{ matrix.lua }},vendored,async,send,serialize,macros" --tests -- --ignored
shell: bash
test_with_sanitizer:
+8
View File
@@ -1,5 +1,13 @@
## v0.10.5 (May 24th, 2025)
- mlua-sys is back to 0.6.x (Luau 0.663)
- Reverted: Trigger abort when Luau userdata destructors are panic (requires new mlua-sys)
- Reverted: Added large (52bit) integers support for Luau (breaking change)
## v0.10.4 (May 5th, 2025)
_yanked_ because of semver-breaking changes
- Luau updated to 0.672
- New serde option `encode_empty_tables_as_array` to serialize empty tables as arrays
- Added `WeakLua` and `Lua::weak()` to create weak references to Lua state
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua"
version = "0.10.4" # remember to update mlua_derive
version = "0.10.5" # remember to update mlua_derive
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@kyju.org>"]
rust-version = "1.79.0"
edition = "2021"
@@ -36,7 +36,7 @@ luau = ["ffi/luau", "dep:libloading"]
luau-jit = ["luau", "ffi/luau-codegen"]
luau-vector4 = ["luau", "ffi/luau-vector4"]
vendored = ["ffi/vendored"]
module = ["dep:mlua_derive", "ffi/module"]
module = ["mlua_derive", "ffi/module"]
async = ["dep:futures-util"]
send = ["parking_lot/send_guard", "error-send"]
error-send = []
@@ -59,7 +59,7 @@ parking_lot = { version = "0.12", features = ["arc_lock"] }
anyhow = { version = "1.0", optional = true }
rustversion = "1.0"
ffi = { package = "mlua-sys", version = "0.7.0", path = "mlua-sys" }
ffi = { package = "mlua-sys", version = "0.6.8", path = "mlua-sys" }
[target.'cfg(unix)'.dependencies]
libloading = { version = "0.8", optional = true }
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua-sys"
version = "0.7.0"
version = "0.6.8"
authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
rust-version = "1.71"
edition = "2021"
@@ -38,9 +38,9 @@ module = []
cc = "1.0"
cfg-if = "1.0"
pkg-config = "0.3.17"
lua-src = { version = ">= 547.1.0, < 547.2.0", optional = true }
luajit-src = { version = ">= 210.6.0, < 210.7.0", optional = true }
luau0-src = { version = "0.14.2", optional = true }
lua-src = { version = ">= 547.0.0, < 547.1.0", optional = true }
luajit-src = { version = ">= 210.5.0, < 210.6.0", optional = true }
luau0-src = { version = "0.12.0", optional = true }
[lints.rust]
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(raw_dylib)'] }
+10 -10
View File
@@ -90,7 +90,7 @@ unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) ->
} else if compat53_findfield(L, objidx, level - 1) != 0 {
// try recursively
lua_remove(L, -2); // remove table (but keep name)
lua_pushliteral(L, c".");
lua_pushliteral(L, ".");
lua_insert(L, -2); // place '.' between the two names
lua_concat(L, 3);
return 1;
@@ -121,13 +121,13 @@ unsafe fn compat53_pushfuncname(L: *mut lua_State, ar: *mut lua_Debug) {
lua_pushfstring(L, cstr!("function '%s'"), (*ar).name);
} else if *(*ar).what == b'm' as c_char {
// main?
lua_pushliteral(L, c"main chunk");
lua_pushliteral(L, "main chunk");
} else if *(*ar).what == b'C' as c_char {
if compat53_pushglobalfuncname(L, ar) != 0 {
lua_pushfstring(L, cstr!("function '%s'"), lua_tostring(L, -1));
lua_remove(L, -2); // remove name
} else {
lua_pushliteral(L, c"?");
lua_pushliteral(L, "?");
}
} else {
lua_pushfstring(
@@ -377,7 +377,7 @@ pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char)
if !msg.is_null() {
luaL_error(L, cstr!("stack overflow (%s)"), msg);
} else {
lua_pushliteral(L, c"stack overflow");
lua_pushliteral(L, "stack overflow");
lua_error(L);
}
}
@@ -467,12 +467,12 @@ pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const
if !msg.is_null() {
lua_pushfstring(L, cstr!("%s\n"), msg);
}
lua_pushliteral(L, c"stack traceback:");
lua_pushliteral(L, "stack traceback:");
while lua_getstack(L1, level, &mut ar) != 0 {
level += 1;
if level == mark {
// too many levels?
lua_pushliteral(L, c"\n\t..."); // add a '...'
lua_pushliteral(L, "\n\t..."); // add a '...'
level = numlevels - COMPAT53_LEVELS2; // and skip to last ones
} else {
lua_getinfo(L1, cstr!("Slnt"), &mut ar);
@@ -480,7 +480,7 @@ pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const
if ar.currentline > 0 {
lua_pushfstring(L, cstr!("%d:"), ar.currentline);
}
lua_pushliteral(L, c" in ");
lua_pushliteral(L, " in ");
compat53_pushfuncname(L, &mut ar);
lua_concat(L, lua_gettop(L) - top);
}
@@ -493,16 +493,16 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize)
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
match lua_type(L, idx) {
LUA_TNIL => {
lua_pushliteral(L, c"nil");
lua_pushliteral(L, "nil");
}
LUA_TSTRING | LUA_TNUMBER => {
lua_pushvalue(L, idx);
}
LUA_TBOOLEAN => {
if lua_toboolean(L, idx) == 0 {
lua_pushliteral(L, c"false");
lua_pushliteral(L, "false");
} else {
lua_pushliteral(L, c"true");
lua_pushliteral(L, "true");
}
}
t => {
+6 -5
View File
@@ -1,6 +1,5 @@
//! Contains definitions from `lua.h`.
use std::ffi::CStr;
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_int, c_void};
use std::ptr;
@@ -84,10 +83,10 @@ pub type lua_Reader =
pub type lua_Writer =
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions (no unwinding)
/// Type for memory-allocation functions
#[rustfmt::skip]
pub type lua_Alloc =
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
unsafe extern "C-unwind" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
extern "C-unwind" {
@@ -313,8 +312,10 @@ pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
}
#[inline(always)]
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
lua_pushstring_(L, s.as_ptr());
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static str) {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring_(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[inline(always)]
+12 -12
View File
@@ -1,24 +1,24 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_int};
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
#[cfg(feature = "luajit")]
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit");
pub const LUA_BITLIBNAME: &str = "bit";
#[cfg(feature = "luajit")]
pub const LUA_JITLIBNAME: *const c_char = cstr!("jit");
pub const LUA_JITLIBNAME: &str = "jit";
#[cfg(feature = "luajit")]
pub const LUA_FFILIBNAME: *const c_char = cstr!("ffi");
pub const LUA_FFILIBNAME: &str = "ffi";
#[cfg_attr(all(windows, raw_dylib), link(name = "lua51", kind = "raw-dylib"))]
extern "C-unwind" {
+3 -3
View File
@@ -199,16 +199,16 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize)
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
match lua_type(L, idx) {
LUA_TNIL => {
lua_pushliteral(L, c"nil");
lua_pushliteral(L, "nil");
}
LUA_TSTRING | LUA_TNUMBER => {
lua_pushvalue(L, idx);
}
LUA_TBOOLEAN => {
if lua_toboolean(L, idx) == 0 {
lua_pushliteral(L, c"false");
lua_pushliteral(L, "false");
} else {
lua_pushliteral(L, c"true");
lua_pushliteral(L, "true");
}
}
t => {
+6 -5
View File
@@ -1,6 +1,5 @@
//! Contains definitions from `lua.h`.
use std::ffi::CStr;
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_uint, c_void};
use std::ptr;
@@ -89,10 +88,10 @@ pub type lua_Reader =
pub type lua_Writer =
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions (no unwinding)
/// Type for memory-allocation functions
#[rustfmt::skip]
pub type lua_Alloc =
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
unsafe extern "C-unwind" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
extern "C-unwind" {
@@ -396,8 +395,10 @@ pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
}
#[inline(always)]
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
lua_pushstring(L, s.as_ptr());
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring_(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[inline(always)]
+10 -10
View File
@@ -1,18 +1,18 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_int};
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
#[cfg_attr(all(windows, raw_dylib), link(name = "lua52", kind = "raw-dylib"))]
extern "C-unwind" {
+2 -2
View File
@@ -9,10 +9,10 @@ use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
// Key, in the registry, for table of loaded modules
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
pub const LUA_LOADED_TABLE: &str = "_LOADED";
// Key, in the registry, for table of preloaded loaders
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
pub const LUA_PRELOAD_TABLE: &str = "_PRELOAD";
#[repr(C)]
pub struct luaL_Reg {
+6 -5
View File
@@ -1,6 +1,5 @@
//! Contains definitions from `lua.h`.
use std::ffi::CStr;
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_void};
use std::{mem, ptr};
@@ -96,10 +95,10 @@ pub type lua_Reader =
pub type lua_Writer =
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions (no unwinding)
/// Type for memory-allocation functions
#[rustfmt::skip]
pub type lua_Alloc =
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
unsafe extern "C-unwind" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
extern "C-unwind" {
@@ -408,8 +407,10 @@ pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
}
#[inline(always)]
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
lua_pushstring(L, s.as_ptr());
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[inline(always)]
+11 -11
View File
@@ -1,19 +1,19 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_int};
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
#[cfg_attr(all(windows, raw_dylib), link(name = "lua53", kind = "raw-dylib"))]
extern "C-unwind" {
+2 -2
View File
@@ -9,10 +9,10 @@ use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State};
pub const LUA_ERRFILE: c_int = lua::LUA_ERRERR + 1;
// Key, in the registry, for table of loaded modules
pub const LUA_LOADED_TABLE: *const c_char = cstr!("_LOADED");
pub const LUA_LOADED_TABLE: &str = "_LOADED";
// Key, in the registry, for table of preloaded loaders
pub const LUA_PRELOAD_TABLE: *const c_char = cstr!("_PRELOAD");
pub const LUA_PRELOAD_TABLE: &str = "_PRELOAD";
#[repr(C)]
pub struct luaL_Reg {
+6 -5
View File
@@ -1,6 +1,5 @@
//! Contains definitions from `lua.h`.
use std::ffi::CStr;
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_int, c_uchar, c_ushort, c_void};
use std::{mem, ptr};
@@ -95,10 +94,10 @@ pub type lua_Reader =
pub type lua_Writer =
unsafe extern "C-unwind" fn(L: *mut lua_State, p: *const c_void, sz: usize, ud: *mut c_void) -> c_int;
/// Type for memory-allocation functions (no unwinding)
/// Type for memory-allocation functions
#[rustfmt::skip]
pub type lua_Alloc =
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
unsafe extern "C-unwind" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
/// Type for warning functions
pub type lua_WarnFunction = unsafe extern "C-unwind" fn(ud: *mut c_void, msg: *const c_char, tocont: c_int);
@@ -435,8 +434,10 @@ pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
}
#[inline(always)]
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
lua_pushstring(L, s.as_ptr());
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static str) -> *const c_char {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[inline(always)]
+10 -10
View File
@@ -1,18 +1,18 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_int};
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
pub const LUA_IOLIBNAME: *const c_char = cstr!("io");
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
pub const LUA_LOADLIBNAME: *const c_char = cstr!("package");
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_IOLIBNAME: &str = "io";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_LOADLIBNAME: &str = "package";
#[cfg_attr(all(windows, raw_dylib), link(name = "lua54", kind = "raw-dylib"))]
extern "C-unwind" {
+13 -53
View File
@@ -10,8 +10,6 @@ use super::lauxlib::*;
use super::lua::*;
use super::luacode::*;
pub const LUA_RESUMEERROR: c_int = -1;
unsafe fn compat53_reverse(L: *mut lua_State, mut a: c_int, mut b: c_int) {
while a < b {
lua_pushvalue(L, a);
@@ -43,7 +41,7 @@ unsafe fn compat53_findfield(L: *mut lua_State, objidx: c_int, level: c_int) ->
} else if compat53_findfield(L, objidx, level - 1) != 0 {
// try recursively
lua_remove(L, -2); // remove table (but keep name)
lua_pushliteral(L, c".");
lua_pushliteral(L, ".");
lua_insert(L, -2); // place '.' between the two names
lua_concat(L, 3);
return 1;
@@ -77,7 +75,7 @@ unsafe fn compat53_pushfuncname(L: *mut lua_State, level: c_int, ar: *mut lua_De
lua_pushfstring(L, cstr!("function '%s'"), lua_tostring(L, -1));
lua_remove(L, -2); // remove name
} else {
lua_pushliteral(L, c"?");
lua_pushliteral(L, "?");
}
}
@@ -127,11 +125,6 @@ pub unsafe fn lua_isinteger(L: *mut lua_State, idx: c_int) -> c_int {
0
}
#[inline(always)]
pub unsafe fn lua_pushinteger(L: *mut lua_State, i: lua_Integer) {
lua_pushnumber(L, i as lua_Number);
}
#[inline(always)]
pub unsafe fn lua_tointeger(L: *mut lua_State, i: c_int) -> lua_Integer {
lua_tointegerx(L, i, ptr::null_mut())
@@ -183,7 +176,6 @@ pub unsafe fn lua_geti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) -> c_i
#[inline(always)]
pub unsafe fn lua_rawgeti(L: *mut lua_State, idx: c_int, n: lua_Integer) -> c_int {
let n = n.try_into().expect("cannot convert index from lua_Integer");
lua_rawgeti_(L, idx, n)
}
@@ -198,7 +190,7 @@ pub unsafe fn lua_rawgetp(L: *mut lua_State, idx: c_int, p: *const c_void) -> c_
pub unsafe fn lua_getuservalue(L: *mut lua_State, mut idx: c_int) -> c_int {
luaL_checkstack(L, 2, cstr!("not enough stack slots available"));
idx = lua_absindex(L, idx);
lua_pushliteral(L, c"__mlua_uservalues");
lua_pushliteral(L, "__mlua_uservalues");
if lua_rawget(L, LUA_REGISTRYINDEX) != LUA_TTABLE {
return LUA_TNIL;
}
@@ -219,7 +211,6 @@ pub unsafe fn lua_seti(L: *mut lua_State, mut idx: c_int, n: lua_Integer) {
#[inline(always)]
pub unsafe fn lua_rawseti(L: *mut lua_State, idx: c_int, n: lua_Integer) {
let n = n.try_into().expect("cannot convert index from lua_Integer");
lua_rawseti_(L, idx, n)
}
@@ -236,13 +227,13 @@ pub unsafe fn lua_rawsetp(L: *mut lua_State, idx: c_int, p: *const c_void) {
pub unsafe fn lua_setuservalue(L: *mut lua_State, mut idx: c_int) {
luaL_checkstack(L, 4, cstr!("not enough stack slots available"));
idx = lua_absindex(L, idx);
lua_pushliteral(L, c"__mlua_uservalues");
lua_pushliteral(L, "__mlua_uservalues");
lua_pushvalue(L, -1);
if lua_rawget(L, LUA_REGISTRYINDEX) != LUA_TTABLE {
lua_pop(L, 1);
lua_createtable(L, 0, 2); // main table
lua_createtable(L, 0, 1); // metatable
lua_pushliteral(L, c"k");
lua_pushliteral(L, "k");
lua_setfield(L, -2, cstr!("__mode"));
lua_setmetatable(L, -2);
lua_pushvalue(L, -2);
@@ -293,19 +284,6 @@ pub unsafe fn lua_resume(L: *mut lua_State, from: *mut lua_State, narg: c_int, n
ret
}
#[inline(always)]
pub unsafe fn lua_resumex(L: *mut lua_State, from: *mut lua_State, narg: c_int, nres: *mut c_int) -> c_int {
let ret = if narg == LUA_RESUMEERROR {
lua_resumeerror(L, from)
} else {
lua_resume_(L, from, narg)
};
if (ret == LUA_OK || ret == LUA_YIELD) && !(nres.is_null()) {
*nres = lua_gettop(L);
}
ret
}
//
// lauxlib ported functions
//
@@ -316,30 +294,12 @@ pub unsafe fn luaL_checkstack(L: *mut lua_State, sz: c_int, msg: *const c_char)
if !msg.is_null() {
luaL_error(L, cstr!("stack overflow (%s)"), msg);
} else {
lua_pushliteral(L, c"stack overflow");
lua_pushliteral(L, "stack overflow");
lua_error(L);
}
}
}
#[inline(always)]
pub unsafe fn luaL_checkinteger(L: *mut lua_State, narg: c_int) -> lua_Integer {
let mut isnum = 0;
let int = lua_tointegerx(L, narg, &mut isnum);
if isnum == 0 {
luaL_typeerror(L, narg, lua_typename(L, LUA_TNUMBER));
}
int
}
pub unsafe fn luaL_optinteger(L: *mut lua_State, narg: c_int, def: lua_Integer) -> lua_Integer {
if lua_isnoneornil(L, narg) != 0 {
def
} else {
luaL_checkinteger(L, narg)
}
}
#[inline(always)]
pub unsafe fn luaL_getmetafield(L: *mut lua_State, obj: c_int, e: *const c_char) -> c_int {
if luaL_getmetafield_(L, obj, e) != 0 {
@@ -372,7 +332,7 @@ pub unsafe fn luaL_loadbufferenv(
fn free(p: *mut c_void);
}
unsafe extern "C" fn data_dtor(_: *mut lua_State, data: *mut c_void) {
unsafe extern "C-unwind" fn data_dtor(data: *mut c_void) {
free(*(data as *mut *mut c_char) as *mut c_void);
}
@@ -455,11 +415,11 @@ pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const
if !msg.is_null() {
lua_pushfstring(L, cstr!("%s\n"), msg);
}
lua_pushliteral(L, c"stack traceback:");
lua_pushliteral(L, "stack traceback:");
while lua_getinfo(L1, level, cstr!(""), &mut ar) != 0 {
if level + 1 == mark {
// too many levels?
lua_pushliteral(L, c"\n\t..."); // add a '...'
lua_pushliteral(L, "\n\t..."); // add a '...'
level = numlevels - COMPAT53_LEVELS2; // and skip to last ones
} else {
lua_getinfo(L1, level, cstr!("sln"), &mut ar);
@@ -467,7 +427,7 @@ pub unsafe fn luaL_traceback(L: *mut lua_State, L1: *mut lua_State, msg: *const
if ar.currentline > 0 {
lua_pushfstring(L, cstr!("%d:"), ar.currentline);
}
lua_pushliteral(L, c" in ");
lua_pushliteral(L, " in ");
compat53_pushfuncname(L, level, &mut ar);
lua_concat(L, lua_gettop(L) - top);
}
@@ -481,16 +441,16 @@ pub unsafe fn luaL_tolstring(L: *mut lua_State, mut idx: c_int, len: *mut usize)
if luaL_callmeta(L, idx, cstr!("__tostring")) == 0 {
match lua_type(L, idx) {
LUA_TNIL => {
lua_pushliteral(L, c"nil");
lua_pushliteral(L, "nil");
}
LUA_TSTRING | LUA_TNUMBER => {
lua_pushvalue(L, idx);
}
LUA_TBOOLEAN => {
if lua_toboolean(L, idx) == 0 {
lua_pushliteral(L, c"false");
lua_pushliteral(L, "false");
} else {
lua_pushliteral(L, c"true");
lua_pushliteral(L, "true");
}
}
t => {
+5 -14
View File
@@ -3,7 +3,7 @@
use std::os::raw::{c_char, c_float, c_int, c_void};
use std::ptr;
use super::lua::{self, lua_CFunction, lua_Number, lua_State, lua_Unsigned, LUA_REGISTRYINDEX};
use super::lua::{self, lua_CFunction, lua_Integer, lua_Number, lua_State, lua_Unsigned, LUA_REGISTRYINDEX};
#[repr(C)]
pub struct luaL_Reg {
@@ -33,10 +33,8 @@ extern "C-unwind" {
pub fn luaL_checkboolean(L: *mut lua_State, narg: c_int) -> c_int;
pub fn luaL_optboolean(L: *mut lua_State, narg: c_int, def: c_int) -> c_int;
#[link_name = "luaL_checkinteger"]
pub fn luaL_checkinteger_(L: *mut lua_State, narg: c_int) -> c_int;
#[link_name = "luaL_optinteger"]
pub fn luaL_optinteger_(L: *mut lua_State, narg: c_int, def: c_int) -> c_int;
pub fn luaL_checkinteger(L: *mut lua_State, narg: c_int) -> lua_Integer;
pub fn luaL_optinteger(L: *mut lua_State, narg: c_int, def: lua_Integer) -> lua_Integer;
pub fn luaL_checkunsigned(L: *mut lua_State, narg: c_int) -> lua_Unsigned;
pub fn luaL_optunsigned(L: *mut lua_State, narg: c_int, def: lua_Unsigned) -> lua_Unsigned;
@@ -71,17 +69,10 @@ extern "C-unwind" {
pub fn luaL_newstate() -> *mut lua_State;
pub fn luaL_findtable(
L: *mut lua_State,
idx: c_int,
fname: *const c_char,
szhint: c_int,
) -> *const c_char;
// TODO: luaL_findtable
pub fn luaL_typename(L: *mut lua_State, idx: c_int) -> *const c_char;
pub fn luaL_callyieldable(L: *mut lua_State, nargs: c_int, nresults: c_int) -> c_int;
// sandbox libraries and globals
#[link_name = "luaL_sandbox"]
pub fn luaL_sandbox_(L: *mut lua_State);
@@ -150,7 +141,7 @@ pub unsafe fn luaL_sandbox(L: *mut lua_State, enabled: c_int) {
}
// set all builtin metatables to read-only
lua_pushliteral(L, c"");
lua_pushliteral(L, "");
if lua_getmetatable(L, -1) != 0 {
lua_setreadonly(L, -1, enabled);
lua_pop(L, 2);
+22 -26
View File
@@ -1,6 +1,5 @@
//! Contains definitions from `lua.h`.
use std::ffi::CStr;
use std::marker::{PhantomData, PhantomPinned};
use std::os::raw::{c_char, c_double, c_float, c_int, c_uint, c_void};
use std::{mem, ptr};
@@ -70,11 +69,8 @@ pub const LUA_MINSTACK: c_int = 20;
/// A Lua number, usually equivalent to `f64`.
pub type lua_Number = c_double;
/// A Lua integer, usually equivalent to `i64`
#[cfg(target_pointer_width = "32")]
pub type lua_Integer = i32;
#[cfg(target_pointer_width = "64")]
pub type lua_Integer = i64;
/// A Lua integer, equivalent to `i32`.
pub type lua_Integer = c_int;
/// A Lua unsigned integer, equivalent to `u32`.
pub type lua_Unsigned = c_uint;
@@ -83,12 +79,13 @@ pub type lua_Unsigned = c_uint;
pub type lua_CFunction = unsafe extern "C-unwind" fn(L: *mut lua_State) -> c_int;
pub type lua_Continuation = unsafe extern "C-unwind" fn(L: *mut lua_State, status: c_int) -> c_int;
/// Type for userdata destructor functions (no unwinding).
pub type lua_Destructor = unsafe extern "C" fn(L: *mut lua_State, *mut c_void);
/// Type for userdata destructor functions.
pub type lua_Udestructor = unsafe extern "C-unwind" fn(*mut c_void);
pub type lua_Destructor = unsafe extern "C-unwind" fn(L: *mut lua_State, *mut c_void);
/// Type for memory-allocation functions (no unwinding).
/// Type for memory-allocation functions.
pub type lua_Alloc =
unsafe extern "C" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
unsafe extern "C-unwind" fn(ud: *mut c_void, ptr: *mut c_void, osize: usize, nsize: usize) -> *mut c_void;
/// Returns Luau release version (eg. `0.xxx`).
pub const fn luau_version() -> Option<&'static str> {
@@ -139,7 +136,7 @@ extern "C-unwind" {
pub fn lua_tonumberx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Number;
#[link_name = "lua_tointegerx"]
pub fn lua_tointegerx_(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> c_int;
pub fn lua_tointegerx_(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Integer;
pub fn lua_tounsignedx(L: *mut lua_State, idx: c_int, isnum: *mut c_int) -> lua_Unsigned;
pub fn lua_tovector(L: *mut lua_State, idx: c_int) -> *const c_float;
pub fn lua_toboolean(L: *mut lua_State, idx: c_int) -> c_int;
@@ -163,8 +160,7 @@ extern "C-unwind" {
//
pub fn lua_pushnil(L: *mut lua_State);
pub fn lua_pushnumber(L: *mut lua_State, n: lua_Number);
#[link_name = "lua_pushinteger"]
pub fn lua_pushinteger_(L: *mut lua_State, n: c_int);
pub fn lua_pushinteger(L: *mut lua_State, n: lua_Integer);
pub fn lua_pushunsigned(L: *mut lua_State, n: lua_Unsigned);
#[cfg(not(feature = "luau-vector4"))]
pub fn lua_pushvector(L: *mut lua_State, x: c_float, y: c_float, z: c_float);
@@ -190,7 +186,7 @@ extern "C-unwind" {
pub fn lua_pushlightuserdatatagged(L: *mut lua_State, p: *mut c_void, tag: c_int);
pub fn lua_newuserdatatagged(L: *mut lua_State, sz: usize, tag: c_int) -> *mut c_void;
pub fn lua_newuserdatataggedwithmetatable(L: *mut lua_State, sz: usize, tag: c_int) -> *mut c_void;
pub fn lua_newuserdatadtor(L: *mut lua_State, sz: usize, dtor: lua_Destructor) -> *mut c_void;
pub fn lua_newuserdatadtor(L: *mut lua_State, sz: usize, dtor: lua_Udestructor) -> *mut c_void;
pub fn lua_newbuffer(L: *mut lua_State, sz: usize) -> *mut c_void;
@@ -289,7 +285,7 @@ extern "C-unwind" {
pub fn lua_setuserdatatag(L: *mut lua_State, idx: c_int, tag: c_int);
pub fn lua_setuserdatadtor(L: *mut lua_State, tag: c_int, dtor: Option<lua_Destructor>);
pub fn lua_getuserdatadtor(L: *mut lua_State, tag: c_int) -> Option<lua_Destructor>;
pub fn lua_setuserdatametatable(L: *mut lua_State, tag: c_int);
pub fn lua_setuserdatametatable(L: *mut lua_State, tag: c_int, idx: c_int);
pub fn lua_getuserdatametatable(L: *mut lua_State, tag: c_int);
pub fn lua_setlightuserdataname(L: *mut lua_State, tag: c_int, name: *const c_char);
pub fn lua_getlightuserdataname(L: *mut lua_State, tag: c_int) -> *const c_char;
@@ -314,13 +310,13 @@ extern "C-unwind" {
//
#[inline(always)]
pub unsafe fn lua_tonumber(L: *mut lua_State, idx: c_int) -> lua_Number {
lua_tonumberx(L, idx, ptr::null_mut())
pub unsafe fn lua_tonumber(L: *mut lua_State, i: c_int) -> lua_Number {
lua_tonumberx(L, i, ptr::null_mut())
}
#[inline(always)]
pub unsafe fn lua_tointeger_(L: *mut lua_State, idx: c_int) -> c_int {
lua_tointegerx_(L, idx, ptr::null_mut())
pub unsafe fn lua_tointeger_(L: *mut lua_State, i: c_int) -> lua_Integer {
lua_tointegerx_(L, i, ptr::null_mut())
}
#[inline(always)]
@@ -344,14 +340,12 @@ pub unsafe fn lua_newuserdata(L: *mut lua_State, sz: usize) -> *mut c_void {
}
#[inline(always)]
pub unsafe fn lua_newuserdata_t<T>(L: *mut lua_State, data: T) -> *mut T {
unsafe extern "C" fn destructor<T>(_: *mut lua_State, ud: *mut c_void) {
pub unsafe fn lua_newuserdata_t<T>(L: *mut lua_State) -> *mut T {
unsafe extern "C-unwind" fn destructor<T>(ud: *mut c_void) {
ptr::drop_in_place(ud as *mut T);
}
let ud_ptr = lua_newuserdatadtor(L, const { mem::size_of::<T>() }, destructor::<T>) as *mut T;
ptr::write(ud_ptr, data);
ud_ptr
lua_newuserdatadtor(L, mem::size_of::<T>(), destructor::<T>) as *mut T
}
// TODO: lua_strlen
@@ -407,8 +401,10 @@ pub unsafe fn lua_isnoneornil(L: *mut lua_State, n: c_int) -> c_int {
}
#[inline(always)]
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static CStr) {
lua_pushstring_(L, s.as_ptr());
pub unsafe fn lua_pushliteral(L: *mut lua_State, s: &'static str) {
use std::ffi::CString;
let c_str = CString::new(s).unwrap();
lua_pushlstring_(L, c_str.as_ptr(), c_str.as_bytes().len())
}
#[inline(always)]
+11 -11
View File
@@ -1,19 +1,19 @@
//! Contains definitions from `lualib.h`.
use std::os::raw::{c_char, c_int};
use std::os::raw::c_int;
use super::lua::lua_State;
pub const LUA_COLIBNAME: *const c_char = cstr!("coroutine");
pub const LUA_TABLIBNAME: *const c_char = cstr!("table");
pub const LUA_OSLIBNAME: *const c_char = cstr!("os");
pub const LUA_STRLIBNAME: *const c_char = cstr!("string");
pub const LUA_BITLIBNAME: *const c_char = cstr!("bit32");
pub const LUA_BUFFERLIBNAME: *const c_char = cstr!("buffer");
pub const LUA_UTF8LIBNAME: *const c_char = cstr!("utf8");
pub const LUA_MATHLIBNAME: *const c_char = cstr!("math");
pub const LUA_DBLIBNAME: *const c_char = cstr!("debug");
pub const LUA_VECLIBNAME: *const c_char = cstr!("vector");
pub const LUA_COLIBNAME: &str = "coroutine";
pub const LUA_TABLIBNAME: &str = "table";
pub const LUA_OSLIBNAME: &str = "os";
pub const LUA_STRLIBNAME: &str = "string";
pub const LUA_BITLIBNAME: &str = "bit32";
pub const LUA_BUFFERLIBNAME: &str = "buffer";
pub const LUA_UTF8LIBNAME: &str = "utf8";
pub const LUA_MATHLIBNAME: &str = "math";
pub const LUA_DBLIBNAME: &str = "debug";
pub const LUA_VECLIBNAME: &str = "vector";
extern "C-unwind" {
pub fn luaopen_base(L: *mut lua_State) -> c_int;
-154
View File
@@ -1,154 +0,0 @@
//! Contains definitions from `Require.h`.
use std::os::raw::{c_char, c_int, c_void};
use super::lua::lua_State;
pub const LUA_REGISTERED_MODULES_TABLE: *const c_char = cstr!("_REGISTEREDMODULES");
#[repr(C)]
pub enum luarequire_NavigateResult {
Success,
Ambiguous,
NotFound,
}
// Functions returning WriteSuccess are expected to set their size_out argument
// to the number of bytes written to the buffer. If WriteBufferTooSmall is
// returned, size_out should be set to the required buffer size.
#[repr(C)]
pub enum luarequire_WriteResult {
Success,
BufferTooSmall,
Failure,
}
#[repr(C)]
pub struct luarequire_Configuration {
// Returns whether requires are permitted from the given chunkname.
pub is_require_allowed:
unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void, requirer_chunkname: *const c_char) -> bool,
// Resets the internal state to point at the requirer module.
pub reset: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
requirer_chunkname: *const c_char,
) -> luarequire_NavigateResult,
// Resets the internal state to point at an aliased module, given its exact path from a configuration
// file. This function is only called when an alias's path cannot be resolved relative to its
// configuration file.
pub jump_to_alias: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
path: *const c_char,
) -> luarequire_NavigateResult,
// Navigates through the context by making mutations to the internal state.
pub to_parent: unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void) -> luarequire_NavigateResult,
pub to_child: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
name: *const c_char,
) -> luarequire_NavigateResult,
// Returns whether the context is currently pointing at a module.
pub is_module_present: unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void) -> bool,
// Provides the contents of the current module. This function is only called if is_module_present returns
// true.
pub get_contents: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
buffer: *mut c_char,
buffer_size: usize,
size_out: *mut usize,
) -> luarequire_WriteResult,
// Provides a chunkname for the current module. This will be accessible through the debug library. This
// function is only called if is_module_present returns true.
pub get_chunkname: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
buffer: *mut c_char,
buffer_size: usize,
size_out: *mut usize,
) -> luarequire_WriteResult,
// Provides a cache key representing the current module. This function is only called if
// is_module_present returns true.
pub get_cache_key: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
buffer: *mut c_char,
buffer_size: usize,
size_out: *mut usize,
) -> luarequire_WriteResult,
// Returns whether a configuration file is present in the current context.
// If not, require-by-string will call to_parent until either a configuration file is present or
// NAVIGATE_FAILURE is returned (at root).
pub is_config_present: unsafe extern "C" fn(L: *mut lua_State, ctx: *mut c_void) -> bool,
// Provides the contents of the configuration file in the current context.
// This function is only called if is_config_present returns true.
pub get_config: unsafe extern "C" fn(
L: *mut lua_State,
ctx: *mut c_void,
buffer: *mut c_char,
buffer_size: usize,
size_out: *mut usize,
) -> luarequire_WriteResult,
// Executes the module and places the result on the stack. Returns the number of results placed on the
// stack.
// Returning -1 directs the requiring thread to yield. In this case, this thread should be resumed with
// the module result pushed onto its stack.
pub load: unsafe extern "C-unwind" fn(
L: *mut lua_State,
ctx: *mut c_void,
path: *const c_char,
chunkname: *const c_char,
contents: *const c_char,
) -> c_int,
}
// Populates function pointers in the given luarequire_Configuration.
pub type luarequire_Configuration_init = unsafe extern "C" fn(config: *mut luarequire_Configuration);
extern "C-unwind" {
// Initializes and pushes the require closure onto the stack without registration.
pub fn luarequire_pushrequire(
L: *mut lua_State,
config_init: luarequire_Configuration_init,
ctx: *mut c_void,
) -> c_int;
// Initializes the require library and registers it globally.
pub fn luaopen_require(L: *mut lua_State, config_init: luarequire_Configuration_init, ctx: *mut c_void);
// Initializes and pushes a "proxyrequire" closure onto the stack.
//
// The closure takes two parameters: the string path to resolve and the chunkname of an existing
// module.
pub fn luarequire_pushproxyrequire(
L: *mut lua_State,
config_init: luarequire_Configuration_init,
ctx: *mut c_void,
) -> c_int;
// Registers an aliased require path to a result.
//
// After registration, the given result will always be immediately returned when the given path is
// required.
// Expects the path and table to be passed as arguments on the stack.
pub fn luarequire_registermodule(L: *mut lua_State) -> c_int;
// Clears the entry associated with the given cache key from the require cache.
// Expects the cache key to be passed as an argument on the stack.
pub fn luarequire_clearcacheentry(L: *mut lua_State) -> c_int;
// Clears all entries from the require cache.
pub fn luarequire_clearcache(L: *mut lua_State) -> c_int;
}
-2
View File
@@ -6,7 +6,6 @@ pub use lua::*;
pub use luacode::*;
pub use luacodegen::*;
pub use lualib::*;
pub use luarequire::*;
pub mod compat;
pub mod lauxlib;
@@ -14,4 +13,3 @@ pub mod lua;
pub mod luacode;
pub mod luacodegen;
pub mod lualib;
pub mod luarequire;
+31 -5
View File
@@ -808,9 +808,15 @@ macro_rules! lua_convert_int {
impl IntoLua for $x {
#[inline]
fn into_lua(self, _: &Lua) -> Result<Value> {
Ok(cast(self)
cast(self)
.map(Value::Integer)
.unwrap_or_else(|| Value::Number(self as ffi::lua_Number)))
.or_else(|| cast(self).map(Value::Number))
// This is impossible error because conversion to Number never fails
.ok_or_else(|| Error::ToLuaConversionError {
from: stringify!($x).to_string(),
to: "number",
message: Some("out of range".to_owned()),
})
}
#[inline]
@@ -893,7 +899,13 @@ macro_rules! lua_convert_float {
impl IntoLua for $x {
#[inline]
fn into_lua(self, _: &Lua) -> Result<Value> {
Ok(Value::Number(self as _))
cast(self)
.ok_or_else(|| Error::ToLuaConversionError {
from: stringify!($x).to_string(),
to: "number",
message: Some("out of range".to_string()),
})
.map(Value::Number)
}
}
@@ -902,19 +914,33 @@ macro_rules! lua_convert_float {
fn from_lua(value: Value, lua: &Lua) -> Result<Self> {
let ty = value.type_name();
lua.coerce_number(value)?
.map(|n| n as $x)
.ok_or_else(|| Error::FromLuaConversionError {
from: ty,
to: stringify!($x).to_string(),
message: Some("expected number or string coercible to number".to_string()),
})
.and_then(|n| {
cast(n).ok_or_else(|| Error::FromLuaConversionError {
from: ty,
to: stringify!($x).to_string(),
message: Some("number out of range".to_string()),
})
})
}
unsafe fn from_stack(idx: c_int, lua: &RawLua) -> Result<Self> {
let state = lua.state();
let type_id = ffi::lua_type(state, idx);
if type_id == ffi::LUA_TNUMBER {
return Ok(ffi::lua_tonumber(state, idx) as _);
let mut ok = 0;
let i = ffi::lua_tonumberx(state, idx, &mut ok);
if ok != 0 {
return cast(i).ok_or_else(|| Error::FromLuaConversionError {
from: "number",
to: stringify!($x).to_string(),
message: Some("out of range".to_owned()),
});
}
}
// Fallback to default
Self::from_lua(lua.stack_value(idx, Some(type_id)), lua.lua())
+2 -2
View File
@@ -280,7 +280,7 @@ impl Function {
// Traverse upvalues until we find the _ENV one
match ffi::lua_getupvalue(state, -1, i) {
s if s.is_null() => break,
s if std::ffi::CStr::from_ptr(s as _) == c"_ENV" => break,
s if std::ffi::CStr::from_ptr(s as _).to_bytes() == b"_ENV" => break,
_ => ffi::lua_pop(state, 1),
}
}
@@ -319,7 +319,7 @@ impl Function {
for i in 1..=255 {
match ffi::lua_getupvalue(state, -1, i) {
s if s.is_null() => return Ok(false),
s if std::ffi::CStr::from_ptr(s as _) == c"_ENV" => {
s if std::ffi::CStr::from_ptr(s as _).to_bytes() == b"_ENV" => {
ffi::lua_pop(state, 1);
// Create an anonymous function with the new environment
let f_with_env = lua
+2 -2
View File
@@ -210,7 +210,7 @@ pub use mlua_derive::FromLua;
///
/// You can register multiple entrypoints as required.
///
/// ```
/// ```ignore
/// use mlua::{Lua, Result, Table};
///
/// #[mlua::lua_module]
@@ -247,7 +247,7 @@ pub use mlua_derive::FromLua;
/// ...
/// }
/// ```
#[cfg(any(feature = "module", docsrs))]
#[cfg(all(feature = "mlua_derive", any(feature = "module", doc)))]
#[cfg_attr(docsrs, doc(cfg(feature = "module")))]
pub use mlua_derive::lua_module;
+1 -1
View File
@@ -51,7 +51,7 @@ unsafe extern "C-unwind" fn lua_collectgarbage(state: *mut ffi::lua_State) -> c_
1
}
Ok("step") => {
let res = ffi::lua_gc(state, ffi::LUA_GCSTEP, arg as _);
let res = ffi::lua_gc(state, ffi::LUA_GCSTEP, arg);
ffi::lua_pushboolean(state, res);
1
}
+4 -3
View File
@@ -124,15 +124,16 @@ unsafe extern "C-unwind" fn lua_require(state: *mut ffi::lua_State) -> c_int {
ffi::lua_pop(state, 1); // remove nil
// load the module
let err_buf = ffi::lua_newuserdata_t(state, StdString::new());
let err_buf = ffi::lua_newuserdata_t::<StdString>(state);
err_buf.write(StdString::new());
ffi::luaL_getsubtable(state, ffi::LUA_REGISTRYINDEX, cstr!("_LOADERS")); // _LOADERS is at index 3
for i in 1.. {
if ffi::lua_rawgeti(state, -1, i) == ffi::LUA_TNIL {
// no more loaders?
if (*err_buf).is_empty() {
if (&*err_buf).is_empty() {
ffi::luaL_error(state, cstr!("module '%s' not found"), name);
} else {
let bytes = (*err_buf).as_bytes();
let bytes = (&*err_buf).as_bytes();
let extra = ffi::lua_pushlstring(state, bytes.as_ptr() as *const _, bytes.len());
ffi::luaL_error(state, cstr!("module '%s' not found:%s"), name, extra);
}
+1 -1
View File
@@ -97,7 +97,7 @@ impl MemoryState {
}
}
unsafe extern "C" fn allocator(
unsafe extern "C-unwind" fn allocator(
extra: *mut c_void,
ptr: *mut c_void,
osize: usize,
+3 -15
View File
@@ -1021,9 +1021,7 @@ impl Lua {
) -> Chunk<'a> {
Chunk {
lua: self.weak(),
name: chunk
.name()
.unwrap_or_else(|| format!("@{}:{}", location.file(), location.line())),
name: chunk.name().unwrap_or_else(|| location.to_string()),
env: chunk.environment(self),
mode: chunk.mode(),
source: chunk.source(),
@@ -1966,12 +1964,7 @@ impl Lua {
#[inline(always)]
pub(crate) fn lock(&self) -> ReentrantMutexGuard<RawLua> {
let rawlua = self.raw.lock();
#[cfg(feature = "luau")]
if unsafe { (*rawlua.extra.get()).running_userdata_gc } {
panic!("Luau VM is suspended while userdata destructor is running");
}
rawlua
self.raw.lock()
}
#[inline(always)]
@@ -1993,12 +1986,7 @@ impl WeakLua {
#[track_caller]
#[inline(always)]
pub(crate) fn lock(&self) -> LuaGuard {
let guard = LuaGuard::new(self.0.upgrade().expect("Lua instance is destroyed"));
#[cfg(feature = "luau")]
if unsafe { (*guard.extra.get()).running_userdata_gc } {
panic!("Luau VM is suspended while userdata destructor is running");
}
guard
LuaGuard::new(self.0.upgrade().expect("Lua instance is destroyed"))
}
#[inline(always)]
-4
View File
@@ -81,8 +81,6 @@ pub(crate) struct ExtraData {
#[cfg(feature = "luau")]
pub(super) interrupt_callback: Option<crate::types::InterruptCallback>,
#[cfg(feature = "luau")]
pub(crate) running_userdata_gc: bool,
#[cfg(feature = "luau")]
pub(super) sandboxed: bool,
#[cfg(feature = "luau")]
@@ -184,8 +182,6 @@ impl ExtraData {
compiler: None,
#[cfg(feature = "luau-jit")]
enable_jit: true,
#[cfg(feature = "luau")]
running_userdata_gc: false,
}));
// Store it in the registry
+24 -7
View File
@@ -1,6 +1,6 @@
use std::any::TypeId;
use std::cell::{Cell, UnsafeCell};
use std::ffi::CStr;
use std::ffi::{CStr, CString};
use std::mem;
use std::os::raw::{c_char, c_int, c_void};
use std::panic::resume_unwind;
@@ -415,7 +415,7 @@ impl RawLua {
}
#[cfg(any(feature = "lua52", feature = "lua51", feature = "luajit"))]
{
ffi::lua_pushliteral(state, c"attempt to yield from a hook");
ffi::lua_pushliteral(state, "attempt to yield from a hook");
ffi::lua_error(state);
}
}
@@ -1265,7 +1265,7 @@ impl RawLua {
"#,
)
.try_cache()
.set_name("=__mlua_async_poll")
.set_name("__mlua_async_poll")
.set_environment(env)
.into_function()
}
@@ -1285,14 +1285,16 @@ impl RawLua {
// Uses 3 stack spaces
unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()> {
unsafe fn requiref(
#[inline(always)]
pub unsafe fn requiref(
state: *mut ffi::lua_State,
modname: *const c_char,
modname: &str,
openf: ffi::lua_CFunction,
glb: c_int,
) -> Result<()> {
protect_lua!(state, 0, 0, |state| {
ffi::luaL_requiref(state, modname, openf, glb)
let modname = mlua_expect!(CString::new(modname), "modname contains nil byte");
protect_lua!(state, 0, 1, |state| {
ffi::luaL_requiref(state, modname.as_ptr() as *const c_char, openf, glb)
})
}
@@ -1323,30 +1325,36 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
{
if libs.contains(StdLib::COROUTINE) {
requiref(state, ffi::LUA_COLIBNAME, ffi::luaopen_coroutine, 1)?;
ffi::lua_pop(state, 1);
}
}
if libs.contains(StdLib::TABLE) {
requiref(state, ffi::LUA_TABLIBNAME, ffi::luaopen_table, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(not(feature = "luau"))]
if libs.contains(StdLib::IO) {
requiref(state, ffi::LUA_IOLIBNAME, ffi::luaopen_io, 1)?;
ffi::lua_pop(state, 1);
}
if libs.contains(StdLib::OS) {
requiref(state, ffi::LUA_OSLIBNAME, ffi::luaopen_os, 1)?;
ffi::lua_pop(state, 1);
}
if libs.contains(StdLib::STRING) {
requiref(state, ffi::LUA_STRLIBNAME, ffi::luaopen_string, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(any(feature = "lua54", feature = "lua53", feature = "luau"))]
{
if libs.contains(StdLib::UTF8) {
requiref(state, ffi::LUA_UTF8LIBNAME, ffi::luaopen_utf8, 1)?;
ffi::lua_pop(state, 1);
}
}
@@ -1354,6 +1362,7 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
{
if libs.contains(StdLib::BIT) {
requiref(state, ffi::LUA_BITLIBNAME, ffi::luaopen_bit32, 1)?;
ffi::lua_pop(state, 1);
}
}
@@ -1361,30 +1370,36 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
{
if libs.contains(StdLib::BIT) {
requiref(state, ffi::LUA_BITLIBNAME, ffi::luaopen_bit, 1)?;
ffi::lua_pop(state, 1);
}
}
#[cfg(feature = "luau")]
if libs.contains(StdLib::BUFFER) {
requiref(state, ffi::LUA_BUFFERLIBNAME, ffi::luaopen_buffer, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(feature = "luau")]
if libs.contains(StdLib::VECTOR) {
requiref(state, ffi::LUA_VECLIBNAME, ffi::luaopen_vector, 1)?;
ffi::lua_pop(state, 1);
}
if libs.contains(StdLib::MATH) {
requiref(state, ffi::LUA_MATHLIBNAME, ffi::luaopen_math, 1)?;
ffi::lua_pop(state, 1);
}
if libs.contains(StdLib::DEBUG) {
requiref(state, ffi::LUA_DBLIBNAME, ffi::luaopen_debug, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(not(feature = "luau"))]
if libs.contains(StdLib::PACKAGE) {
requiref(state, ffi::LUA_LOADLIBNAME, ffi::luaopen_package, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(feature = "luau")]
if libs.contains(StdLib::PACKAGE) {
@@ -1395,11 +1410,13 @@ unsafe fn load_std_libs(state: *mut ffi::lua_State, libs: StdLib) -> Result<()>
#[cfg(feature = "luajit")]
if libs.contains(StdLib::JIT) {
requiref(state, ffi::LUA_JITLIBNAME, ffi::luaopen_jit, 1)?;
ffi::lua_pop(state, 1);
}
#[cfg(feature = "luajit")]
if libs.contains(StdLib::FFI) {
requiref(state, ffi::LUA_FFILIBNAME, ffi::luaopen_ffi, 1)?;
ffi::lua_pop(state, 1);
}
Ok(())
+3 -1
View File
@@ -221,7 +221,9 @@ impl MetaMethod {
pub(crate) const fn as_cstr(self) -> &'static CStr {
match self {
#[rustfmt::skip]
MetaMethod::Type => if cfg!(feature = "luau") { c"__type" } else { c"__name" },
MetaMethod::Type => unsafe {
CStr::from_bytes_with_nul_unchecked(if cfg!(feature = "luau") { b"__type\0" } else { b"__name\0" })
},
_ => unreachable!(),
}
}
+3 -3
View File
@@ -1,4 +1,4 @@
use std::any::{type_name, TypeId};
use std::any::TypeId;
use std::ops::{Deref, DerefMut};
use std::os::raw::c_int;
use std::{fmt, mem};
@@ -7,7 +7,7 @@ use crate::error::{Error, Result};
use crate::state::{Lua, RawLua};
use crate::traits::FromLua;
use crate::userdata::AnyUserData;
use crate::util::get_userdata;
use crate::util::{get_userdata, short_type_name};
use crate::value::Value;
use super::cell::{UserDataStorage, UserDataVariant};
@@ -449,7 +449,7 @@ fn try_value_to_userdata<T>(value: Value) -> Result<AnyUserData> {
_ => Err(Error::FromLuaConversionError {
from: value.type_name(),
to: "userdata".to_string(),
message: Some(format!("expected userdata of type {}", type_name::<T>())),
message: Some(format!("expected userdata of type {}", short_type_name::<T>())),
}),
}
}
+4 -13
View File
@@ -354,7 +354,7 @@ unsafe fn init_userdata_metatable_index(state: *mut ffi::lua_State) -> Result<()
end
"#;
protect_lua!(state, 0, 1, |state| {
let ret = ffi::luaL_loadbuffer(state, code.as_ptr(), code.count_bytes(), cstr!("__mlua_index"));
let ret = ffi::luaL_loadbuffer(state, code.as_ptr(), code.count_bytes(), cstr!("=__mlua_index"));
if ret != ffi::LUA_OK {
ffi::lua_error(state);
}
@@ -405,7 +405,8 @@ unsafe fn init_userdata_metatable_newindex(state: *mut ffi::lua_State) -> Result
end
"#;
protect_lua!(state, 0, 1, |state| {
let ret = ffi::luaL_loadbuffer(state, code.as_ptr(), code.count_bytes(), cstr!("__mlua_newindex"));
let code_len = code.count_bytes();
let ret = ffi::luaL_loadbuffer(state, code.as_ptr(), code_len, cstr!("=__mlua_newindex"));
if ret != ffi::LUA_OK {
ffi::lua_error(state);
}
@@ -436,18 +437,8 @@ pub(crate) unsafe extern "C-unwind" fn collect_userdata<T>(state: *mut ffi::lua_
// This method is called by Luau GC when it's time to collect the userdata.
#[cfg(feature = "luau")]
pub(crate) unsafe extern "C" fn collect_userdata<T>(
state: *mut ffi::lua_State,
ud: *mut std::os::raw::c_void,
) {
// Almost none Lua operations are allowed when destructor is running,
// so we need to set a flag to prevent calling any Lua functions
let extra = (*ffi::lua_callbacks(state)).userdata as *mut crate::state::ExtraData;
(*extra).running_userdata_gc = true;
// Luau does not support _any_ panics in destructors (they are declared as "C", NOT as "C-unwind"),
// so any panics will trigger `abort()`.
pub(crate) unsafe extern "C-unwind" fn collect_userdata<T>(ud: *mut std::os::raw::c_void) {
ptr::drop_in_place(ud as *mut T);
(*extra).running_userdata_gc = false;
}
// This method can be called by user or Lua GC to destroy the userdata.
+5 -8
View File
@@ -15,23 +15,20 @@ pub(crate) unsafe fn push_internal_userdata<T: TypeKey>(
#[cfg(not(feature = "luau"))]
let ud_ptr = if protect {
protect_lua!(state, 0, 1, move |state| {
let ud_ptr = ffi::lua_newuserdata(state, const { mem::size_of::<T>() }) as *mut T;
ptr::write(ud_ptr, t);
ud_ptr
ffi::lua_newuserdata(state, const { mem::size_of::<T>() }) as *mut T
})?
} else {
let ud_ptr = ffi::lua_newuserdata(state, const { mem::size_of::<T>() }) as *mut T;
ptr::write(ud_ptr, t);
ud_ptr
ffi::lua_newuserdata(state, const { mem::size_of::<T>() }) as *mut T
};
#[cfg(feature = "luau")]
let ud_ptr = if protect {
protect_lua!(state, 0, 1, move |state| ffi::lua_newuserdata_t::<T>(state, t))?
protect_lua!(state, 0, 1, move |state| ffi::lua_newuserdata_t::<T>(state))?
} else {
ffi::lua_newuserdata_t::<T>(state, t)
ffi::lua_newuserdata_t::<T>(state)
};
ptr::write(ud_ptr, t);
get_internal_metatable::<T>(state);
ffi::lua_setmetatable(state, -2);
Ok(ud_ptr)
+1 -4
View File
@@ -272,10 +272,7 @@ impl Value {
/// If the value is a Lua [`Integer`], try to convert it to `i64` or return `None` otherwise.
#[inline]
pub fn as_i64(&self) -> Option<i64> {
#[cfg(target_pointer_width = "64")]
return self.as_integer();
#[cfg(not(target_pointer_width = "64"))]
return self.as_integer().map(i64::from);
self.as_integer().map(i64::from)
}
/// Cast the value to `u64`.
+1 -1
View File
@@ -7,7 +7,7 @@ fn test_chunk_methods() -> Result<()> {
let lua = Lua::new();
#[cfg(unix)]
assert!(lua.load("return 123").name().starts_with("@tests/chunk.rs"));
assert!(lua.load("return 123").name().contains("tests/chunk.rs"));
let chunk2 = lua.load("return 123").set_name("@new_name");
assert_eq!(chunk2.name(), "@new_name");
+29 -51
View File
@@ -1,32 +1,28 @@
error[E0277]: the type `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
error[E0277]: the type `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> tests/compile/lua_norefunwindsafe.rs:7:18
|
7 | catch_unwind(|| lua.create_table().unwrap());
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
|
= help: within `Lua`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::raw::RawLua>`, which is required by `{closure@$DIR/tests/compile/lua_norefunwindsafe.rs:7:18: 7:20}: UnwindSafe`
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
= help: within `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<*mut lua_State>`
note: required because it appears within the type `Cell<*mut lua_State>`
--> $RUST/core/src/cell.rs
|
| pub struct ReentrantMutex<R, G, T: ?Sized> {
| ^^^^^^^^^^^^^^
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
| pub struct Cell<T: ?Sized> {
| ^^^^
note: required because it appears within the type `mlua::state::raw::RawLua`
--> src/state/raw.rs
|
| struct ArcInner<T: ?Sized> {
| ^^^^^^^^
note: required because it appears within the type `PhantomData<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>`
--> $RUST/core/src/marker.rs
| pub struct RawLua {
| ^^^^^^
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
--> src/types/sync.rs
|
| pub struct PhantomData<T: ?Sized>;
| ^^^^^^^^^^^
note: required because it appears within the type `Arc<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
|
| pub struct Arc<
| ^^^
| pub(crate) struct ReentrantMutex<T>(T);
| ^^^^^^^^^^^^^^
= note: required for `Rc<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>` to implement `RefUnwindSafe`
note: required because it appears within the type `Lua`
--> src/state.rs
|
@@ -44,45 +40,27 @@ note: required by a bound in `std::panic::catch_unwind`
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
| ^^^^^^^^^^ required by this bound in `catch_unwind`
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
error[E0277]: the type `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> tests/compile/lua_norefunwindsafe.rs:7:18
|
7 | catch_unwind(|| lua.create_table().unwrap());
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
|
= help: within `Lua`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`, which is required by `{closure@$DIR/tests/compile/lua_norefunwindsafe.rs:7:18: 7:20}: UnwindSafe`
note: required because it appears within the type `Cell<usize>`
--> $RUST/core/src/cell.rs
= help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::extra::ExtraData>`
= note: required for `Rc<UnsafeCell<mlua::state::extra::ExtraData>>` to implement `RefUnwindSafe`
note: required because it appears within the type `mlua::state::raw::RawLua`
--> src/state/raw.rs
|
| pub struct Cell<T: ?Sized> {
| ^^^^
note: required because it appears within the type `lock_api::remutex::RawReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
| pub struct RawLua {
| ^^^^^^
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
--> src/types/sync.rs
|
| pub struct RawReentrantMutex<R, G> {
| ^^^^^^^^^^^^^^^^^
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
|
| pub struct ReentrantMutex<R, G, T: ?Sized> {
| ^^^^^^^^^^^^^^
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
|
| struct ArcInner<T: ?Sized> {
| ^^^^^^^^
note: required because it appears within the type `PhantomData<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>`
--> $RUST/core/src/marker.rs
|
| pub struct PhantomData<T: ?Sized>;
| ^^^^^^^^^^^
note: required because it appears within the type `Arc<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
|
| pub struct Arc<
| ^^^
| pub(crate) struct ReentrantMutex<T>(T);
| ^^^^^^^^^^^^^^
= note: required for `Rc<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>` to implement `RefUnwindSafe`
note: required because it appears within the type `Lua`
--> src/state.rs
|
+1 -1
View File
@@ -8,7 +8,7 @@ error[E0277]: `Rc<Cell<i32>>` cannot be sent between threads safely
| | within this `{closure@$DIR/tests/compile/non_send.rs:11:25: 11:37}`
| required by a bound introduced by this call
|
= help: within `{closure@$DIR/tests/compile/non_send.rs:11:25: 11:37}`, the trait `Send` is not implemented for `Rc<Cell<i32>>`, which is required by `{closure@$DIR/tests/compile/non_send.rs:11:25: 11:37}: MaybeSend`
= help: within `{closure@$DIR/tests/compile/non_send.rs:11:25: 11:37}`, the trait `Send` is not implemented for `Rc<Cell<i32>>`
note: required because it's used within this closure
--> tests/compile/non_send.rs:11:25
|
+104 -47
View File
@@ -1,38 +1,38 @@
error[E0277]: the type `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> tests/compile/ref_nounwindsafe.rs:8:18
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::raw::RawLua>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
|
= help: within `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::raw::RawLua>`, which is required by `{closure@$DIR/tests/compile/ref_nounwindsafe.rs:8:18: 8:25}: UnwindSafe`
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
= help: within `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`
note: required because it appears within the type `Cell<usize>`
--> $RUST/core/src/cell.rs
|
| pub struct ReentrantMutex<R, G, T: ?Sized> {
| ^^^^^^^^^^^^^^
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
| pub struct Cell<T: ?Sized> {
| ^^^^
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| struct ArcInner<T: ?Sized> {
| ^^^^^^^^
= note: required for `NonNull<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
note: required because it appears within the type `std::sync::Weak<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
| struct RcInner<T: ?Sized> {
| ^^^^^^^
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| pub struct Weak<
| ^^^^
note: required because it appears within the type `mlua::state::WeakLua`
note: required because it appears within the type `WeakLua`
--> src/state.rs
|
| pub(crate) struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
| ^^^^^^^
note: required because it appears within the type `mlua::types::ValueRef`
--> src/types.rs
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
| ^^^^^^^
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
--> src/types/value_ref.rs
|
| pub(crate) struct ValueRef {
| ^^^^^^^^
| pub struct ValueRef {
| ^^^^^^^^
note: required because it appears within the type `LuaTable`
--> src/table.rs
|
@@ -49,51 +49,108 @@ note: required by a bound in `std::panic::catch_unwind`
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
| ^^^^^^^^^^ required by this bound in `catch_unwind`
error[E0277]: the type `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
error[E0277]: the type `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> tests/compile/ref_nounwindsafe.rs:8:18
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<usize>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<*mut lua_State>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
|
= help: within `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<usize>`, which is required by `{closure@$DIR/tests/compile/ref_nounwindsafe.rs:8:18: 8:25}: UnwindSafe`
note: required because it appears within the type `Cell<usize>`
= help: within `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`, the trait `RefUnwindSafe` is not implemented for `UnsafeCell<*mut lua_State>`
note: required because it appears within the type `Cell<*mut lua_State>`
--> $RUST/core/src/cell.rs
|
| pub struct Cell<T: ?Sized> {
| ^^^^
note: required because it appears within the type `lock_api::remutex::RawReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
note: required because it appears within the type `mlua::state::raw::RawLua`
--> src/state/raw.rs
|
| pub struct RawReentrantMutex<R, G> {
| ^^^^^^^^^^^^^^^^^
note: required because it appears within the type `lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>`
--> $CARGO/lock_api-0.4.12/src/remutex.rs
| pub struct RawLua {
| ^^^^^^
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
--> src/types/sync.rs
|
| pub struct ReentrantMutex<R, G, T: ?Sized> {
| ^^^^^^^^^^^^^^
note: required because it appears within the type `alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
| pub(crate) struct ReentrantMutex<T>(T);
| ^^^^^^^^^^^^^^
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| struct ArcInner<T: ?Sized> {
| ^^^^^^^^
= note: required for `NonNull<alloc::sync::ArcInner<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
note: required because it appears within the type `std::sync::Weak<lock_api::remutex::ReentrantMutex<parking_lot::raw_mutex::RawMutex, parking_lot::remutex::RawThreadId, mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/sync.rs
| struct RcInner<T: ?Sized> {
| ^^^^^^^
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| pub struct Weak<
| ^^^^
note: required because it appears within the type `mlua::state::WeakLua`
note: required because it appears within the type `WeakLua`
--> src/state.rs
|
| pub(crate) struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
| ^^^^^^^
note: required because it appears within the type `mlua::types::ValueRef`
--> src/types.rs
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
| ^^^^^^^
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
--> src/types/value_ref.rs
|
| pub(crate) struct ValueRef {
| ^^^^^^^^
| pub struct ValueRef {
| ^^^^^^^^
note: required because it appears within the type `LuaTable`
--> src/table.rs
|
| pub struct Table(pub(crate) ValueRef);
| ^^^^^
note: required because it's used within this closure
--> tests/compile/ref_nounwindsafe.rs:8:18
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
| ^^^^^^^
note: required by a bound in `std::panic::catch_unwind`
--> $RUST/std/src/panic.rs
|
| pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
| ^^^^^^^^^^ required by this bound in `catch_unwind`
error[E0277]: the type `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
--> tests/compile/ref_nounwindsafe.rs:8:18
|
8 | catch_unwind(move || table.set("a", "b").unwrap());
| ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `UnsafeCell<mlua::state::extra::ExtraData>` may contain interior mutability and a reference may not be safely transferrable across a catch_unwind boundary
| |
| required by a bound introduced by this call
|
= help: the trait `RefUnwindSafe` is not implemented for `UnsafeCell<mlua::state::extra::ExtraData>`
= note: required for `Rc<UnsafeCell<mlua::state::extra::ExtraData>>` to implement `RefUnwindSafe`
note: required because it appears within the type `mlua::state::raw::RawLua`
--> src/state/raw.rs
|
| pub struct RawLua {
| ^^^^^^
note: required because it appears within the type `mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>`
--> src/types/sync.rs
|
| pub(crate) struct ReentrantMutex<T>(T);
| ^^^^^^^^^^^^^^
note: required because it appears within the type `rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| struct RcInner<T: ?Sized> {
| ^^^^^^^
= note: required for `NonNull<rc::RcInner<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>>` to implement `UnwindSafe`
note: required because it appears within the type `std::rc::Weak<mlua::types::sync::inner::ReentrantMutex<mlua::state::raw::RawLua>>`
--> $RUST/alloc/src/rc.rs
|
| pub struct Weak<
| ^^^^
note: required because it appears within the type `WeakLua`
--> src/state.rs
|
| pub struct WeakLua(XWeak<ReentrantMutex<RawLua>>);
| ^^^^^^^
note: required because it appears within the type `mlua::types::value_ref::ValueRef`
--> src/types/value_ref.rs
|
| pub struct ValueRef {
| ^^^^^^^^
note: required because it appears within the type `LuaTable`
--> src/table.rs
|
+1 -1
View File
@@ -2,7 +2,7 @@ error[E0373]: closure may outlive the current function, but it borrows `inner`,
--> tests/compile/scope_callback_capture.rs:7:43
|
5 | lua.scope(|scope| {
| ----- has type `&'1 mut mlua::scope::Scope<'1, '_>`
| ----- has type `&'1 mlua::Scope<'1, '_>`
6 | let mut inner: Option<Table> = None;
7 | let f = scope.create_function_mut(|_, t: Table| {
| ^^^^^^^^^^^^^ may outlive borrowed value `inner`
+1 -1
View File
@@ -2,7 +2,7 @@ error[E0373]: closure may outlive the current function, but it borrows `test.fie
--> tests/compile/scope_invariance.rs:13:39
|
9 | lua.scope(|scope| {
| ----- has type `&'1 mut mlua::scope::Scope<'1, '_>`
| ----- has type `&'1 mlua::Scope<'1, '_>`
...
13 | scope.create_function_mut(|_, ()| {
| ^^^^^^^ may outlive borrowed value `test.field`
+1 -1
View File
@@ -2,7 +2,7 @@ error[E0499]: cannot borrow `i` as mutable more than once at a time
--> tests/compile/scope_mutable_aliasing.rs:12:51
|
10 | lua.scope(|scope| {
| ----- has type `&mut mlua::scope::Scope<'_, '1>`
| ----- has type `&mlua::Scope<'_, '1>`
11 | let _a = scope.create_userdata(MyUserData(&mut i)).unwrap();
| -----------------------------------------
| | |
+1 -1
View File
@@ -2,7 +2,7 @@ error[E0597]: `ibad` does not live long enough
--> tests/compile/scope_userdata_borrow.rs:15:46
|
11 | lua.scope(|scope| {
| ----- has type `&mut mlua::scope::Scope<'_, '1>`
| ----- has type `&mlua::Scope<'_, '1>`
...
14 | let ibad = 42;
| ---- binding `ibad` declared here
+3 -3
View File
@@ -1,6 +1,6 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::ffi::{CString, OsString};
use std::ffi::{CStr, CString, OsString};
use std::path::PathBuf;
use bstr::BString;
@@ -450,8 +450,8 @@ fn test_conv_cstring() -> Result<()> {
let s2: CString = lua.globals().get("s")?;
assert_eq!(s, s2);
let cs = c"hello";
lua.globals().set("cs", c"hello")?;
let cs = CStr::from_bytes_with_nul(b"hello\0").unwrap();
lua.globals().set("cs", cs)?;
let cs2: CString = lua.globals().get("cs")?;
assert_eq!(cs, cs2.as_c_str());
-23
View File
@@ -501,29 +501,6 @@ fn test_panic() -> Result<()> {
Ok(())
}
#[cfg(target_pointer_width = "64")]
#[test]
fn test_safe_integers() -> Result<()> {
const MAX_SAFE_INTEGER: i64 = 2i64.pow(53) - 1;
const MIN_SAFE_INTEGER: i64 = -2i64.pow(53) + 1;
let lua = Lua::new();
let f = lua.load("return ...").into_function()?;
assert_eq!(f.call::<i64>(MAX_SAFE_INTEGER)?, MAX_SAFE_INTEGER);
assert_eq!(f.call::<i64>(MIN_SAFE_INTEGER)?, MIN_SAFE_INTEGER);
// For Lua versions that does not support 64-bit integers, the values will be converted to f64
#[cfg(any(feature = "luau", feature = "lua51", feature = "luajit"))]
{
assert_ne!(f.call::<i64>(MAX_SAFE_INTEGER + 2)?, MAX_SAFE_INTEGER + 2);
assert_ne!(f.call::<i64>(MIN_SAFE_INTEGER - 2)?, MIN_SAFE_INTEGER - 2);
assert_eq!(f.call::<f64>(i64::MAX)?, i64::MAX as f64);
}
Ok(())
}
#[test]
fn test_num_conversion() -> Result<()> {
let lua = Lua::new();