Add `Table::to_pointer()` and `String::to_pointer()` functions

This commit is contained in:
Alex Orlenko 2022-06-27 14:56:31 +01:00
parent 113f91ace3
commit 04ba93137c
No known key found for this signature in database
GPG Key ID: 4C150C250863B96D
4 changed files with 33 additions and 13 deletions

View File

@ -8,7 +8,6 @@ use rustc_hash::FxHashSet;
use serde::de::{self, IntoDeserializer};
use crate::error::{Error, Result};
use crate::ffi;
use crate::table::{Table, TablePairs, TableSequence};
use crate::value::Value;
@ -563,9 +562,7 @@ impl RecursionGuard {
#[inline]
fn new(table: &Table, visited: &Rc<RefCell<FxHashSet<*const c_void>>>) -> Self {
let visited = Rc::clone(visited);
let lua = table.0.lua;
let ptr =
unsafe { lua.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, table.0.index)) };
let ptr = table.to_pointer();
visited.borrow_mut().insert(ptr);
RecursionGuard { ptr, visited }
}
@ -585,9 +582,7 @@ fn check_value_if_skip(
) -> Result<bool> {
match value {
Value::Table(table) => {
let lua = table.0.lua;
let ptr =
unsafe { lua.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, table.0.index)) };
let ptr = table.to_pointer();
if visited.borrow().contains(&ptr) {
if options.deny_recursive_tables {
return Err(de::Error::custom("recursive table detected"));

View File

@ -1,5 +1,6 @@
use std::borrow::{Borrow, Cow};
use std::hash::{Hash, Hasher};
use std::os::raw::c_void;
use std::string::String as StdString;
use std::{slice, str};
@ -112,6 +113,17 @@ impl<'lua> String<'lua> {
slice::from_raw_parts(data as *const u8, size + 1)
}
}
/// Converts the string 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 {
let lua = self.0.lua;
unsafe { lua.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, self.0.index)) }
}
}
impl<'lua> AsRef<[u8]> for String<'lua> {

View File

@ -1,10 +1,11 @@
use std::marker::PhantomData;
use std::os::raw::c_void;
#[cfg(feature = "serialize")]
use {
rustc_hash::FxHashSet,
serde::ser::{self, Serialize, SerializeMap, SerializeSeq, Serializer},
std::{cell::RefCell, os::raw::c_void, result::Result as StdResult},
std::{cell::RefCell, result::Result as StdResult},
};
use crate::error::{Error, Result};
@ -382,6 +383,18 @@ impl<'lua> Table<'lua> {
unsafe { lua.ref_thread_exec(|refthr| ffi::lua_getreadonly(refthr, self.0.index) != 0) }
}
/// Converts the 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.
///
/// Typically this function is used only for hashing and debug information.
#[inline]
pub fn to_pointer(&self) -> *const c_void {
let lua = self.0.lua;
unsafe { lua.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, self.0.index)) }
}
/// Consume this table and return an iterator over the pairs of the table.
///
/// This works like the Lua `pairs` function, but does not invoke the `__pairs` metamethod.
@ -699,8 +712,7 @@ impl<'lua> Serialize for Table<'lua> {
static VISITED: RefCell<FxHashSet<*const c_void>> = RefCell::new(FxHashSet::default());
}
let lua = self.0.lua;
let ptr = unsafe { lua.ref_thread_exec(|refthr| ffi::lua_topointer(refthr, self.0.index)) };
let ptr = self.to_pointer();
let res = VISITED.with(|visited| {
{
let mut visited = visited.borrow_mut();

View File

@ -103,13 +103,14 @@ impl<'lua> Value<'lua> {
/// 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 {
unsafe {
match self {
Value::LightUserData(ud) => ud.0,
Value::String(String(v))
| Value::Table(Table(v))
| Value::Function(Function(v))
Value::Table(t) => t.to_pointer(),
Value::String(s) => s.to_pointer(),
Value::Function(Function(v))
| Value::Thread(Thread(v))
| Value::UserData(AnyUserData(v)) => v
.lua