Compare commits

...

12 Commits

Author SHA1 Message Date
Alex Orlenko f2d48ce296 v0.9.8 2024-05-15 23:17:30 +01:00
Alex Orlenko 0fa39d431d mlua_derive: v0.9.3 2024-05-15 23:14:23 +01:00
Alex Orlenko 0aa86c4d47 Update CHANGELOG 2024-05-15 23:11:50 +01:00
Alex Orlenko ea2faa3755 clippy 2024-05-15 23:11:33 +01:00
Alex Orlenko 59c9abbac7 Fix serializing same table multiple times.
Fixes #408
2024-05-14 00:42:04 +01:00
Alex Orlenko 8f3de8aa19 mlua-sys: v0.6.0 2024-05-04 21:22:17 +01:00
Alex Orlenko 317ce7caa6 Add Lua::set_fflag() to control Luau feature flags 2024-05-04 21:15:22 +01:00
Alex Orlenko 3a44729a48 Mark lua_Callbacks as non exhaustive (Luau) 2024-05-04 21:11:29 +01:00
Alex Orlenko 3d46fad459 Update luau-src to v0.9
Mark `lua_CompileOptions` as non exhaustive
2024-05-04 21:10:24 +01:00
Joris Willems ffc4bd599c Fix module imports for export (#394) 2024-04-18 10:22:41 +01:00
Eric Stokes 1c969da286 update build script to fix cross compilation of windows dlls from unix (#397) 2024-04-17 20:29:41 +01:00
Alex Orlenko 45fd2fa40a mlua-sys: v0.5.2 2024-04-05 14:04:15 +01:00
15 changed files with 116 additions and 31 deletions
+6
View File
@@ -1,3 +1,9 @@
## v0.9.8
- Fixed serializing same table multiple times (#408)
- Use `mlua-sys` v0.6 (to support Luau 0.624+)
- Fixed cross compilation of windows dlls from unix (#394)
## v0.9.7
- Implemented `IntoLua` for `RegistryKey`
+3 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua"
version = "0.9.7" # remember to update mlua_derive
version = "0.9.8" # remember to update mlua_derive
authors = ["Aleksandr Orlenko <zxteam@pm.me>", "kyren <catherine@kyju.org>"]
rust-version = "1.71"
edition = "2021"
@@ -44,7 +44,7 @@ macros = ["mlua_derive/macros"]
unstable = []
[dependencies]
mlua_derive = { version = "=0.9.2", optional = true, path = "mlua_derive" }
mlua_derive = { version = "=0.9.3", optional = true, path = "mlua_derive" }
bstr = { version = "1.0", features = ["std"], default_features = false }
once_cell = { version = "1.0" }
num-traits = { version = "0.2.14" }
@@ -55,7 +55,7 @@ erased-serde = { version = "0.4", optional = true }
serde-value = { version = "0.7", optional = true }
parking_lot = { version = "0.12", optional = true }
ffi = { package = "mlua-sys", version = "0.5.1", path = "mlua-sys" }
ffi = { package = "mlua-sys", version = "0.6.0", path = "mlua-sys" }
[target.'cfg(unix)'.dependencies]
libloading = { version = "0.8", optional = true }
+2 -2
View File
@@ -133,7 +133,7 @@ Add to `Cargo.toml` :
``` toml
[dependencies]
mlua = { version = "0.9.7", features = ["lua54", "vendored"] }
mlua = { version = "0.9.8", features = ["lua54", "vendored"] }
```
`main.rs`
@@ -168,7 +168,7 @@ Add to `Cargo.toml` :
crate-type = ["cdylib"]
[dependencies]
mlua = { version = "0.9.7", features = ["lua54", "module"] }
mlua = { version = "0.9.8", features = ["lua54", "module"] }
```
`lib.rs` :
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua-sys"
version = "0.5.1"
version = "0.6.0"
authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
rust-version = "1.71"
edition = "2021"
@@ -40,4 +40,4 @@ cfg-if = "1.0"
pkg-config = "0.3.17"
lua-src = { version = ">= 546.0.2, < 546.1.0", optional = true }
luajit-src = { version = ">= 210.5.0, < 210.6.0", optional = true }
luau0-src = { version = "0.8.0", optional = true }
luau0-src = { version = "0.9.0", optional = true }
+4 -2
View File
@@ -1,3 +1,5 @@
use std::env;
cfg_if::cfg_if! {
if #[cfg(any(feature = "luau", feature = "vendored"))] {
#[path = "find_vendored.rs"]
@@ -17,8 +19,8 @@ fn main() {
println!("cargo:rerun-if-changed=build");
#[cfg(windows)]
if cfg!(feature = "module") {
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
if target_os == "windows" && cfg!(feature = "module") {
if !std::env::var("LUA_LIB_NAME").unwrap_or_default().is_empty() {
// Don't use raw-dylib linking
find::probe_lua();
+6
View File
@@ -525,6 +525,7 @@ pub struct lua_Debug {
//
#[repr(C)]
#[non_exhaustive]
pub struct lua_Callbacks {
/// arbitrary userdata pointer that is never overwritten by Luau
pub userdata: *mut c_void,
@@ -552,3 +553,8 @@ pub struct lua_Callbacks {
extern "C" {
pub fn lua_callbacks(L: *mut lua_State) -> *mut lua_Callbacks;
}
// Functions from customization lib
extern "C" {
pub fn luau_setfflag(name: *const c_char, value: c_int) -> c_int;
}
+18 -1
View File
@@ -1,12 +1,14 @@
//! Contains definitions from `luacode.h`.
use std::os::raw::{c_char, c_int, c_void};
use std::slice;
use std::{ptr, slice};
#[repr(C)]
#[non_exhaustive]
pub struct lua_CompileOptions {
pub optimizationLevel: c_int,
pub debugLevel: c_int,
pub typeInfoLevel: c_int,
pub coverageLevel: c_int,
pub vectorLib: *const c_char,
pub vectorCtor: *const c_char,
@@ -14,6 +16,21 @@ pub struct lua_CompileOptions {
pub mutableGlobals: *const *const c_char,
}
impl Default for lua_CompileOptions {
fn default() -> Self {
Self {
optimizationLevel: 1,
debugLevel: 1,
typeInfoLevel: 0,
coverageLevel: 0,
vectorLib: ptr::null(),
vectorCtor: ptr::null(),
vectorType: ptr::null(),
mutableGlobals: ptr::null(),
}
}
}
extern "C-unwind" {
#[link_name = "luau_compile"]
pub fn luau_compile_(
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "mlua_derive"
version = "0.9.2"
version = "0.9.3"
authors = ["Aleksandr Orlenko <zxteam@pm.me>"]
edition = "2021"
description = "Procedural macros for the mlua crate."
+4 -4
View File
@@ -58,13 +58,13 @@ pub fn lua_module(attr: TokenStream, item: TokenStream) -> TokenStream {
};
let wrapped = quote! {
::mlua::require_module_feature!();
mlua::require_module_feature!();
#func
#[no_mangle]
unsafe extern "C-unwind" fn #ext_entrypoint_name(state: *mut ::mlua::lua_State) -> ::std::os::raw::c_int {
let lua = ::mlua::Lua::init_from_ptr(state);
unsafe extern "C-unwind" fn #ext_entrypoint_name(state: *mut mlua::lua_State) -> ::std::os::raw::c_int {
let lua = mlua::Lua::init_from_ptr(state);
#skip_memory_check
lua.entrypoint1(state, #func_name)
}
@@ -95,7 +95,7 @@ pub fn chunk(input: TokenStream) -> TokenStream {
});
let wrapped_code = quote! {{
use ::mlua::{AsChunk, ChunkMode, Lua, Result, Table};
use mlua::{AsChunk, ChunkMode, Lua, Result, Table};
use ::std::borrow::Cow;
use ::std::cell::Cell;
use ::std::io::Result as IoResult;
+21 -9
View File
@@ -122,6 +122,7 @@ pub enum ChunkMode {
pub struct Compiler {
optimization_level: u8,
debug_level: u8,
type_info_level: u8,
coverage_level: u8,
vector_lib: Option<String>,
vector_ctor: Option<String>,
@@ -144,6 +145,7 @@ impl Compiler {
Compiler {
optimization_level: 1,
debug_level: 1,
type_info_level: 0,
coverage_level: 0,
vector_lib: None,
vector_ctor: None,
@@ -176,6 +178,16 @@ impl Compiler {
self
}
/// Sets Luau type information level used to guide native code generation decisions.
///
/// Possible values:
/// * 0 - generate for native modules (default)
/// * 1 - generate for all modules
pub const fn set_type_info_level(mut self, level: u8) -> Self {
self.type_info_level = level;
self
}
/// Sets Luau compiler code coverage level.
///
/// Possible values:
@@ -250,15 +262,15 @@ impl Compiler {
}
unsafe {
let options = ffi::lua_CompileOptions {
optimizationLevel: self.optimization_level as c_int,
debugLevel: self.debug_level as c_int,
coverageLevel: self.coverage_level as c_int,
vectorLib: vector_lib.map_or(ptr::null(), |s| s.as_ptr()),
vectorCtor: vector_ctor.map_or(ptr::null(), |s| s.as_ptr()),
vectorType: vector_type.map_or(ptr::null(), |s| s.as_ptr()),
mutableGlobals: mutable_globals_ptr,
};
let mut options = ffi::lua_CompileOptions::default();
options.optimizationLevel = self.optimization_level as c_int;
options.debugLevel = self.debug_level as c_int;
options.typeInfoLevel = self.type_info_level as c_int;
options.coverageLevel = self.coverage_level as c_int;
options.vectorLib = vector_lib.map_or(ptr::null(), |s| s.as_ptr());
options.vectorCtor = vector_ctor.map_or(ptr::null(), |s| s.as_ptr());
options.vectorType = vector_type.map_or(ptr::null(), |s| s.as_ptr());
options.mutableGlobals = mutable_globals_ptr;
ffi::luau_compile(source.as_ref(), options)
}
}
+15
View File
@@ -1288,6 +1288,21 @@ impl Lua {
unsafe { (*self.extra.get()).enable_jit = enable };
}
/// Sets Luau feature flag (global setting).
///
/// See https://github.com/luau-lang/luau/blob/master/CONTRIBUTING.md#feature-flags for details.
#[cfg(feature = "luau")]
#[doc(hidden)]
#[allow(clippy::result_unit_err)]
pub fn set_fflag(name: &str, enabled: bool) -> StdResult<(), ()> {
if let Ok(name) = CString::new(name) {
if unsafe { ffi::luau_setfflag(name.as_ptr(), enabled as c_int) != 0 } {
return Ok(());
}
}
Err(())
}
/// Returns Lua source code as a `Chunk` builder type.
///
/// In order to actually compile or run the resulting code, you must call [`Chunk::exec`] or
+2 -2
View File
@@ -660,14 +660,14 @@ impl<'lua, 'de> de::VariantAccess<'de> for VariantDeserializer<'lua> {
// Adds `ptr` to the `visited` map and removes on drop
// Used to track recursive tables but allow to traverse same tables multiple times
struct RecursionGuard {
pub(crate) struct RecursionGuard {
ptr: *const c_void,
visited: Rc<RefCell<FxHashSet<*const c_void>>>,
}
impl RecursionGuard {
#[inline]
fn new(table: &Table, visited: &Rc<RefCell<FxHashSet<*const c_void>>>) -> Self {
pub(crate) fn new(table: &Table, visited: &Rc<RefCell<FxHashSet<*const c_void>>>) -> Self {
let visited = Rc::clone(visited);
let ptr = table.to_pointer();
visited.borrow_mut().insert(ptr);
+5 -5
View File
@@ -1089,7 +1089,7 @@ impl<'a, 'lua> Serialize for SerializableTable<'a, 'lua> {
where
S: Serializer,
{
use crate::serde::de::{check_value_for_skip, MapPairs};
use crate::serde::de::{check_value_for_skip, MapPairs, RecursionGuard};
use crate::value::SerializableValue;
let convert_result = |res: Result<()>, serialize_err: Option<S::Error>| match res {
@@ -1101,7 +1101,7 @@ impl<'a, 'lua> Serialize for SerializableTable<'a, 'lua> {
let options = self.options;
let visited = &self.visited;
visited.borrow_mut().insert(self.table.to_pointer());
let _guard = RecursionGuard::new(self.table, visited);
// Array
let len = self.table.raw_len();
@@ -1109,7 +1109,7 @@ impl<'a, 'lua> Serialize for SerializableTable<'a, 'lua> {
let mut seq = serializer.serialize_seq(Some(len))?;
let mut serialize_err = None;
let res = self.table.for_each_value::<Value>(|value| {
let skip = check_value_for_skip(&value, self.options, &self.visited)
let skip = check_value_for_skip(&value, self.options, visited)
.map_err(|err| Error::SerializeError(err.to_string()))?;
if skip {
// continue iteration
@@ -1129,9 +1129,9 @@ impl<'a, 'lua> Serialize for SerializableTable<'a, 'lua> {
let mut map = serializer.serialize_map(None)?;
let mut serialize_err = None;
let mut process_pair = |key, value| {
let skip_key = check_value_for_skip(&key, self.options, &self.visited)
let skip_key = check_value_for_skip(&key, self.options, visited)
.map_err(|err| Error::SerializeError(err.to_string()))?;
let skip_value = check_value_for_skip(&value, self.options, &self.visited)
let skip_value = check_value_for_skip(&value, self.options, visited)
.map_err(|err| Error::SerializeError(err.to_string()))?;
if skip_key || skip_value {
// continue iteration
+6
View File
@@ -484,3 +484,9 @@ fn test_buffer() -> Result<()> {
Ok(())
}
#[test]
fn test_fflags() {
// We cannot really on any particular feature flag to be present
assert!(Lua::set_fflag("UnknownFlag", true).is_err());
}
+21
View File
@@ -269,6 +269,27 @@ fn test_serialize_globals() -> LuaResult<()> {
Ok(())
}
#[test]
fn test_serialize_same_table_twice() -> LuaResult<()> {
let lua = Lua::new();
let value = lua
.load(
r#"
local foo = {}
return {
a = foo,
b = foo,
}
"#,
)
.eval::<Value>()?;
let json = serde_json::to_string(&value.to_serializable().sort_keys(true)).unwrap();
assert_eq!(json, r#"{"a":{},"b":{}}"#);
Ok(())
}
#[test]
fn test_to_value_struct() -> LuaResult<()> {
let lua = Lua::new();