From b677b88bddefe6a31e076150b441ccd2cc7675a4 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Tue, 21 Jul 2020 04:40:04 +0900 Subject: [PATCH] sequence::cmp take DynPyIter instead of SimpleSeq to avoid duplicated code generation for Box operation --- vm/src/obj/objlist.rs | 6 ++-- vm/src/obj/objtuple.rs | 13 +++++--- vm/src/sequence.rs | 60 +++++++++++++----------------------- vm/src/stdlib/collections.rs | 10 +++--- 4 files changed, 37 insertions(+), 52 deletions(-) diff --git a/vm/src/obj/objlist.rs b/vm/src/obj/objlist.rs index dc66341eb..70139ab45 100644 --- a/vm/src/obj/objlist.rs +++ b/vm/src/obj/objlist.rs @@ -530,12 +530,12 @@ impl PyList { #[inline] fn cmp(&self, other: PyObjectRef, op: F, vm: &VirtualMachine) -> PyResult where - F: Fn(&Vec, &Vec) -> PyResult, + F: Fn(sequence::DynPyIter, sequence::DynPyIter) -> PyResult, { let r = if let Some(other) = other.payload_if_subclass::(vm) { Implemented(op( - &self.borrow_elements().clone(), - &other.borrow_elements().clone(), + self.borrow_elements().boxed_iter(), + other.borrow_elements().boxed_iter(), )?) } else { NotImplemented diff --git a/vm/src/obj/objtuple.rs b/vm/src/obj/objtuple.rs index 1b3099473..43570b386 100644 --- a/vm/src/obj/objtuple.rs +++ b/vm/src/obj/objtuple.rs @@ -11,7 +11,7 @@ use crate::pyobject::{ PyArithmaticValue::{self, *}, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, }; -use crate::sequence; +use crate::sequence::{self, SimpleSeq}; use crate::vm::{ReprGuard, VirtualMachine}; /// tuple() -> empty tuple @@ -81,10 +81,13 @@ impl PyTuple { #[inline] fn cmp(&self, other: PyObjectRef, op: F, vm: &VirtualMachine) -> PyResult where - F: Fn(&Vec, &Vec) -> PyResult, + F: Fn(sequence::DynPyIter, sequence::DynPyIter) -> PyResult, { let r = if let Some(other) = other.payload_if_subclass::(vm) { - Implemented(op(&self.elements, &other.elements)?) + Implemented(op( + self.as_slice().boxed_iter(), + other.as_slice().boxed_iter(), + )?) } else { NotImplemented }; @@ -116,8 +119,8 @@ impl PyTuple { if let Some(other) = other.payload_if_subclass::(vm) { let elements: Vec<_> = self .elements - .iter() - .chain(other.as_slice().iter()) + .boxed_iter() + .chain(other.as_slice().boxed_iter()) .cloned() .collect(); Implemented(elements.into()) diff --git a/vm/src/sequence.rs b/vm/src/sequence.rs index 394e47992..557569218 100644 --- a/vm/src/sequence.rs +++ b/vm/src/sequence.rs @@ -7,7 +7,7 @@ pub(super) type DynPyIter<'a> = Box usize; - fn iter(&self) -> DynPyIter; + fn boxed_iter(&self) -> DynPyIter; } impl<'a, D> SimpleSeq for D @@ -18,18 +18,14 @@ where self.deref().len() } - fn iter(&self) -> DynPyIter { + fn boxed_iter(&self) -> DynPyIter { Box::new(self.deref().iter()) } } -pub(crate) fn eq( - vm: &VirtualMachine, - zelf: &impl SimpleSeq, - other: &impl SimpleSeq, -) -> PyResult { +pub(crate) fn eq(vm: &VirtualMachine, zelf: DynPyIter, other: DynPyIter) -> PyResult { if zelf.len() == other.len() { - for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { + for (a, b) in Iterator::zip(zelf, other) { if a.is(b) { continue; } @@ -43,58 +39,44 @@ pub(crate) fn eq( } } -pub(crate) fn lt( - vm: &VirtualMachine, - zelf: &impl SimpleSeq, - other: &impl SimpleSeq, -) -> PyResult { - for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { +pub(crate) fn lt(vm: &VirtualMachine, zelf: DynPyIter, other: DynPyIter) -> PyResult { + let fallback = zelf.len() < other.len(); + for (a, b) in Iterator::zip(zelf, other) { if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? { return Ok(v); } } - Ok(zelf.len() < other.len()) + Ok(fallback) } -pub(crate) fn gt( - vm: &VirtualMachine, - zelf: &impl SimpleSeq, - other: &impl SimpleSeq, -) -> PyResult { - for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { +pub(crate) fn gt(vm: &VirtualMachine, zelf: DynPyIter, other: DynPyIter) -> PyResult { + let fallback = zelf.len() > other.len(); + for (a, b) in Iterator::zip(zelf, other) { if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? { return Ok(v); } } - Ok(zelf.len() > other.len()) + Ok(fallback) } -pub(crate) fn ge( - vm: &VirtualMachine, - zelf: &impl SimpleSeq, - other: &impl SimpleSeq, -) -> PyResult { - for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { +pub(crate) fn ge(vm: &VirtualMachine, zelf: DynPyIter, other: DynPyIter) -> PyResult { + let fallback = zelf.len() >= other.len(); + for (a, b) in Iterator::zip(zelf, other) { if let Some(v) = vm.bool_seq_gt(a.clone(), b.clone())? { return Ok(v); } } - - Ok(zelf.len() >= other.len()) + Ok(fallback) } -pub(crate) fn le( - vm: &VirtualMachine, - zelf: &impl SimpleSeq, - other: &impl SimpleSeq, -) -> PyResult { - for (a, b) in Iterator::zip(zelf.iter(), other.iter()) { +pub(crate) fn le(vm: &VirtualMachine, zelf: DynPyIter, other: DynPyIter) -> PyResult { + let fallback = zelf.len() <= other.len(); + for (a, b) in Iterator::zip(zelf, other) { if let Some(v) = vm.bool_seq_lt(a.clone(), b.clone())? { return Ok(v); } } - - Ok(zelf.len() <= other.len()) + Ok(fallback) } pub(crate) struct SeqMul<'a> { @@ -115,7 +97,7 @@ impl<'a> Iterator for SeqMul<'a> { None } else { self.repetitions -= 1; - self.iter = Some(self.seq.iter()); + self.iter = Some(self.seq.boxed_iter()); self.next() } } diff --git a/vm/src/stdlib/collections.rs b/vm/src/stdlib/collections.rs index 90bd579c5..a959970b8 100644 --- a/vm/src/stdlib/collections.rs +++ b/vm/src/stdlib/collections.rs @@ -8,7 +8,7 @@ mod _collections { IdProtocol, PyArithmaticValue::*, PyClassImpl, PyComparisonValue, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, }; - use crate::sequence; + use crate::sequence::{self, SimpleSeq}; use crate::vm::ReprGuard; use crate::VirtualMachine; use itertools::Itertools; @@ -54,7 +54,7 @@ mod _collections { self.0.len() } - fn iter(&self) -> sequence::DynPyIter { + fn boxed_iter(&self) -> sequence::DynPyIter { Box::new(self.0.iter()) } } @@ -285,12 +285,12 @@ mod _collections { vm: &VirtualMachine, ) -> PyResult where - F: Fn(&SimpleSeqDeque, &SimpleSeqDeque) -> PyResult, + F: Fn(sequence::DynPyIter, sequence::DynPyIter) -> PyResult, { let r = if let Some(other) = other.payload_if_subclass::(vm) { Implemented(op( - &self.borrow_deque().into(), - &other.borrow_deque().into(), + SimpleSeqDeque::from(self.borrow_deque()).boxed_iter(), + SimpleSeqDeque::from(other.borrow_deque()).boxed_iter(), )?) } else { NotImplemented