Skip to content

Commit 9734146

Browse files
committed
Add Function::deep_clone() (Luau only)
1 parent 58be624 commit 9734146

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

src/function.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,27 @@ impl<'lua> Function<'lua> {
504504
self.0.to_pointer()
505505
}
506506

507+
/// Creates a deep clone of the Lua function.
508+
///
509+
/// Copies the function prototype and all its upvalues to the
510+
/// newly created function.
511+
///
512+
/// This function returns shallow clone (same handle) for Rust/C functions.
513+
/// Requires `feature = "luau"`
514+
#[cfg(feature = "luau")]
515+
#[cfg_attr(docsrs, doc(cfg(feature = "luau")))]
516+
pub fn deep_clone(&self) -> Self {
517+
let ref_thread = self.0.lua.ref_thread();
518+
unsafe {
519+
if ffi::lua_iscfunction(ref_thread, self.0.index) != 0 {
520+
return self.clone();
521+
}
522+
523+
ffi::lua_clonefunction(ref_thread, self.0.index);
524+
Function(self.0.lua.pop_ref_thread())
525+
}
526+
}
527+
507528
/// Convert this handle to owned version.
508529
#[cfg(all(feature = "unstable", any(not(feature = "send"), doc)))]
509530
#[cfg_attr(docsrs, doc(cfg(all(feature = "unstable", not(feature = "send")))))]

tests/function.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,27 @@ fn test_function_pointer() -> Result<()> {
244244
Ok(())
245245
}
246246

247+
#[cfg(feature = "luau")]
248+
#[test]
249+
fn test_function_deep_clone() -> Result<()> {
250+
let lua = Lua::new();
251+
252+
lua.globals().set("a", 1)?;
253+
let func1 = lua.load("a += 1; return a").into_function()?;
254+
let func2 = func1.deep_clone();
255+
256+
assert_ne!(func1.to_pointer(), func2.to_pointer());
257+
assert_eq!(func1.call::<_, i32>(())?, 2);
258+
assert_eq!(func2.call::<_, i32>(())?, 3);
259+
260+
// Check that for Rust functions deep_clone is just a clone
261+
let rust_func = lua.create_function(|_, ()| Ok(42))?;
262+
let rust_func2 = rust_func.deep_clone();
263+
assert_eq!(rust_func.to_pointer(), rust_func2.to_pointer());
264+
265+
Ok(())
266+
}
267+
247268
#[test]
248269
fn test_function_wrap() -> Result<()> {
249270
use mlua::Error;

0 commit comments

Comments
 (0)