From 0abe90dd0a49ac8658c5cc2d461f7e61970ff2fc Mon Sep 17 00:00:00 2001 From: Kangzhi Shi Date: Sun, 5 Dec 2021 10:24:28 +0200 Subject: [PATCH] move obj_as to sequence_downcast --- vm/src/builtins/bytearray.rs | 16 ++++----- vm/src/builtins/bytes.rs | 15 ++++++--- vm/src/builtins/dict.rs | 22 +++++++++---- vm/src/builtins/list.rs | 21 +++++++----- vm/src/builtins/mappingproxy.rs | 2 +- vm/src/builtins/memory.rs | 4 +-- vm/src/builtins/pystr.rs | 10 +++--- vm/src/builtins/range.rs | 58 ++++++++++++++------------------- vm/src/builtins/set.rs | 8 ++--- vm/src/builtins/tuple.rs | 10 +++--- vm/src/protocol/sequence.rs | 8 ++--- vm/src/stdlib/collections.rs | 17 +++++----- vm/src/types/slot.rs | 7 +++- 13 files changed, 103 insertions(+), 95 deletions(-) diff --git a/vm/src/builtins/bytearray.rs b/vm/src/builtins/bytearray.rs index 65ed27b89..6685b9a03 100644 --- a/vm/src/builtins/bytearray.rs +++ b/vm/src/builtins/bytearray.rs @@ -765,21 +765,21 @@ impl AsSequence for PyByteArray { impl PyByteArray { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .inner() .concat(other, vm) .map(|x| PyByteArray::from(x).into_object(vm)) }), repeat: Some(|seq, n, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .mul(n as isize, vm) .map(|x| x.into_object(vm)) }), - item: Some(|seq, i, vm| seq.obj_as::().inner().item(i, vm)), + item: Some(|seq, i, vm| Self::sequence_downcast(seq).inner().item(i, vm)), ass_item: Some(|seq, i, value, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); if let Some(value) = value { zelf.setitem_by_idx(i, value, vm) } else { @@ -788,15 +788,15 @@ impl PyByteArray { }), contains: Some(|seq, other, vm| { let other = >::try_from_object(vm, other.to_owned())?; - seq.obj_as::().contains(other, vm) + Self::sequence_downcast(seq).contains(other, vm) }), inplace_concat: Some(|seq, other, vm| { let other = ArgBytesLike::try_from_object(vm, other.to_owned())?; - let zelf = seq.obj_as::().to_owned(); + let zelf = Self::sequence_downcast(seq).to_owned(); Self::iadd(zelf, other, vm).map(|x| x.into()) }), inplace_repeat: Some(|seq, n, vm| { - let zelf = seq.obj_as::().to_owned(); + let zelf = Self::sequence_downcast(seq).to_owned(); Self::imul(zelf, n as isize, vm).map(|x| x.into()) }), }; diff --git a/vm/src/builtins/bytes.rs b/vm/src/builtins/bytes.rs index 2bdfadc39..d3f9a82f2 100644 --- a/vm/src/builtins/bytes.rs +++ b/vm/src/builtins/bytes.rs @@ -580,18 +580,23 @@ impl AsSequence for PyBytes { impl PyBytes { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .inner .concat(other, vm) .map(|x| vm.ctx.new_bytes(x).into()) }), - repeat: Some(|seq, n, vm| Ok(vm.ctx.new_bytes(seq.obj_as::().repeat(n)).into())), - item: Some(|seq, i, vm| seq.obj_as::().inner.item(i, vm)), + repeat: Some(|seq, n, vm| { + Ok(vm + .ctx + .new_bytes(Self::sequence_downcast(seq).repeat(n)) + .into()) + }), + item: Some(|seq, i, vm| Self::sequence_downcast(seq).inner.item(i, vm)), contains: Some(|seq, other, vm| { let other = >::try_from_object(vm, other.to_owned())?; - seq.obj_as::().contains(other, vm) + Self::sequence_downcast(seq).contains(other, vm) }), ..*PySequenceMethods::not_implemented() }; diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index f0b91680e..5e6fed876 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -465,7 +465,7 @@ impl AsSequence for PyDict { impl PyDict { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - contains: Some(|seq, target, vm| seq.obj_as::().entries.contains(vm, target)), + contains: Some(|seq, target, vm| Self::sequence_downcast(seq).entries.contains(vm, target)), ..*PySequenceMethods::not_implemented() }; } @@ -1029,8 +1029,13 @@ impl AsSequence for PyDictKeys { } impl PyDictKeys { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), - contains: Some(|seq, target, vm| seq.obj_as::().dict.entries.contains(vm, target)), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), + contains: Some(|seq, target, vm| { + Self::sequence_downcast(seq) + .dict + .entries + .contains(vm, target) + }), ..*PySequenceMethods::not_implemented() }; } @@ -1081,8 +1086,13 @@ impl AsSequence for PyDictItems { } impl PyDictItems { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), - contains: Some(|seq, target, vm| seq.obj_as::().dict.entries.contains(vm, target)), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), + contains: Some(|seq, target, vm| { + Self::sequence_downcast(seq) + .dict + .entries + .contains(vm, target) + }), ..*PySequenceMethods::not_implemented() }; } @@ -1101,7 +1111,7 @@ impl AsSequence for PyDictValues { } impl PyDictValues { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/builtins/list.rs b/vm/src/builtins/list.rs index 200579d29..933bad834 100644 --- a/vm/src/builtins/list.rs +++ b/vm/src/builtins/list.rs @@ -404,20 +404,24 @@ impl AsSequence for PyList { } impl PyList { const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .concat(other, vm) .map(|x| x.into_object()) }), repeat: Some(|seq, n, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .mul(n as isize, vm) .map(|x| x.into_object()) }), - item: Some(|seq, i, vm| seq.obj_as::().borrow_vec().get_item_by_index(vm, i)), + item: Some(|seq, i, vm| { + Self::sequence_downcast(seq) + .borrow_vec() + .get_item_by_index(vm, i) + }), ass_item: Some(|seq, i, value, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); if let Some(value) = value { zelf.borrow_vec_mut().set_item_by_index(vm, i, value) } else { @@ -425,19 +429,18 @@ impl PyList { } }), contains: Some(|seq, target, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.mut_contains(vm, target) }), inplace_concat: Some(|seq, other, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); Ok(Self::inplace_concat(zelf, other, vm)) }), inplace_repeat: Some(|seq, n, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.borrow_vec_mut().imul(vm, n as isize)?; Ok(zelf.to_owned().into_object()) }), - ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/builtins/mappingproxy.rs b/vm/src/builtins/mappingproxy.rs index c75dee83e..a7b4b5930 100644 --- a/vm/src/builtins/mappingproxy.rs +++ b/vm/src/builtins/mappingproxy.rs @@ -189,7 +189,7 @@ impl AsSequence for PyMappingProxy { impl PyMappingProxy { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - contains: Some(|seq, target, vm| seq.obj_as::()._contains(target, vm)), + contains: Some(|seq, target, vm| Self::sequence_downcast(seq)._contains(target, vm)), ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/builtins/memory.rs b/vm/src/builtins/memory.rs index 5b5e056ea..6be155256 100644 --- a/vm/src/builtins/memory.rs +++ b/vm/src/builtins/memory.rs @@ -991,12 +991,12 @@ impl AsSequence for PyMemoryView { impl PyMemoryView { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { length: Some(|seq, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.try_not_released(vm)?; zelf.len(vm) }), item: Some(|seq, i, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.try_not_released(vm)?; zelf.getitem_by_idx(i, vm) }), diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index ab4c4faf5..9d1f062bd 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -1298,21 +1298,21 @@ impl AsSequence for PyStr { impl PyStr { const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); Self::add(zelf.to_owned(), other.to_owned(), vm) }), repeat: Some(|seq, n, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); Self::mul(zelf.to_owned(), n as isize, vm).map(|x| x.into()) }), item: Some(|seq, i, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.get_item_by_index(vm, i) .map(|x| zelf.new_substr(x.to_string()).into_ref(vm).into()) }), - contains: Some(|seq, needle, vm| seq.obj_as::()._contains(needle, vm)), + contains: Some(|seq, needle, vm| Self::sequence_downcast(seq)._contains(needle, vm)), ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 078379ae2..6e350b4df 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -379,22 +379,36 @@ impl PyRange { } impl PyRange { + fn protocol_length(&self, vm: &VirtualMachine) -> PyResult { + self.len() + .to_isize() + .ok_or_else(|| { + vm.new_overflow_error("RustPython int too large to convert to C ssize_t".to_owned()) + }) + .map(|x| x as usize) + } + const MAPPING_METHODS: PyMappingMethods = PyMappingMethods { - length: Some(|mapping, vm| { - Self::mapping_downcast(mapping) - .len() - .to_usize() - .ok_or_else(|| { - vm.new_overflow_error( - "RustPython int too large to convert to C ssize_t".to_owned(), - ) - }) - }), + length: Some(|mapping, vm| Self::mapping_downcast(mapping).protocol_length(vm)), subscript: Some(|mapping, needle, vm| { Self::mapping_downcast(mapping).getitem(needle.to_owned(), vm) }), ass_subscript: None, }; + + const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { + length: Some(|seq, vm| Self::sequence_downcast(seq).protocol_length(vm)), + item: Some(|seq, i, vm| { + Self::sequence_downcast(seq) + .get(&i.into()) + .map(|x| PyInt::from(x).into_ref(vm).into()) + .ok_or_else(|| vm.new_index_error("index out of range".to_owned())) + }), + contains: Some(|seq, needle, vm| { + Ok(Self::sequence_downcast(seq).contains(needle.to_owned(), vm)) + }), + ..*PySequenceMethods::not_implemented() + }; } impl AsMapping for PyRange { @@ -412,30 +426,6 @@ impl AsSequence for PyRange { } } -impl PyRange { - const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, vm| { - seq.obj_as::() - .len() - .to_isize() - .ok_or_else(|| { - vm.new_overflow_error( - "RustPython int too large to convert to C ssize_t".to_owned(), - ) - }) - .map(|x| x as usize) - }), - item: Some(|seq, i, vm| { - seq.obj_as::() - .get(&i.into()) - .map(|x| PyInt::from(x).into_ref(vm).into()) - .ok_or_else(|| vm.new_index_error("index out of range".to_owned())) - }), - contains: Some(|seq, needle, vm| Ok(seq.obj_as::().contains(needle.to_owned(), vm))), - ..*PySequenceMethods::not_implemented() - }; -} - impl Hashable for PyRange { fn hash(zelf: &crate::PyObjectView, vm: &VirtualMachine) -> PyResult { let length = zelf.compute_length(); diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 362cd2b7b..e21e9ae90 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -665,8 +665,8 @@ impl AsSequence for PySet { impl PySet { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), - contains: Some(|seq, needle, vm| seq.obj_as::().inner.contains(needle, vm)), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), + contains: Some(|seq, needle, vm| Self::sequence_downcast(seq).inner.contains(needle, vm)), ..*PySequenceMethods::not_implemented() }; } @@ -905,8 +905,8 @@ impl AsSequence for PyFrozenSet { impl PyFrozenSet { const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), - contains: Some(|seq, needle, vm| seq.obj_as::().inner.contains(needle, vm)), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), + contains: Some(|seq, needle, vm| Self::sequence_downcast(seq).inner.contains(needle, vm)), ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/builtins/tuple.rs b/vm/src/builtins/tuple.rs index eafed7a88..8844f4bdc 100644 --- a/vm/src/builtins/tuple.rs +++ b/vm/src/builtins/tuple.rs @@ -340,9 +340,9 @@ impl AsSequence for PyTuple { impl PyTuple { const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); match Self::add(zelf.to_owned(), other.to_owned(), vm) { PyArithmeticValue::Implemented(tuple) => Ok(tuple.into()), PyArithmeticValue::NotImplemented => Err(vm.new_type_error(format!( @@ -352,15 +352,15 @@ impl PyTuple { } }), repeat: Some(|seq, n, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); Self::mul(zelf.to_owned(), n as isize, vm).map(|x| x.into()) }), item: Some(|seq, i, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf.elements.get_item_by_index(vm, i) }), contains: Some(|seq, needle, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf._contains(needle, vm) }), ..*PySequenceMethods::not_implemented() diff --git a/vm/src/protocol/sequence.rs b/vm/src/protocol/sequence.rs index 62e0a19eb..8d1c45d8c 100644 --- a/vm/src/protocol/sequence.rs +++ b/vm/src/protocol/sequence.rs @@ -8,8 +8,8 @@ use crate::{ common::lock::OnceCell, function::IntoPyObject, protocol::PyMapping, - IdProtocol, PyArithmeticValue, PyObject, PyObjectPayload, PyObjectRef, PyObjectView, PyResult, - PyValue, TypeProtocol, VirtualMachine, + IdProtocol, PyArithmeticValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol, + VirtualMachine, }; // Sequence Protocol @@ -84,10 +84,6 @@ impl<'a> PySequence<'a> { } impl PySequence<'_> { - pub fn obj_as(&self) -> &PyObjectView { - unsafe { self.obj.downcast_unchecked_ref::() } - } - // PySequence_Check pub fn check(&self, vm: &VirtualMachine) -> bool { self.methods(vm).item.is_some() diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index babd56c65..9c952211d 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -521,37 +521,36 @@ mod _collections { impl PyDeque { const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods { - length: Some(|seq, _vm| Ok(seq.obj_as::().len())), + length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())), concat: Some(|seq, other, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .concat(other, vm) .map(|x| x.into_ref(vm).into()) }), repeat: Some(|seq, n, vm| { - seq.obj_as::() + Self::sequence_downcast(seq) .mul(n as isize, vm) .map(|x| x.into_ref(vm).into()) }), - item: Some(|seq, i, vm| seq.obj_as::().getitem(i, vm)), + item: Some(|seq, i, vm| Self::sequence_downcast(seq).getitem(i, vm)), ass_item: Some(|seq, i, value, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); if let Some(value) = value { zelf.setitem(i, value, vm) } else { zelf.delitem(i, vm) } }), - contains: Some(|seq, needle, vm| seq.obj_as::()._contains(needle, vm)), + contains: Some(|seq, needle, vm| Self::sequence_downcast(seq)._contains(needle, vm)), inplace_concat: Some(|seq, other, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); zelf._extend(other, vm)?; Ok(zelf.to_owned().into()) }), inplace_repeat: Some(|seq, n, vm| { - let zelf = seq.obj_as::(); + let zelf = Self::sequence_downcast(seq); Self::imul(zelf.to_owned(), n as isize, vm).map(|x| x.into()) }), - ..*PySequenceMethods::not_implemented() }; } diff --git a/vm/src/types/slot.rs b/vm/src/types/slot.rs index d47374eea..00ca9b0ee 100644 --- a/vm/src/types/slot.rs +++ b/vm/src/types/slot.rs @@ -1,7 +1,7 @@ pub use crate::builtins::object::{generic_getattr, generic_setattr}; use crate::common::{hash::PyHash, lock::PyRwLock}; use crate::function::IntoPyObject; -use crate::protocol::PySequenceMethods; +use crate::protocol::{PySequence, PySequenceMethods}; use crate::{ builtins::{PyInt, PyStrRef, PyType, PyTypeRef}, function::{FromArgs, FuncArgs, IntoPyResult, OptionalArg}, @@ -843,10 +843,15 @@ pub trait AsSequence: PyValue { let zelf = unsafe { zelf.downcast_unchecked_ref::() }; Self::as_sequence(zelf, vm) } + fn as_sequence( zelf: &PyObjectView, vm: &VirtualMachine, ) -> Cow<'static, PySequenceMethods>; + + fn sequence_downcast<'a>(seq: &'a PySequence) -> &'a PyObjectView { + unsafe { seq.obj.downcast_unchecked_ref() } + } } #[pyimpl]