Add `Table::to_pointer()` and `String::to_pointer()` functions
This commit is contained in:
parent
113f91ace3
commit
04ba93137c
|
@ -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"));
|
||||
|
|
|
@ -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> {
|
||||
|
|
18
src/table.rs
18
src/table.rs
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue