From 77e33c53388de1387413e1850d59464ad546f8d4 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 15 Oct 2021 05:59:05 +0900 Subject: [PATCH] slot_as_mapping never fails --- vm/src/protocol/mapping.rs | 2 +- vm/src/pyobjectrc.rs | 7 +++++++ vm/src/types/slot.rs | 16 +++++++--------- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/vm/src/protocol/mapping.rs b/vm/src/protocol/mapping.rs index 174652c45..6b4a1dcfe 100644 --- a/vm/src/protocol/mapping.rs +++ b/vm/src/protocol/mapping.rs @@ -36,7 +36,7 @@ impl PyMapping { let obj_cls = self.0.class(); for cls in obj_cls.iter_mro() { if let Some(f) = cls.slots.as_mapping.load() { - return f(&self.0, vm).unwrap(); + return f(&self.0, vm); } } PyMappingMethods::default() diff --git a/vm/src/pyobjectrc.rs b/vm/src/pyobjectrc.rs index 28b01bd3f..952f3ecc2 100644 --- a/vm/src/pyobjectrc.rs +++ b/vm/src/pyobjectrc.rs @@ -237,6 +237,13 @@ impl PyObjectRef { PyRef::from_obj_unchecked(self) } + /// # Safety + /// T must be the exact payload type + pub unsafe fn downcast_unchecked_ref(&self) -> &PyRef { + debug_assert!(self.payload_is::()); + &*(self as *const PyObjectRef as *const PyRef) + } + pub(crate) fn class_lock(&self) -> &PyRwLock { &self.rc.inner.typ } diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index 08898374c..4ce18e15d 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -128,7 +128,7 @@ impl Default for PyTypeFlags { } pub(crate) type GenericMethod = fn(&PyObjectRef, FuncArgs, &VirtualMachine) -> PyResult; -pub(crate) type AsMappingFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult; +pub(crate) type AsMappingFunc = fn(&PyObjectRef, &VirtualMachine) -> PyMappingMethods; pub(crate) type HashFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult; // CallFunc = GenericMethod pub(crate) type GetattroFunc = fn(PyObjectRef, PyStrRef, &VirtualMachine) -> PyResult; @@ -150,7 +150,7 @@ pub(crate) type DescrSetFunc = pub(crate) type NewFunc = fn(PyTypeRef, FuncArgs, &VirtualMachine) -> PyResult; pub(crate) type DelFunc = fn(&PyObjectRef, &VirtualMachine) -> PyResult<()>; -fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult { +fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyMappingMethods { macro_rules! then_some_closure { ($cond:expr, $closure:expr) => { if $cond { @@ -160,7 +160,7 @@ fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult(vm) @@ -189,7 +189,7 @@ fn as_mapping_wrapper(zelf: &PyObjectRef, _vm: &VirtualMachine) -> PyResult PyResult { @@ -763,11 +763,9 @@ pub trait AsBuffer: PyValue { pub trait AsMapping: PyValue { #[inline] #[pyslot] - fn slot_as_mapping(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyResult { - let zelf = zelf - .downcast_ref() - .ok_or_else(|| vm.new_type_error("unexpected payload for as_mapping".to_owned()))?; - Ok(Self::as_mapping(zelf, vm)) + fn slot_as_mapping(zelf: &PyObjectRef, vm: &VirtualMachine) -> PyMappingMethods { + let zelf = unsafe { zelf.downcast_unchecked_ref::() }; + Self::as_mapping(zelf, vm) } #[inline]