Skip to content

Commit 5befe49

Browse files
committed
PyMemoryView::getitem_slice reuse common convert_slice
1 parent 6a309cb commit 5befe49

File tree

1 file changed

+18
-46
lines changed

1 file changed

+18
-46
lines changed

vm/src/builtins/memory.rs

Lines changed: 18 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::common::{
99
rc::PyRc,
1010
};
1111
use crate::function::{FuncArgs, OptionalArg};
12-
use crate::sliceable::{convert_slice, saturate_range, wrap_index, SequenceIndex};
12+
use crate::sliceable::{convert_slice, wrap_index, SequenceIndex};
1313
use crate::slots::{AsBuffer, Comparable, Hashable, PyComparisonOp, SlotConstructor};
1414
use crate::stdlib::pystruct::_struct::FormatSpec;
1515
use crate::utils::Either;
@@ -19,8 +19,7 @@ use crate::{
1919
};
2020
use crossbeam_utils::atomic::AtomicCell;
2121
use itertools::Itertools;
22-
use num_bigint::BigInt;
23-
use num_traits::{One, Signed, ToPrimitive, Zero};
22+
use num_traits::ToPrimitive;
2423
use std::fmt::Debug;
2524
use std::ops::Deref;
2625

@@ -255,25 +254,20 @@ impl PyMemoryView {
255254

256255
fn getitem_by_slice(zelf: PyRef<Self>, slice: PySliceRef, vm: &VirtualMachine) -> PyResult {
257256
// slicing a memoryview return a new memoryview
258-
let start = slice.start_index(vm)?;
259-
let stop = slice.stop_index(vm)?;
260-
let step = slice.step_index(vm)?.unwrap_or_else(BigInt::one);
261-
if step.is_zero() {
262-
return Err(vm.new_value_error("slice step cannot be zero".to_owned()));
263-
}
264-
let newstep: BigInt = step.clone() * zelf.step;
265257
let len = zelf.buffer.options.len;
258+
let (range, step, is_negative_step) = convert_slice(&slice, len, vm)?;
259+
let abs_step = step.unwrap();
260+
let step = if is_negative_step {
261+
-(abs_step as isize)
262+
} else {
263+
abs_step as isize
264+
};
265+
let newstep = step * zelf.step;
266266
let itemsize = zelf.buffer.options.itemsize;
267267

268268
let format_spec = zelf.format_spec.clone();
269269

270-
if newstep == BigInt::one() {
271-
let range = saturate_range(&start, &stop, len);
272-
let range = if range.end < range.start {
273-
range.start..range.start
274-
} else {
275-
range
276-
};
270+
if newstep == 1 {
277271
let newlen = range.end - range.start;
278272
let start = zelf.start + range.start * itemsize;
279273
let stop = zelf.start + range.end * itemsize;
@@ -294,35 +288,7 @@ impl PyMemoryView {
294288
.into_object(vm));
295289
}
296290

297-
let (start, stop) = if step.is_negative() {
298-
(
299-
stop.map(|x| {
300-
if x == -BigInt::one() {
301-
len + BigInt::one()
302-
} else {
303-
x + 1
304-
}
305-
}),
306-
start.map(|x| {
307-
if x == -BigInt::one() {
308-
BigInt::from(len)
309-
} else {
310-
x + 1
311-
}
312-
}),
313-
)
314-
} else {
315-
(start, stop)
316-
};
317-
318-
let range = saturate_range(&start, &stop, len);
319-
let newlen = if range.end > range.start {
320-
// overflow is not possible as dividing a positive integer
321-
((range.end - range.start - 1) / step.abs())
322-
.to_usize()
323-
.unwrap()
324-
+ 1
325-
} else {
291+
if range.start >= range.end {
326292
return Ok(PyMemoryView {
327293
buffer: zelf.buffer.clone_with_options(BufferOptions {
328294
len: 0,
@@ -340,6 +306,12 @@ impl PyMemoryView {
340306
.into_object(vm));
341307
};
342308

309+
// overflow is not possible as dividing a positive integer
310+
let newlen = ((range.end - range.start - 1) / abs_step)
311+
.to_usize()
312+
.unwrap()
313+
+ 1;
314+
343315
// newlen will be 0 if step is overflowed
344316
let newstep = newstep.to_isize().unwrap_or(-1);
345317

0 commit comments

Comments
 (0)