mirror of
https://github.com/mlua-rs/mlua
synced 2026-06-08 16:05:43 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 34679e105d | |||
| bc194981fc | |||
| c9715aa5d9 | |||
| c108dc8213 | |||
| e86ef9d755 | |||
| 05eb20f9c6 | |||
| 9716918517 | |||
| c88417a3b6 | |||
| 6e95386f30 |
@@ -1,3 +1,15 @@
|
||||
## v0.8.8
|
||||
|
||||
- Fix potential deadlock when trying to reuse dropped registry keys.
|
||||
- Optimize userdata methods call when __index and fields_getters are nil
|
||||
|
||||
## v0.8.7
|
||||
|
||||
- Minimum Luau updated to 0.555 (`LUAI_MAXCSTACK` limit increased to 100000)
|
||||
- `_VERSION` in Luau now includes version number
|
||||
- Fixed lifetime of `DebugNames` in `Debug::names()` and `DebugSource` in `Debug::source()`
|
||||
- Fixed subtraction overflow when calculating index for `MultiValue::get()`
|
||||
|
||||
## v0.8.6
|
||||
|
||||
- Fixed bug when recycled Registry slot can be set to Nil
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mlua"
|
||||
version = "0.8.6" # remember to update html_root_url and mlua_derive
|
||||
version = "0.8.8" # remember to update html_root_url and mlua_derive
|
||||
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@chucklefish.org>"]
|
||||
edition = "2021"
|
||||
repository = "https://github.com/khvzak/mlua"
|
||||
@@ -58,7 +58,7 @@ cc = { version = "1.0" }
|
||||
pkg-config = { version = "0.3.17" }
|
||||
lua-src = { version = ">= 544.0.0, < 550.0.0", optional = true }
|
||||
luajit-src = { version = ">= 210.4.0, < 220.0.0", optional = true }
|
||||
luau0-src = { version = "0.4.0", optional = true }
|
||||
luau0-src = { version = "0.5.0", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rustyline = "10.0"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
[crates.io]: https://crates.io/crates/mlua
|
||||
[API Documentation]: https://docs.rs/mlua/badge.svg
|
||||
[docs.rs]: https://docs.rs/mlua
|
||||
[Coverage Status]: https://codecov.io/gh/khvzak/mlua/branch/master/graph/badge.svg?token=99339FS1CG
|
||||
[Coverage Status]: https://codecov.io/gh/khvzak/mlua/branch/v0.8/graph/badge.svg?token=99339FS1CG
|
||||
[codecov.io]: https://codecov.io/gh/khvzak/mlua
|
||||
[MSRV]: https://img.shields.io/badge/rust-1.56+-brightgreen.svg?&logo=rust
|
||||
|
||||
|
||||
+6
-3
@@ -7,12 +7,15 @@ use std::ptr;
|
||||
// Option for multiple returns in 'lua_pcall' and 'lua_call'
|
||||
pub const LUA_MULTRET: c_int = -1;
|
||||
|
||||
// Max number of Lua stack slots
|
||||
const LUAI_MAXCSTACK: c_int = 100000;
|
||||
|
||||
//
|
||||
// Pseudo-indices
|
||||
//
|
||||
pub const LUA_REGISTRYINDEX: c_int = -10000;
|
||||
pub const LUA_ENVIRONINDEX: c_int = -10001;
|
||||
pub const LUA_GLOBALSINDEX: c_int = -10002;
|
||||
pub const LUA_REGISTRYINDEX: c_int = -LUAI_MAXCSTACK - 2000;
|
||||
pub const LUA_ENVIRONINDEX: c_int = -LUAI_MAXCSTACK - 2001;
|
||||
pub const LUA_GLOBALSINDEX: c_int = -LUAI_MAXCSTACK - 2002;
|
||||
|
||||
pub const fn lua_upvalueindex(i: c_int) -> c_int {
|
||||
LUA_GLOBALSINDEX - i
|
||||
|
||||
+2
-2
@@ -63,7 +63,7 @@ impl<'lua> Debug<'lua> {
|
||||
}
|
||||
|
||||
/// Corresponds to the `n` what mask.
|
||||
pub fn names(&self) -> DebugNames<'lua> {
|
||||
pub fn names(&self) -> DebugNames {
|
||||
unsafe {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
mlua_assert!(
|
||||
@@ -87,7 +87,7 @@ impl<'lua> Debug<'lua> {
|
||||
}
|
||||
|
||||
/// Corresponds to the `S` what mask.
|
||||
pub fn source(&self) -> DebugSource<'lua> {
|
||||
pub fn source(&self) -> DebugSource {
|
||||
unsafe {
|
||||
#[cfg(not(feature = "luau"))]
|
||||
mlua_assert!(
|
||||
|
||||
+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.8.6")]
|
||||
#![doc(html_root_url = "https://docs.rs/mlua/0.8.8")]
|
||||
// Deny warnings inside doc tests / examples. When this isn't present, rustdoc doesn't show *any*
|
||||
// warnings at all.
|
||||
#![doc(test(attr(deny(warnings))))]
|
||||
|
||||
+12
-7
@@ -2072,22 +2072,27 @@ impl Lua {
|
||||
let _sg = StackGuard::new(self.state);
|
||||
check_stack(self.state, 4)?;
|
||||
|
||||
let unref_list = (*self.extra.get()).registry_unref_list.clone();
|
||||
self.push_value(t)?;
|
||||
|
||||
// Try to reuse previously allocated slot
|
||||
let unref_list2 = unref_list.clone();
|
||||
let mut unref_list2 = mlua_expect!(unref_list2.lock(), "unref list poisoned");
|
||||
if let Some(registry_id) = unref_list2.as_mut().and_then(|x| x.pop()) {
|
||||
let unref_list = (*self.extra.get()).registry_unref_list.clone();
|
||||
let free_registry_id = mlua_expect!(unref_list.lock(), "unref list poisoned")
|
||||
.as_mut()
|
||||
.and_then(|x| x.pop());
|
||||
if let Some(registry_id) = free_registry_id {
|
||||
// It must be safe to replace the value without triggering memory error
|
||||
ffi::lua_rawseti(self.state, ffi::LUA_REGISTRYINDEX, registry_id as Integer);
|
||||
return Ok(RegistryKey::new(registry_id, unref_list));
|
||||
}
|
||||
|
||||
// Allocate a new RegistryKey
|
||||
let registry_id = protect_lua!(self.state, 1, 0, |state| {
|
||||
ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX)
|
||||
})?;
|
||||
let registry_id = if self.unlikely_memory_error() {
|
||||
ffi::luaL_ref(self.state, ffi::LUA_REGISTRYINDEX)
|
||||
} else {
|
||||
protect_lua!(self.state, 1, 0, |state| {
|
||||
ffi::luaL_ref(state, ffi::LUA_REGISTRYINDEX)
|
||||
})?
|
||||
};
|
||||
Ok(RegistryKey::new(registry_id, unref_list))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,12 @@ impl Lua {
|
||||
globals.raw_set("require", self.create_function(lua_require)?)?;
|
||||
globals.raw_set("vector", self.create_c_function(lua_vector)?)?;
|
||||
|
||||
// Set `_VERSION` global to include version number
|
||||
// The environment variable `LUAU_VERSION` set by the build script
|
||||
if let Some(version) = option_env!("LUAU_VERSION") {
|
||||
globals.raw_set("_VERSION", format!("Luau {version}"))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+10
-3
@@ -245,7 +245,8 @@ pub unsafe fn pop_error(state: *mut ffi::lua_State, err_code: c_int) -> Error {
|
||||
// Uses 3 (or 1 if unprotected) stack spaces, does not call checkstack.
|
||||
#[inline(always)]
|
||||
pub unsafe fn push_string(state: *mut ffi::lua_State, s: &[u8], protect: bool) -> Result<()> {
|
||||
if protect {
|
||||
// Always use protected mode if the string is too long
|
||||
if protect || s.len() > (1 << 30) {
|
||||
protect_lua!(state, 0, 1, |state| {
|
||||
ffi::lua_pushlstring(state, s.as_ptr() as *const c_char, s.len());
|
||||
})
|
||||
@@ -427,11 +428,17 @@ unsafe fn init_userdata_metatable_index(state: *mut ffi::lua_State) -> Result<()
|
||||
}
|
||||
ffi::lua_pop(state, 1);
|
||||
|
||||
// Create and cache `__index` helper
|
||||
// Create and cache `__index` generator
|
||||
let code = cstr!(
|
||||
r#"
|
||||
local error, isfunction = ...
|
||||
return function (__index, field_getters, methods)
|
||||
-- Fastpath to return methods table for index access
|
||||
if __index == nil and field_getters == nil then
|
||||
return methods
|
||||
end
|
||||
|
||||
-- Alternatively return a function for index access
|
||||
return function (self, key)
|
||||
if field_getters ~= nil then
|
||||
local field_getter = field_getters[key]
|
||||
@@ -481,7 +488,7 @@ pub unsafe fn init_userdata_metatable_newindex(state: *mut ffi::lua_State) -> Re
|
||||
}
|
||||
ffi::lua_pop(state, 1);
|
||||
|
||||
// Create and cache `__newindex` helper
|
||||
// Create and cache `__newindex` generator
|
||||
let code = cstr!(
|
||||
r#"
|
||||
local error, isfunction = ...
|
||||
|
||||
+4
-2
@@ -197,7 +197,6 @@ pub struct MultiValue<'lua>(Vec<Value<'lua>>);
|
||||
|
||||
impl<'lua> MultiValue<'lua> {
|
||||
/// Creates an empty `MultiValue` containing no values.
|
||||
#[inline]
|
||||
pub const fn new() -> MultiValue<'lua> {
|
||||
MultiValue(Vec::new())
|
||||
}
|
||||
@@ -276,7 +275,10 @@ impl<'lua> MultiValue<'lua> {
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self, index: usize) -> Option<&Value<'lua>> {
|
||||
self.0.get(self.0.len() - index - 1)
|
||||
if index < self.0.len() {
|
||||
return self.0.get(self.0.len() - index - 1);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
||||
+4
-1
@@ -276,7 +276,10 @@ fn test_error() -> Result<()> {
|
||||
end, 3)
|
||||
|
||||
local function handler(err)
|
||||
if string.match(_VERSION, ' 5%.1$') or string.match(_VERSION, ' 5%.2$') or _VERSION == "Luau" then
|
||||
if string.match(_VERSION, " 5%.1$")
|
||||
or string.match(_VERSION, " 5%.2$")
|
||||
or string.match(_VERSION, "Luau")
|
||||
then
|
||||
-- Special case for Lua 5.1/5.2 and Luau
|
||||
local caps = string.match(err, ': (%d+)$')
|
||||
if caps then
|
||||
|
||||
+19
-1
@@ -1,6 +1,6 @@
|
||||
use std::ptr;
|
||||
|
||||
use mlua::{Lua, Result, Value};
|
||||
use mlua::{Lua, MultiValue, Result, Value};
|
||||
|
||||
#[test]
|
||||
fn test_value_eq() -> Result<()> {
|
||||
@@ -63,3 +63,21 @@ fn test_value_eq() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multi_value() {
|
||||
let mut multi_value = MultiValue::new();
|
||||
assert_eq!(multi_value.len(), 0);
|
||||
assert_eq!(multi_value.get(0), None);
|
||||
|
||||
multi_value.push_front(Value::Number(2.));
|
||||
multi_value.push_front(Value::Number(1.));
|
||||
assert_eq!(multi_value.get(0), Some(&Value::Number(1.)));
|
||||
assert_eq!(multi_value.get(1), Some(&Value::Number(2.)));
|
||||
|
||||
assert_eq!(multi_value.pop_front(), Some(Value::Number(1.)));
|
||||
assert_eq!(multi_value[0], Value::Number(2.));
|
||||
|
||||
multi_value.clear();
|
||||
assert!(multi_value.is_empty());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user