mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 18:59:04 +08:00
PyStrInterned
This commit is contained in:
1 parent
bbc31364bb
commit
f8b1c65ede
5 files changed
+47
-47
No files matched your search
@@ -59,7 +59,7 @@ pub(crate) mod bool_;
|
||||
pub use bool_::PyBool;
|
||||
#[path = "str.rs"]
|
||||
pub(crate) mod pystr;
|
||||
pub use pystr::{PyStr, PyStrRef};
|
||||
pub use pystr::{PyStr, PyStrInterned, PyStrRef};
|
||||
#[path = "super.rs"]
|
||||
pub(crate) mod super_;
|
||||
pub use super_::PySuper;
|
||||
|
||||
+26
-1
@@ -9,6 +9,7 @@ use crate::{
|
||||
convert::{ToPyException, ToPyObject},
|
||||
format::{FormatSpec, FormatString, FromTemplate},
|
||||
function::{ArgIterable, FuncArgs, OptionalArg, OptionalOption, PyComparisonValue},
|
||||
intern::PyInterned,
|
||||
protocol::{PyIterReturn, PyMappingMethods, PySequenceMethods},
|
||||
sequence::SequenceOp,
|
||||
sliceable::{SequenceIndex, SliceableSequenceOp},
|
||||
@@ -227,7 +228,7 @@ impl IntoPyStrRef for &str {
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPyStrRef for &'static crate::intern::PyStrInterned {
|
||||
impl IntoPyStrRef for &'static PyStrInterned {
|
||||
#[inline]
|
||||
fn into_pystr_ref(self, _vm: &VirtualMachine) -> PyRef<PyStr> {
|
||||
self.to_owned()
|
||||
@@ -1741,3 +1742,27 @@ impl<'s> AnyStr<'s> for str {
|
||||
splited
|
||||
}
|
||||
}
|
||||
|
||||
/// The unique reference of interned PyStr
|
||||
/// Always intended to be used as a static reference
|
||||
pub type PyStrInterned = PyInterned<PyStr>;
|
||||
|
||||
impl PyStrInterned {
|
||||
#[inline]
|
||||
pub fn to_exact(&'static self) -> PyRefExact<PyStr> {
|
||||
unsafe { PyRefExact::new_unchecked(self.to_owned()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PyStrInterned {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for PyStrInterned {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
+15
-40
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
builtins::{PyStr, PyTypeRef},
|
||||
builtins::{PyStr, PyStrInterned, PyTypeRef},
|
||||
common::lock::PyRwLock,
|
||||
convert::ToPyObject,
|
||||
AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, VirtualMachine,
|
||||
@@ -42,17 +42,16 @@ impl StringPool {
|
||||
let cache = CachedPyStrRef { inner: s };
|
||||
let inserted = zelf.inner.write().insert(cache.clone());
|
||||
if inserted {
|
||||
let interned = unsafe { PyStrInterned::borrow_cache(&cache) };
|
||||
let interned = unsafe { cache.as_interned_str() };
|
||||
unsafe { interned.as_object().mark_intern() };
|
||||
interned
|
||||
} else {
|
||||
unsafe {
|
||||
PyStrInterned::borrow_cache(
|
||||
zelf.inner
|
||||
.read()
|
||||
.get(cache.as_ref())
|
||||
.expect("inserted is false"),
|
||||
)
|
||||
zelf.inner
|
||||
.read()
|
||||
.get(cache.as_ref())
|
||||
.expect("inserted is false")
|
||||
.as_interned_str()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,7 +67,7 @@ impl StringPool {
|
||||
self.inner
|
||||
.read()
|
||||
.get(s.as_ref())
|
||||
.map(|cached| unsafe { PyStrInterned::borrow_cache(cached) })
|
||||
.map(|cached| unsafe { cached.as_interned_str() })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +106,13 @@ impl AsRef<str> for CachedPyStrRef {
|
||||
}
|
||||
|
||||
impl CachedPyStrRef {
|
||||
/// # Safety
|
||||
/// the given cache must be alive while returned reference is alive
|
||||
#[inline]
|
||||
unsafe fn as_interned_str(&self) -> &'static PyStrInterned {
|
||||
std::mem::transmute_copy(self)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn as_str(&self) -> &str {
|
||||
self.inner.as_str()
|
||||
@@ -188,37 +194,6 @@ impl<T: PyPayload> ToPyObject for &'static PyInterned<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// The unique reference of interned PyStr
|
||||
/// Always intended to be used as a static reference
|
||||
pub type PyStrInterned = PyInterned<PyStr>;
|
||||
|
||||
impl PyStrInterned {
|
||||
/// # Safety
|
||||
/// the given cache must be alive while returned reference is alive
|
||||
#[inline]
|
||||
unsafe fn borrow_cache(cache: &CachedPyStrRef) -> &'static Self {
|
||||
std::mem::transmute_copy(cache)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_exact(&'static self) -> PyRefExact<PyStr> {
|
||||
unsafe { PyRefExact::new_unchecked(self.to_owned()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PyStrInterned {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.as_str(), f)
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for PyStrInterned {
|
||||
#[inline(always)]
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
mod sealed {
|
||||
use crate::{
|
||||
builtins::PyStr,
|
||||
|
||||
@@ -512,8 +512,8 @@ mod sys {
|
||||
}
|
||||
|
||||
#[pyfunction]
|
||||
fn intern(s: PyRefExact<PyStr>, vm: &VirtualMachine) -> PyRefExact<PyStr> {
|
||||
vm.ctx.intern_str(s).to_exact()
|
||||
fn intern(s: PyRefExact<PyStr>, vm: &VirtualMachine) -> PyRef<PyStr> {
|
||||
vm.ctx.intern_str(s).to_owned()
|
||||
}
|
||||
|
||||
#[pyattr]
|
||||
|
||||
@@ -7,13 +7,13 @@ use crate::{
|
||||
object, pystr,
|
||||
type_::PyAttributes,
|
||||
PyBaseException, PyComplex, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, PyInt,
|
||||
PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, PyType,
|
||||
PyTypeRef,
|
||||
PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyStrInterned, PyTuple,
|
||||
PyTupleRef, PyType, PyTypeRef,
|
||||
},
|
||||
class::{PyClassImpl, StaticType},
|
||||
exceptions,
|
||||
function::IntoPyNativeFunc,
|
||||
intern::{Internable, MaybeInterned, PyStrInterned, StringPool},
|
||||
intern::{Internable, MaybeInterned, StringPool},
|
||||
object::{PyObjectPayload, PyObjectRef, PyPayload, PyRef},
|
||||
types::{PyTypeFlags, PyTypeSlots, TypeZoo},
|
||||
};
|
||||
|
||||
Reference in new issue
Block a user