mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c213a85ef0 | |||
| 4963cc1b8b | |||
| 418e8fba32 | |||
| 08a7e30820 | |||
| 19676bda40 | |||
| 5a06778fbc | |||
| e33bdddc7a | |||
| cfb5d3fd45 | |||
| 84a174c94d | |||
| 888b2bbf8d |
@@ -1,3 +1,12 @@
|
||||
## v0.7.3
|
||||
|
||||
- Fixed cross-compilation issue (introduced in 84a174c)
|
||||
|
||||
## v0.7.2
|
||||
|
||||
- Allow `pkg-config` to omit include paths if they equals to standard (#114).
|
||||
- Various bugfixes (eg. #121)
|
||||
|
||||
## v0.7.1
|
||||
|
||||
- Fixed traceback generation for errors (#112)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.7.1" # remember to update html_root_url and mlua_derive
|
||||
version = "0.7.3" # remember to update html_root_url and mlua_derive
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@chucklefish.org>"]
|
||||
edition = "2018"
|
||||
repository = "https://github.com/khvzak/mlua"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
`mlua` is bindings to [Lua](https://www.lua.org) programming language for Rust with a goal to provide
|
||||
_safe_ (as far as it's possible), high level, easy to use, practical and flexible API.
|
||||
|
||||
Started as [rlua] fork, `mlua` supports Lua 5.4, 5.3, 5.2 and 5.1 including LuaJIT (2.0.5 and 2.1 beta) and allows to write native Lua modules in Rust as well as use Lua in a standalone mode.
|
||||
Started as `rlua` fork, `mlua` supports Lua 5.4, 5.3, 5.2 and 5.1 including LuaJIT (2.0.5 and 2.1 beta) and allows to write native Lua modules in Rust as well as use Lua in a standalone mode.
|
||||
|
||||
`mlua` tested on Windows/macOS/Linux including module mode in [GitHub Actions] on `x86_64` platform and cross-compilation to `aarch64` (other targets are also supported).
|
||||
|
||||
|
||||
+23
-51
@@ -10,7 +10,7 @@ fn get_env_var(name: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn probe_lua() -> PathBuf {
|
||||
pub fn probe_lua() -> Option<PathBuf> {
|
||||
let include_dir = get_env_var("LUA_INC");
|
||||
let lib_dir = get_env_var("LUA_LIB");
|
||||
let lua_lib = get_env_var("LUA_LIB_NAME");
|
||||
@@ -38,73 +38,42 @@ pub fn probe_lua() -> PathBuf {
|
||||
println!("cargo:rustc-link-search=native={}", lib_dir);
|
||||
println!("cargo:rustc-link-lib={}{}", link_lib, lua_lib);
|
||||
}
|
||||
return PathBuf::from(include_dir);
|
||||
return Some(PathBuf::from(include_dir));
|
||||
}
|
||||
|
||||
// Find using `pkg-config`
|
||||
|
||||
#[cfg(feature = "lua54")]
|
||||
{
|
||||
let mut lua = pkg_config::Config::new()
|
||||
.range_version((Bound::Included("5.4"), Bound::Excluded("5.5")))
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua");
|
||||
|
||||
if lua.is_err() {
|
||||
lua = pkg_config::Config::new()
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua5.4");
|
||||
}
|
||||
|
||||
lua.unwrap().include_paths[0].clone()
|
||||
}
|
||||
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.4", "5.5", "lua5.4", "5.4");
|
||||
#[cfg(feature = "lua53")]
|
||||
{
|
||||
let mut lua = pkg_config::Config::new()
|
||||
.range_version((Bound::Included("5.3"), Bound::Excluded("5.4")))
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua");
|
||||
|
||||
if lua.is_err() {
|
||||
lua = pkg_config::Config::new()
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua5.3");
|
||||
}
|
||||
|
||||
lua.unwrap().include_paths[0].clone()
|
||||
}
|
||||
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.3", "5.4", "lua5.3", "5.3");
|
||||
#[cfg(feature = "lua52")]
|
||||
{
|
||||
let mut lua = pkg_config::Config::new()
|
||||
.range_version((Bound::Included("5.2"), Bound::Excluded("5.3")))
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua");
|
||||
|
||||
if lua.is_err() {
|
||||
lua = pkg_config::Config::new()
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua5.2");
|
||||
}
|
||||
|
||||
lua.unwrap().include_paths[0].clone()
|
||||
}
|
||||
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.2", "5.3", "lua5.2", "5.2");
|
||||
#[cfg(feature = "lua51")]
|
||||
let (incl_bound, excl_bound, alt_probe, ver) = ("5.1", "5.2", "lua5.1", "5.1");
|
||||
|
||||
#[cfg(any(
|
||||
feature = "lua54",
|
||||
feature = "lua53",
|
||||
feature = "lua52",
|
||||
feature = "lua51"
|
||||
))]
|
||||
{
|
||||
let mut lua = pkg_config::Config::new()
|
||||
.range_version((Bound::Included("5.1"), Bound::Excluded("5.2")))
|
||||
.range_version((Bound::Included(incl_bound), Bound::Excluded(excl_bound)))
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua");
|
||||
|
||||
if lua.is_err() {
|
||||
lua = pkg_config::Config::new()
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("lua5.1");
|
||||
.probe(alt_probe);
|
||||
}
|
||||
|
||||
lua.unwrap().include_paths[0].clone()
|
||||
lua.expect(&format!("cannot find Lua {} using `pkg-config`", ver))
|
||||
.include_paths
|
||||
.get(0)
|
||||
.cloned()
|
||||
}
|
||||
|
||||
#[cfg(feature = "luajit")]
|
||||
@@ -114,6 +83,9 @@ pub fn probe_lua() -> PathBuf {
|
||||
.cargo_metadata(need_lua_lib)
|
||||
.probe("luajit");
|
||||
|
||||
lua.unwrap().include_paths[0].clone()
|
||||
lua.expect("cannot find LuaJIT using `pkg-config`")
|
||||
.include_paths
|
||||
.get(0)
|
||||
.cloned()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn probe_lua() -> PathBuf {
|
||||
pub fn probe_lua() -> Option<PathBuf> {
|
||||
#[cfg(feature = "lua54")]
|
||||
let artifacts = lua_src::Build::new().build(lua_src::Lua54);
|
||||
#[cfg(feature = "lua53")]
|
||||
@@ -21,5 +21,5 @@ pub fn probe_lua() -> PathBuf {
|
||||
#[cfg(not(feature = "module"))]
|
||||
artifacts.print_cargo_metadata();
|
||||
|
||||
artifacts.include_dir().to_owned()
|
||||
Some(artifacts.include_dir().to_owned())
|
||||
}
|
||||
|
||||
+7
-3
@@ -68,11 +68,14 @@ impl CommandExt for Command {
|
||||
}
|
||||
}
|
||||
|
||||
fn build_glue<P: AsRef<Path> + std::fmt::Debug>(include_path: &P) {
|
||||
// `include_path` is optional as Lua headers can be also found in compiler standard paths
|
||||
fn build_glue(include_path: Option<impl AsRef<Path>>) {
|
||||
let build_dir = PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
|
||||
let mut config = cc::Build::new();
|
||||
config.include(include_path);
|
||||
if let Some(include_path) = include_path {
|
||||
config.include(include_path.as_ref());
|
||||
}
|
||||
|
||||
// Compile and run glue.c
|
||||
let glue = build_dir.join("glue");
|
||||
@@ -245,9 +248,10 @@ fn main() {
|
||||
|
||||
let include_dir = find::probe_lua();
|
||||
if env::var("TARGET").unwrap() != env::var("HOST").unwrap() {
|
||||
// The `probe_lua` call above is still needed here
|
||||
generate_glue().unwrap();
|
||||
} else {
|
||||
build_glue(&include_dir);
|
||||
build_glue(include_dir);
|
||||
println!("cargo:rerun-if-changed=src/ffi/glue/glue.c");
|
||||
}
|
||||
|
||||
|
||||
@@ -175,8 +175,7 @@ impl Tokens {
|
||||
pub(crate) fn retokenize(tt: TokenStream) -> Tokens {
|
||||
Tokens(
|
||||
tt.into_iter()
|
||||
.map(Tokens::from)
|
||||
.flatten()
|
||||
.flat_map(Tokens::from)
|
||||
.peekable()
|
||||
.batching(|iter| {
|
||||
// Find variable tokens
|
||||
@@ -217,7 +216,7 @@ impl From<TokenTree> for Tokens {
|
||||
|
||||
vec![Token::new_delim(b, tt.clone(), true)]
|
||||
.into_iter()
|
||||
.chain(g.stream().into_iter().map(Tokens::from).flatten())
|
||||
.chain(g.stream().into_iter().flat_map(Tokens::from))
|
||||
.chain(vec![Token::new_delim(e, tt, false)])
|
||||
.collect()
|
||||
}
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
//! [`serde::Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
|
||||
|
||||
// mlua types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/mlua/0.7.1")]
|
||||
#![doc(html_root_url = "https://docs.rs/mlua/0.7.3")]
|
||||
// Deny warnings inside doc tests / examples. When this isn't present, rustdoc doesn't show *any*
|
||||
// warnings at all.
|
||||
#![doc(test(attr(deny(warnings))))]
|
||||
|
||||
+29
-8
@@ -83,7 +83,7 @@ struct ExtraData {
|
||||
app_data: RefCell<HashMap<TypeId, Box<dyn Any + Send>>>,
|
||||
|
||||
libs: StdLib,
|
||||
mem_info: Option<Box<MemoryInfo>>,
|
||||
mem_info: Option<ptr::NonNull<MemoryInfo>>,
|
||||
safe: bool, // Same as in the Lua struct
|
||||
|
||||
ref_thread: *mut ffi::lua_State,
|
||||
@@ -180,6 +180,7 @@ impl LuaOptions {
|
||||
/// Sets [`catch_rust_panics`] option.
|
||||
///
|
||||
/// [`catch_rust_panics`]: #structfield.catch_rust_panics
|
||||
#[must_use]
|
||||
pub const fn catch_rust_panics(mut self, enabled: bool) -> Self {
|
||||
self.catch_rust_panics = enabled;
|
||||
self
|
||||
@@ -190,6 +191,7 @@ impl LuaOptions {
|
||||
/// [`thread_cache_size`]: #structfield.thread_cache_size
|
||||
#[cfg(feature = "async")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
|
||||
#[must_use]
|
||||
pub const fn thread_cache_size(mut self, size: usize) -> Self {
|
||||
self.thread_cache_size = size;
|
||||
self
|
||||
@@ -242,6 +244,9 @@ impl Drop for Lua {
|
||||
impl Drop for ExtraData {
|
||||
fn drop(&mut self) {
|
||||
*mlua_expect!(self.registry_unref_list.lock(), "unref list poisoned") = None;
|
||||
if let Some(mem_info) = self.mem_info {
|
||||
drop(unsafe { Box::from_raw(mem_info.as_ptr()) });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,13 +391,13 @@ impl Lua {
|
||||
}
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
let mut mem_info = Box::new(MemoryInfo {
|
||||
let mem_info = Box::into_raw(Box::new(MemoryInfo {
|
||||
used_memory: 0,
|
||||
memory_limit: 0,
|
||||
});
|
||||
}));
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
let state = ffi::lua_newstate(allocator, &mut *mem_info as *mut MemoryInfo as *mut c_void);
|
||||
let state = ffi::lua_newstate(allocator, mem_info as *mut c_void);
|
||||
#[cfg(any(feature = "lua51", feature = "luajit"))]
|
||||
let state = ffi::luaL_newstate();
|
||||
|
||||
@@ -406,7 +411,7 @@ impl Lua {
|
||||
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
{
|
||||
extra.mem_info = Some(mem_info);
|
||||
extra.mem_info = ptr::NonNull::new(mem_info);
|
||||
}
|
||||
|
||||
mlua_expect!(
|
||||
@@ -918,7 +923,7 @@ impl Lua {
|
||||
pub fn used_memory(&self) -> usize {
|
||||
unsafe {
|
||||
let state = self.main_state.unwrap_or(self.state);
|
||||
match &(*self.extra.get()).mem_info {
|
||||
match (*self.extra.get()).mem_info.map(|x| x.as_ref()) {
|
||||
Some(mem_info) => mem_info.used_memory as usize,
|
||||
None => {
|
||||
// Get data from the Lua GC
|
||||
@@ -942,7 +947,7 @@ impl Lua {
|
||||
#[cfg(any(feature = "lua54", feature = "lua53", feature = "lua52"))]
|
||||
pub fn set_memory_limit(&self, memory_limit: usize) -> Result<usize> {
|
||||
unsafe {
|
||||
match &mut (*self.extra.get()).mem_info {
|
||||
match (*self.extra.get()).mem_info.map(|mut x| x.as_mut()) {
|
||||
Some(mem_info) => {
|
||||
let prev_limit = mem_info.memory_limit as usize;
|
||||
mem_info.memory_limit = memory_limit as isize;
|
||||
@@ -2278,6 +2283,22 @@ impl Lua {
|
||||
}
|
||||
}
|
||||
|
||||
struct StateGuard(*mut Lua, *mut ffi::lua_State);
|
||||
|
||||
impl StateGuard {
|
||||
unsafe fn new(lua: *mut Lua, state: *mut ffi::lua_State) -> Self {
|
||||
let orig_state = (*lua).state;
|
||||
(*lua).state = state;
|
||||
Self(lua, orig_state)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for StateGuard {
|
||||
fn drop(&mut self) {
|
||||
unsafe { (*self.0).state = self.1 }
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn call_callback(state: *mut ffi::lua_State) -> c_int {
|
||||
let extra = match ffi::lua_type(state, ffi::lua_upvalueindex(1)) {
|
||||
ffi::LUA_TUSERDATA => {
|
||||
@@ -2299,7 +2320,7 @@ impl Lua {
|
||||
}
|
||||
|
||||
let lua = &mut (*upvalue).lua;
|
||||
lua.state = state;
|
||||
let _guard = StateGuard::new(lua, state);
|
||||
|
||||
let mut args = MultiValue::new_or_cached(lua);
|
||||
args.reserve(nargs as usize);
|
||||
|
||||
@@ -61,6 +61,7 @@ impl Options {
|
||||
/// Sets [`deny_unsupported_types`] option.
|
||||
///
|
||||
/// [`deny_unsupported_types`]: #structfield.deny_unsupported_types
|
||||
#[must_use]
|
||||
pub const fn deny_unsupported_types(mut self, enabled: bool) -> Self {
|
||||
self.deny_unsupported_types = enabled;
|
||||
self
|
||||
@@ -69,6 +70,7 @@ impl Options {
|
||||
/// Sets [`deny_recursive_tables`] option.
|
||||
///
|
||||
/// [`deny_recursive_tables`]: #structfield.deny_recursive_tables
|
||||
#[must_use]
|
||||
pub fn deny_recursive_tables(mut self, enabled: bool) -> Self {
|
||||
self.deny_recursive_tables = enabled;
|
||||
self
|
||||
|
||||
@@ -69,6 +69,7 @@ impl Options {
|
||||
/// Sets [`set_array_metatable`] option.
|
||||
///
|
||||
/// [`set_array_metatable`]: #structfield.set_array_metatable
|
||||
#[must_use]
|
||||
pub const fn set_array_metatable(mut self, enabled: bool) -> Self {
|
||||
self.set_array_metatable = enabled;
|
||||
self
|
||||
@@ -77,6 +78,7 @@ impl Options {
|
||||
/// Sets [`serialize_none_to_null`] option.
|
||||
///
|
||||
/// [`serialize_none_to_null`]: #structfield.serialize_none_to_null
|
||||
#[must_use]
|
||||
pub const fn serialize_none_to_null(mut self, enabled: bool) -> Self {
|
||||
self.serialize_none_to_null = enabled;
|
||||
self
|
||||
@@ -85,6 +87,7 @@ impl Options {
|
||||
/// Sets [`serialize_unit_to_null`] option.
|
||||
///
|
||||
/// [`serialize_unit_to_null`]: #structfield.serialize_unit_to_null
|
||||
#[must_use]
|
||||
pub const fn serialize_unit_to_null(mut self, enabled: bool) -> Self {
|
||||
self.serialize_unit_to_null = enabled;
|
||||
self
|
||||
|
||||
Reference in New Issue
Block a user