move obj_as to sequence_downcast

This commit is contained in:
Kangzhi Shi
2021-12-05 10:24:28 +02:00
committed by Jeong YunWon
parent 994c0be479
commit 0abe90dd0a
13 changed files with 103 additions and 95 deletions

View File

@@ -765,21 +765,21 @@ impl AsSequence for PyByteArray {
impl PyByteArray {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
seq.obj_as::<Self>()
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>()
Self::sequence_downcast(seq)
.mul(n as isize, vm)
.map(|x| x.into_object(vm))
}),
item: Some(|seq, i, vm| seq.obj_as::<Self>().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::<Self>();
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 = <Either<PyBytesInner, PyIntRef>>::try_from_object(vm, other.to_owned())?;
seq.obj_as::<Self>().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::<Self>().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::<Self>().to_owned();
let zelf = Self::sequence_downcast(seq).to_owned();
Self::imul(zelf, n as isize, vm).map(|x| x.into())
}),
};

View File

@@ -580,18 +580,23 @@ impl AsSequence for PyBytes {
impl PyBytes {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
seq.obj_as::<Self>()
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::<Self>().repeat(n)).into())),
item: Some(|seq, i, vm| seq.obj_as::<Self>().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 = <Either<PyBytesInner, PyIntRef>>::try_from_object(vm, other.to_owned())?;
seq.obj_as::<Self>().contains(other, vm)
Self::sequence_downcast(seq).contains(other, vm)
}),
..*PySequenceMethods::not_implemented()
};

View File

@@ -465,7 +465,7 @@ impl AsSequence for PyDict {
impl PyDict {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
contains: Some(|seq, target, vm| seq.obj_as::<Self>().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::<Self>().len())),
contains: Some(|seq, target, vm| seq.obj_as::<Self>().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::<Self>().len())),
contains: Some(|seq, target, vm| seq.obj_as::<Self>().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::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
..*PySequenceMethods::not_implemented()
};
}

View File

@@ -404,20 +404,24 @@ impl AsSequence for PyList {
}
impl PyList {
const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
seq.obj_as::<Self>()
Self::sequence_downcast(seq)
.concat(other, vm)
.map(|x| x.into_object())
}),
repeat: Some(|seq, n, vm| {
seq.obj_as::<Self>()
Self::sequence_downcast(seq)
.mul(n as isize, vm)
.map(|x| x.into_object())
}),
item: Some(|seq, i, vm| seq.obj_as::<Self>().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::<Self>();
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::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf.mut_contains(vm, target)
}),
inplace_concat: Some(|seq, other, vm| {
let zelf = seq.obj_as::<Self>();
let zelf = Self::sequence_downcast(seq);
Ok(Self::inplace_concat(zelf, other, vm))
}),
inplace_repeat: Some(|seq, n, vm| {
let zelf = seq.obj_as::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf.borrow_vec_mut().imul(vm, n as isize)?;
Ok(zelf.to_owned().into_object())
}),
..*PySequenceMethods::not_implemented()
};
}

View File

@@ -189,7 +189,7 @@ impl AsSequence for PyMappingProxy {
impl PyMappingProxy {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
contains: Some(|seq, target, vm| seq.obj_as::<Self>()._contains(target, vm)),
contains: Some(|seq, target, vm| Self::sequence_downcast(seq)._contains(target, vm)),
..*PySequenceMethods::not_implemented()
};
}

View File

@@ -991,12 +991,12 @@ impl AsSequence for PyMemoryView {
impl PyMemoryView {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, vm| {
let zelf = seq.obj_as::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf.try_not_released(vm)?;
zelf.len(vm)
}),
item: Some(|seq, i, vm| {
let zelf = seq.obj_as::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf.try_not_released(vm)?;
zelf.getitem_by_idx(i, vm)
}),

View File

@@ -1298,21 +1298,21 @@ impl AsSequence for PyStr {
impl PyStr {
const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
let zelf = seq.obj_as::<Self>();
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::<Self>();
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::<Self>();
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::<Self>()._contains(needle, vm)),
contains: Some(|seq, needle, vm| Self::sequence_downcast(seq)._contains(needle, vm)),
..*PySequenceMethods::not_implemented()
};
}

View File

@@ -379,22 +379,36 @@ impl PyRange {
}
impl PyRange {
fn protocol_length(&self, vm: &VirtualMachine) -> PyResult<usize> {
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::<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)
}),
item: Some(|seq, i, vm| {
seq.obj_as::<Self>()
.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::<Self>().contains(needle.to_owned(), vm))),
..*PySequenceMethods::not_implemented()
};
}
impl Hashable for PyRange {
fn hash(zelf: &crate::PyObjectView<Self>, vm: &VirtualMachine) -> PyResult<PyHash> {
let length = zelf.compute_length();

View File

@@ -665,8 +665,8 @@ impl AsSequence for PySet {
impl PySet {
const SEQUENCE_METHODS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
contains: Some(|seq, needle, vm| seq.obj_as::<Self>().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::<Self>().len())),
contains: Some(|seq, needle, vm| seq.obj_as::<Self>().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()
};
}

View File

@@ -340,9 +340,9 @@ impl AsSequence for PyTuple {
impl PyTuple {
const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
let zelf = seq.obj_as::<Self>();
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::<Self>();
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::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf.elements.get_item_by_index(vm, i)
}),
contains: Some(|seq, needle, vm| {
let zelf = seq.obj_as::<Self>();
let zelf = Self::sequence_downcast(seq);
zelf._contains(needle, vm)
}),
..*PySequenceMethods::not_implemented()

View File

@@ -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<T: PyObjectPayload>(&self) -> &PyObjectView<T> {
unsafe { self.obj.downcast_unchecked_ref::<T>() }
}
// PySequence_Check
pub fn check(&self, vm: &VirtualMachine) -> bool {
self.methods(vm).item.is_some()

View File

@@ -521,37 +521,36 @@ mod _collections {
impl PyDeque {
const SEQUENCE_METHDOS: PySequenceMethods = PySequenceMethods {
length: Some(|seq, _vm| Ok(seq.obj_as::<Self>().len())),
length: Some(|seq, _vm| Ok(Self::sequence_downcast(seq).len())),
concat: Some(|seq, other, vm| {
seq.obj_as::<Self>()
Self::sequence_downcast(seq)
.concat(other, vm)
.map(|x| x.into_ref(vm).into())
}),
repeat: Some(|seq, n, vm| {
seq.obj_as::<Self>()
Self::sequence_downcast(seq)
.mul(n as isize, vm)
.map(|x| x.into_ref(vm).into())
}),
item: Some(|seq, i, vm| seq.obj_as::<Self>().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::<Self>();
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::<Self>()._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::<Self>();
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::<Self>();
let zelf = Self::sequence_downcast(seq);
Self::imul(zelf.to_owned(), n as isize, vm).map(|x| x.into())
}),
..*PySequenceMethods::not_implemented()
};
}

View File

@@ -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>() };
Self::as_sequence(zelf, vm)
}
fn as_sequence(
zelf: &PyObjectView<Self>,
vm: &VirtualMachine,
) -> Cow<'static, PySequenceMethods>;
fn sequence_downcast<'a>(seq: &'a PySequence) -> &'a PyObjectView<Self> {
unsafe { seq.obj.downcast_unchecked_ref() }
}
}
#[pyimpl]