From be81dd0923101b647850e4eb257e250d30b78d47 Mon Sep 17 00:00:00 2001 From: Jeong Yunwon Date: Tue, 17 May 2022 07:34:01 +0900 Subject: [PATCH] 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}, };