From b1f73ec29d8fbd1dfd587d8a2f63d81e8bee8966 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Tue, 8 Jul 2025 22:09:24 +0100 Subject: [PATCH] Update Luau `Compiler` methods to better control extra options: - Add `add_mutable_global` - Add `add_userdata_type` - Replace `set_library_constants` with `add_library_constant` - Add `add_disabled_builtin` --- src/chunk.rs | 91 ++++++++++++++++++++++++++++++++++++++------------ tests/chunk.rs | 18 +++++----- 2 files changed, 77 insertions(+), 32 deletions(-) diff --git a/src/chunk.rs b/src/chunk.rs index 3de6164..216ee1c 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -163,15 +163,36 @@ pub enum CompileConstant { String(String), } -#[cfg(feature = "luau")] -impl From<&'static str> for CompileConstant { - fn from(s: &'static str) -> Self { - CompileConstant::String(s.to_string()) +#[cfg(any(feature = "luau", doc))] +impl From for CompileConstant { + fn from(b: bool) -> Self { + CompileConstant::Boolean(b) } } #[cfg(any(feature = "luau", doc))] -type LibraryMemberConstantMap = std::sync::Arc>; +impl From for CompileConstant { + fn from(n: crate::Number) -> Self { + CompileConstant::Number(n) + } +} + +#[cfg(any(feature = "luau", doc))] +impl From for CompileConstant { + fn from(v: crate::Vector) -> Self { + CompileConstant::Vector(v) + } +} + +#[cfg(any(feature = "luau", doc))] +impl From<&str> for CompileConstant { + fn from(s: &str) -> Self { + CompileConstant::String(s.to_owned()) + } +} + +#[cfg(any(feature = "luau", doc))] +type LibraryMemberConstantMap = HashMap<(String, String), CompileConstant>; /// Luau compiler #[cfg(any(feature = "luau", doc))] @@ -288,23 +309,39 @@ impl Compiler { self } + /// Adds a mutable global. + /// + /// It disables the import optimization for fields accessed through it. + #[must_use] + pub fn add_mutable_global(mut self, global: impl Into) -> Self { + self.mutable_globals.push(global.into()); + self + } + /// Sets a list of globals that are mutable. /// /// It disables the import optimization for fields accessed through these. #[must_use] - pub fn set_mutable_globals>(mut self, globals: Vec) -> Self { + pub fn set_mutable_globals>(mut self, globals: impl IntoIterator) -> Self { self.mutable_globals = globals.into_iter().map(|s| s.into()).collect(); self } + /// Adds a userdata type to the list that will be included in the type information. + #[must_use] + pub fn add_userdata_type(mut self, r#type: impl Into) -> Self { + self.userdata_types.push(r#type.into()); + self + } + /// Sets a list of userdata types that will be included in the type information. #[must_use] - pub fn set_userdata_types>(mut self, types: Vec) -> Self { + pub fn set_userdata_types>(mut self, types: impl IntoIterator) -> Self { self.userdata_types = types.into_iter().map(|s| s.into()).collect(); self } - /// Sets constants for known library members. + /// Adds a constant for a known library member. /// /// The constants are used by the compiler to optimize the generated bytecode. /// Optimization level must be at least 2 for this to have any effect. @@ -312,25 +349,35 @@ impl Compiler { /// The first element of the tuple is the library name,the second is the member name, and the /// third is the constant value. #[must_use] - pub fn set_library_constants(mut self, constants: Vec<(L, M, CompileConstant)>) -> Self - where - L: Into, - M: Into, - { - let map = constants - .into_iter() - .map(|(lib, member, cons)| ((lib.into(), member.into()), cons)) - .collect::>(); - self.library_constants = Some(std::sync::Arc::new(map)); - self.libraries_with_known_members = (self.library_constants.clone()) - .map(|map| map.keys().map(|(lib, _)| lib.clone()).collect()) - .unwrap_or_default(); + pub fn add_library_constant( + mut self, + lib: impl Into, + member: impl Into, + r#const: impl Into, + ) -> Self { + let (lib, member) = (lib.into(), member.into()); + if !self.libraries_with_known_members.contains(&lib) { + self.libraries_with_known_members.push(lib.clone()); + } + self.library_constants + .get_or_insert_with(HashMap::new) + .insert((lib, member), r#const.into()); + self + } + + /// Adds a builtin that should be disabled. + #[must_use] + pub fn add_disabled_builtin(mut self, builtin: impl Into) -> Self { + self.disabled_builtins.push(builtin.into()); self } /// Sets a list of builtins that should be disabled. #[must_use] - pub fn set_disabled_builtins>(mut self, builtins: Vec) -> Self { + pub fn set_disabled_builtins>( + mut self, + builtins: impl IntoIterator, + ) -> Self { self.disabled_builtins = builtins.into_iter().map(|s| s.into()).collect(); self } diff --git a/tests/chunk.rs b/tests/chunk.rs index 45ad95e..39b18b7 100644 --- a/tests/chunk.rs +++ b/tests/chunk.rs @@ -122,9 +122,9 @@ fn test_compiler() -> Result<()> { .set_vector_lib("vector") .set_vector_ctor("new") .set_vector_type("vector") - .set_mutable_globals(vec!["mutable_global"]) - .set_userdata_types(vec!["MyUserdata"]) - .set_disabled_builtins(vec!["tostring"]); + .set_mutable_globals(["mutable_global"]) + .set_userdata_types(["MyUserdata"]) + .set_disabled_builtins(["tostring"]); assert!(compiler.compile("return tostring(vector.new(1, 2, 3))").is_ok()); @@ -142,16 +142,14 @@ fn test_compiler() -> Result<()> { #[cfg(feature = "luau")] #[test] fn test_compiler_library_constants() { - use mlua::{CompileConstant, Compiler, Vector}; + use mlua::{Compiler, Vector}; let compiler = Compiler::new() .set_optimization_level(2) - .set_library_constants(vec![ - ("mylib", "const_bool", CompileConstant::Boolean(true)), - ("mylib", "const_num", CompileConstant::Number(123.0)), - ("mylib", "const_vec", CompileConstant::Vector(Vector::zero())), - ("mylib", "const_str", "value1".into()), - ]); + .add_library_constant("mylib", "const_bool", true) + .add_library_constant("mylib", "const_num", 123.0) + .add_library_constant("mylib", "const_vec", Vector::zero()) + .add_library_constant("mylib", "const_str", "value1"); let lua = Lua::new(); lua.set_compiler(compiler);