From be81dd0923101b647850e4eb257e250d30b78d47 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Tue, 17 May 2022 07:34:01 +0900 Subject: [PATCH 1/3] PyExact as counterpart of PyExactRef --- vm/src/lib.rs | 2 +- vm/src/object/ext.rs | 100 +++++++++++++++++++++++++++++++++++++++++-- vm/src/prelude.rs | 3 +- 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/vm/src/lib.rs b/vm/src/lib.rs index c2370c4ba..a772e4604 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -77,7 +77,7 @@ pub mod vm; pub use self::convert::{TryFromBorrowedObject, TryFromObject}; pub use self::object::{ - AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef, + AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef, }; pub use self::vm::{Context, Interpreter, Settings, VirtualMachine}; diff --git a/vm/src/object/ext.rs b/vm/src/object/ext.rs index 67105953f..d46490af0 100644 --- a/vm/src/object/ext.rs +++ b/vm/src/object/ext.rs @@ -58,7 +58,66 @@ where } } +#[repr(transparent)] +pub struct PyExact { + inner: Py, +} + +impl PyExact { + /// # Safety + /// Given reference must be exact type of payload T + #[inline(always)] + pub unsafe fn ref_unchecked(r: &Py) -> &Self { + &*(r as *const _ as *const Self) + } +} + +impl Deref for PyExact { + type Target = Py; + #[inline(always)] + fn deref(&self) -> &Py { + &self.inner + } +} + +impl Borrow for PyExact { + #[inline(always)] + fn borrow(&self) -> &PyObject { + self.inner.borrow() + } +} + +impl AsRef for PyExact { + #[inline(always)] + fn as_ref(&self) -> &PyObject { + self.inner.as_ref() + } +} + +impl Borrow> for PyExact { + #[inline(always)] + fn borrow(&self) -> &Py { + &self.inner + } +} + +impl AsRef> for PyExact { + #[inline(always)] + fn as_ref(&self) -> &Py { + &self.inner + } +} + +impl std::borrow::ToOwned for PyExact { + type Owned = PyRefExact; + fn to_owned(&self) -> Self::Owned { + let owned = self.inner.to_owned(); + unsafe { PyRefExact::new_unchecked(owned) } + } +} + #[derive(Debug)] +#[repr(transparent)] pub struct PyRefExact { inner: PyRef, } @@ -109,10 +168,31 @@ impl TryFromObject for PyRefExact { } impl Deref for PyRefExact { - type Target = PyRef; + type Target = PyExact; #[inline(always)] - fn deref(&self) -> &PyRef { - &self.inner + fn deref(&self) -> &PyExact { + unsafe { PyExact::ref_unchecked(self.inner.deref()) } + } +} + +impl Borrow for PyRefExact { + #[inline(always)] + fn borrow(&self) -> &PyObject { + self.inner.borrow() + } +} + +impl AsRef for PyRefExact { + #[inline(always)] + fn as_ref(&self) -> &PyObject { + self.inner.as_ref() + } +} + +impl Borrow> for PyRefExact { + #[inline(always)] + fn borrow(&self) -> &Py { + self.inner.borrow() } } @@ -123,6 +203,20 @@ impl AsRef> for PyRefExact { } } +impl Borrow> for PyRefExact { + #[inline(always)] + fn borrow(&self) -> &PyExact { + self + } +} + +impl AsRef> for PyRefExact { + #[inline(always)] + fn as_ref(&self) -> &PyExact { + self + } +} + impl ToPyObject for PyRefExact { #[inline(always)] fn to_pyobject(self, _vm: &VirtualMachine) -> PyObjectRef { diff --git a/vm/src/prelude.rs b/vm/src/prelude.rs index 415e7da79..0bd0fe88b 100644 --- a/vm/src/prelude.rs +++ b/vm/src/prelude.rs @@ -1,6 +1,7 @@ pub use crate::{ object::{ - AsObject, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, PyWeakRef, + AsObject, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, + PyWeakRef, }, vm::{Context, Interpreter, Settings, VirtualMachine}, }; From 6d3589d245cd36dea68f344961acce6dd6e247d8 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Tue, 17 May 2022 07:52:38 +0900 Subject: [PATCH 2/3] adapt PyExact To DictKey --- vm/src/dictdatatype.rs | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 7fb97de95..3838f84e8 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -10,7 +10,7 @@ use crate::common::{ use crate::{ builtins::{PyInt, PyStr, PyStrRef}, convert::ToPyObject, - AsObject, Py, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine, + AsObject, Py, PyExact, PyObject, PyObjectRef, PyRefExact, PyResult, VirtualMachine, }; use num_traits::ToPrimitive; use std::{fmt, mem::size_of, ops::ControlFlow}; @@ -686,23 +686,23 @@ pub trait DictKey { /// to index dictionaries. impl DictKey for PyObject { type Owned = PyObjectRef; - #[inline] + #[inline(always)] fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned { self.to_owned() } - + #[inline(always)] fn key_hash(&self, vm: &VirtualMachine) -> PyResult { self.hash(vm) } - + #[inline(always)] fn key_is(&self, other: &PyObject) -> bool { self.is(other) } - + #[inline(always)] fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult { vm.identical_or_equal(self, other_key) } - + #[inline] fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult { vm.to_index(self)?.try_to_primitive(vm) } @@ -710,15 +710,15 @@ impl DictKey for PyObject { impl DictKey for Py { type Owned = PyStrRef; - #[inline] + #[inline(always)] fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned { self.to_owned() } - + #[inline] fn key_hash(&self, vm: &VirtualMachine) -> PyResult { Ok(self.hash(vm)) } - + #[inline(always)] fn key_is(&self, other: &PyObject) -> bool { self.is(other) } @@ -732,28 +732,31 @@ impl DictKey for Py { vm.bool_eq(self.as_object(), other_key) } } - + #[inline(always)] fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult { self.as_object().key_as_isize(vm) } } -impl DictKey for PyRefExact { - type Owned = Self; - #[inline] +impl DictKey for PyExact { + type Owned = PyRefExact; + #[inline(always)] fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned { - self.clone() + self.to_owned() } - + #[inline(always)] fn key_hash(&self, vm: &VirtualMachine) -> PyResult { (**self).key_hash(vm) } + #[inline] fn key_is(&self, other: &PyObject) -> bool { (**self).key_is(other) } + #[inline(always)] fn key_eq(&self, vm: &VirtualMachine, other_key: &PyObject) -> PyResult { (**self).key_eq(vm, other_key) } + #[inline(always)] fn key_as_isize(&self, vm: &VirtualMachine) -> PyResult { (**self).key_as_isize(vm) } @@ -765,16 +768,16 @@ impl DictKey for PyRefExact { /// to index dictionaries. impl DictKey for str { type Owned = String; - #[inline] + #[inline(always)] fn _to_owned(&self, _vm: &VirtualMachine) -> Self::Owned { self.to_owned() } - + #[inline] fn key_hash(&self, vm: &VirtualMachine) -> PyResult { // follow a similar route as the hashing of PyStrRef Ok(vm.state.hash_secret.hash_str(self)) } - + #[inline(always)] fn key_is(&self, _other: &PyObject) -> bool { // No matter who the other pyobject is, we are never the same thing, since // we are a str, not a pyobject. From cce206c41f88f21436eeda22cde62b579b7662b2 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Tue, 17 May 2022 07:55:50 +0900 Subject: [PATCH 3/3] adapt PyExact --- vm/src/builtins/str.rs | 8 +++++++- vm/src/intern.rs | 13 ++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/vm/src/builtins/str.rs b/vm/src/builtins/str.rs index 9c74de710..40f610c45 100644 --- a/vm/src/builtins/str.rs +++ b/vm/src/builtins/str.rs @@ -16,7 +16,7 @@ use crate::{ AsMapping, AsSequence, Comparable, Constructor, Hashable, IterNext, IterNextIterable, Iterable, PyComparisonOp, Unconstructible, }, - AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, + AsObject, Context, Py, PyExact, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult, TryFromBorrowedObject, VirtualMachine, }; use ascii::{AsciiStr, AsciiString}; @@ -1534,6 +1534,12 @@ impl AsRef for PyRefExact { } } +impl AsRef for PyExact { + fn as_ref(&self) -> &str { + self.as_str() + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/vm/src/intern.rs b/vm/src/intern.rs index 5ba888ed2..c07828a82 100644 --- a/vm/src/intern.rs +++ b/vm/src/intern.rs @@ -2,7 +2,7 @@ use crate::{ builtins::{PyStr, PyTypeRef}, common::lock::PyRwLock, convert::ToPyObject, - Py, PyObject, PyObjectRef, PyRef, PyRefExact, + Py, PyExact, PyObject, PyObjectRef, PyRef, PyRefExact, }; use std::{ borrow::{Borrow, ToOwned}, @@ -199,7 +199,7 @@ impl std::fmt::Display for PyStrInterned { mod sealed { use crate::{ builtins::PyStr, - object::{Py, PyRefExact}, + object::{Py, PyExact, PyRefExact}, }; pub trait SealedInternable {} @@ -211,7 +211,7 @@ mod sealed { pub trait SealedMaybeInterned {} impl SealedMaybeInterned for str {} - impl SealedMaybeInterned for PyRefExact {} + impl SealedMaybeInterned for PyExact {} impl SealedMaybeInterned for Py {} } @@ -259,6 +259,13 @@ impl MaybeInterned for str { } } +impl MaybeInterned for PyExact { + #[inline(always)] + fn as_interned(&self) -> Option<&'static PyStrInterned> { + None + } +} + impl MaybeInterned for Py { #[inline(always)] fn as_interned(&self) -> Option<&'static PyStrInterned> {