From 908f37656ac581db796556a9e0847ddab27d3ef9 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Fri, 2 Feb 2024 09:23:16 +0000 Subject: [PATCH] Add `to_pointer` function to `Function`/`Table`/`Thread` --- src/function.rs | 10 ++++++++++ src/string.rs | 2 +- src/table.rs | 2 +- src/thread.rs | 12 +++++++++++- src/userdata.rs | 12 +++++++++++- tests/function.rs | 13 +++++++++++++ tests/string.rs | 13 +++++++++++++ tests/table.rs | 13 +++++++++++++ tests/thread.rs | 13 +++++++++++++ tests/userdata.rs | 14 ++++++++++++++ 10 files changed, 100 insertions(+), 4 deletions(-) diff --git a/src/function.rs b/src/function.rs index 7182b4a..263e3c1 100644 --- a/src/function.rs +++ b/src/function.rs @@ -494,6 +494,16 @@ impl<'lua> Function<'lua> { } } + /// Converts this function to a generic C pointer. + /// + /// There is no way to convert the pointer back to its original value. + /// + /// Typically this function is used only for hashing and debug information. + #[inline] + pub fn to_pointer(&self) -> *const c_void { + self.0.to_pointer() + } + /// Convert this handle to owned version. #[cfg(all(feature = "unstable", any(not(feature = "send"), doc)))] #[cfg_attr(docsrs, doc(cfg(all(feature = "unstable", not(feature = "send")))))] diff --git a/src/string.rs b/src/string.rs index d35f618..3b805d5 100644 --- a/src/string.rs +++ b/src/string.rs @@ -132,7 +132,7 @@ impl<'lua> String<'lua> { } } - /// Converts the string to a generic C pointer. + /// Converts this string to a generic C pointer. /// /// There is no way to convert the pointer back to its original value. /// diff --git a/src/table.rs b/src/table.rs index 2a95b3a..e1c2955 100644 --- a/src/table.rs +++ b/src/table.rs @@ -591,7 +591,7 @@ impl<'lua> Table<'lua> { unsafe { ffi::lua_getreadonly(ref_thread, self.0.index) != 0 } } - /// Converts the table to a generic C pointer. + /// Converts this table to a generic C pointer. /// /// Different tables will give different pointers. /// There is no way to convert the pointer back to its original value. diff --git a/src/thread.rs b/src/thread.rs index e594297..5bd634e 100644 --- a/src/thread.rs +++ b/src/thread.rs @@ -1,4 +1,4 @@ -use std::os::raw::c_int; +use std::os::raw::{c_int, c_void}; use crate::error::{Error, Result}; #[allow(unused)] @@ -375,6 +375,16 @@ impl<'lua> Thread<'lua> { } } + /// Converts this thread to a generic C pointer. + /// + /// There is no way to convert the pointer back to its original value. + /// + /// Typically this function is used only for hashing and debug information. + #[inline] + pub fn to_pointer(&self) -> *const c_void { + self.0.to_pointer() + } + /// Convert this handle to owned version. #[cfg(all(feature = "unstable", any(not(feature = "send"), doc)))] #[cfg_attr(docsrs, doc(cfg(all(feature = "unstable", not(feature = "send")))))] diff --git a/src/userdata.rs b/src/userdata.rs index 21fc1d4..d9496a3 100644 --- a/src/userdata.rs +++ b/src/userdata.rs @@ -5,7 +5,7 @@ use std::fmt; use std::hash::Hash; use std::mem; use std::ops::{Deref, DerefMut}; -use std::os::raw::{c_char, c_int}; +use std::os::raw::{c_char, c_int, c_void}; use std::string::String as StdString; #[cfg(feature = "async")] @@ -1096,6 +1096,16 @@ impl<'lua> AnyUserData<'lua> { } } + /// Converts this userdata to a generic C pointer. + /// + /// There is no way to convert the pointer back to its original value. + /// + /// Typically this function is used only for hashing and debug information. + #[inline] + pub fn to_pointer(&self) -> *const c_void { + self.0.to_pointer() + } + /// Convert this handle to owned version. #[cfg(all(feature = "unstable", any(not(feature = "send"), doc)))] #[cfg_attr(docsrs, doc(cfg(all(feature = "unstable", not(feature = "send")))))] diff --git a/tests/function.rs b/tests/function.rs index 48efb8b..8a59a63 100644 --- a/tests/function.rs +++ b/tests/function.rs @@ -231,6 +231,19 @@ fn test_function_info() -> Result<()> { Ok(()) } +#[test] +fn test_function_pointer() -> Result<()> { + let lua = Lua::new(); + + let func1 = lua.load("return function() end").into_function()?; + let func2 = func1.call::<_, Function>(())?; + + assert_eq!(func1.to_pointer(), func1.clone().to_pointer()); + assert_ne!(func1.to_pointer(), func2.to_pointer()); + + Ok(()) +} + #[test] fn test_function_wrap() -> Result<()> { use mlua::Error; diff --git a/tests/string.rs b/tests/string.rs index f4e9927..ad06c5f 100644 --- a/tests/string.rs +++ b/tests/string.rs @@ -99,6 +99,19 @@ fn test_string_debug() -> Result<()> { Ok(()) } +#[test] +fn test_string_pointer() -> Result<()> { + let lua = Lua::new(); + + let str1 = lua.create_string("hello")?; + let str2 = lua.create_string("hello")?; + + // Lua uses string interning, so these should be the same + assert_eq!(str1.to_pointer(), str2.to_pointer()); + + Ok(()) +} + #[cfg(all(feature = "unstable", not(feature = "send")))] #[test] fn test_owned_string() -> Result<()> { diff --git a/tests/table.rs b/tests/table.rs index 2304324..04885fc 100644 --- a/tests/table.rs +++ b/tests/table.rs @@ -369,6 +369,19 @@ fn test_table_eq() -> Result<()> { Ok(()) } +#[test] +fn test_table_pointer() -> Result<()> { + let lua = Lua::new(); + + let table1 = lua.create_table()?; + let table2 = lua.create_table()?; + + assert_eq!(table1.to_pointer(), table1.clone().to_pointer()); + assert_ne!(table1.to_pointer(), table2.to_pointer()); + + Ok(()) +} + #[test] fn test_table_error() -> Result<()> { let lua = Lua::new(); diff --git a/tests/thread.rs b/tests/thread.rs index 0473e88..06bae95 100644 --- a/tests/thread.rs +++ b/tests/thread.rs @@ -191,6 +191,19 @@ fn test_coroutine_panic() { } } +#[test] +fn test_thread_pointer() -> Result<()> { + let lua = Lua::new(); + + let func = lua.load("return 123").into_function()?; + let thread = lua.create_thread(func.clone())?; + + assert_eq!(thread.to_pointer(), thread.clone().to_pointer()); + assert_ne!(thread.to_pointer(), lua.current_thread().to_pointer()); + + Ok(()) +} + #[cfg(all(feature = "unstable", not(feature = "send")))] #[test] fn test_owned_thread() -> Result<()> { diff --git a/tests/userdata.rs b/tests/userdata.rs index 0a8d329..1f41009 100644 --- a/tests/userdata.rs +++ b/tests/userdata.rs @@ -951,6 +951,20 @@ fn test_userdata_method_errors() -> Result<()> { Ok(()) } +#[test] +fn test_userdata_pointer() -> Result<()> { + let lua = Lua::new(); + + let ud1 = lua.create_any_userdata("hello")?; + let ud2 = lua.create_any_userdata("hello")?; + + assert_eq!(ud1.to_pointer(), ud1.clone().to_pointer()); + // Different userdata objects with the same value should have different pointers + assert_ne!(ud1.to_pointer(), ud2.to_pointer()); + + Ok(()) +} + #[cfg(all(feature = "unstable", not(feature = "send")))] #[test] fn test_owned_userdata() -> Result<()> {