Skip to content

Commit 89566ee

Browse files
authored
Merge pull request RustPython#1543 from palaviv/use-primitives-directly
Use primitives directly
2 parents 2bfb08a + ea5381d commit 89566ee

File tree

14 files changed

+157
-317
lines changed

14 files changed

+157
-317
lines changed

vm/src/obj/objbytearray.rs

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22
use std::cell::{Cell, RefCell};
33
use std::convert::TryFrom;
44

5-
use num_traits::ToPrimitive;
6-
75
use super::objbyteinner::{
86
ByteInnerExpandtabsOptions, ByteInnerFindOptions, ByteInnerNewOptions, ByteInnerPaddingOptions,
97
ByteInnerPosition, ByteInnerSplitOptions, ByteInnerSplitlinesOptions,
@@ -172,14 +170,14 @@ impl PyByteArrayRef {
172170
}
173171

174172
#[pymethod(name = "__getitem__")]
175-
fn getitem(self, needle: Either<PyIntRef, PySliceRef>, vm: &VirtualMachine) -> PyResult {
173+
fn getitem(self, needle: Either<i32, PySliceRef>, vm: &VirtualMachine) -> PyResult {
176174
self.inner.borrow().getitem(needle, vm)
177175
}
178176

179177
#[pymethod(name = "__setitem__")]
180178
fn setitem(
181179
self,
182-
needle: Either<PyIntRef, PySliceRef>,
180+
needle: Either<i32, PySliceRef>,
183181
value: PyObjectRef,
184182
vm: &VirtualMachine,
185183
) -> PyResult {
@@ -506,18 +504,13 @@ impl PyByteArrayRef {
506504
}
507505

508506
#[pymethod(name = "insert")]
509-
fn insert(self, index: PyIntRef, x: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
507+
fn insert(self, mut index: isize, x: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
510508
let bytes = &mut self.inner.borrow_mut().elements;
511509
let len = isize::try_from(bytes.len())
512510
.map_err(|_e| vm.new_overflow_error("bytearray too big".to_string()))?;
513511

514512
let x = x.as_bigint().byte_or(vm)?;
515513

516-
let mut index = index
517-
.as_bigint()
518-
.to_isize()
519-
.ok_or_else(|| vm.new_overflow_error("index too big".to_string()))?;
520-
521514
if index >= len {
522515
bytes.push(x);
523516
return Ok(());
@@ -550,17 +543,17 @@ impl PyByteArrayRef {
550543
}
551544

552545
#[pymethod(name = "__mul__")]
553-
fn repeat(self, n: PyIntRef, vm: &VirtualMachine) -> PyResult {
546+
fn repeat(self, n: isize, vm: &VirtualMachine) -> PyResult {
554547
Ok(vm.ctx.new_bytearray(self.inner.borrow().repeat(n, vm)?))
555548
}
556549

557550
#[pymethod(name = "__rmul__")]
558-
fn rmul(self, n: PyIntRef, vm: &VirtualMachine) -> PyResult {
551+
fn rmul(self, n: isize, vm: &VirtualMachine) -> PyResult {
559552
self.repeat(n, vm)
560553
}
561554

562555
#[pymethod(name = "__imul__")]
563-
fn irepeat(self, n: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
556+
fn irepeat(self, n: isize, vm: &VirtualMachine) -> PyResult<()> {
564557
self.inner.borrow_mut().irepeat(n, vm)
565558
}
566559

vm/src/obj/objbyteinner.rs

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ use super::objstr::{PyString, PyStringRef};
1717
use super::objtuple::PyTupleRef;
1818
use crate::function::OptionalArg;
1919
use crate::pyhash;
20-
use crate::pyobject::{
21-
Either, PyIterable, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol,
22-
};
20+
use crate::pyobject::{Either, PyIterable, PyObjectRef, PyResult, TryFromObject, TypeProtocol};
2321
use crate::vm::VirtualMachine;
2422

2523
#[derive(Debug, Default, Clone)]
@@ -48,22 +46,6 @@ impl TryFromObject for PyByteInner {
4846
}
4947
}
5048

51-
impl<B: PyValue> TryFromObject for Either<PyByteInner, PyRef<B>> {
52-
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
53-
match PyByteInner::try_from_object(vm, obj.clone()) {
54-
Ok(a) => Ok(Either::A(a)),
55-
Err(_) => match obj.clone().downcast::<B>() {
56-
Ok(b) => Ok(Either::B(b)),
57-
Err(_) => Err(vm.new_type_error(format!(
58-
"a bytes-like object or {} is required, not {}",
59-
B::class(vm),
60-
obj.class()
61-
))),
62-
},
63-
}
64-
}
65-
}
66-
6749
#[derive(FromArgs)]
6850
pub struct ByteInnerNewOptions {
6951
#[pyarg(positional_only, optional = true)]
@@ -274,7 +256,7 @@ pub struct ByteInnerSplitOptions {
274256
#[pyarg(positional_or_keyword, optional = true)]
275257
sep: OptionalArg<Option<PyByteInner>>,
276258
#[pyarg(positional_or_keyword, optional = true)]
277-
maxsplit: OptionalArg<PyIntRef>,
259+
maxsplit: OptionalArg<i32>,
278260
}
279261

280262
impl ByteInnerSplitOptions {
@@ -285,7 +267,7 @@ impl ByteInnerSplitOptions {
285267
};
286268

287269
let maxsplit = if let OptionalArg::Present(value) = self.maxsplit {
288-
value.as_bigint().to_i32().unwrap()
270+
value
289271
} else {
290272
-1
291273
};
@@ -442,10 +424,10 @@ impl PyByteInner {
442424
}
443425
}
444426

445-
pub fn getitem(&self, needle: Either<PyIntRef, PySliceRef>, vm: &VirtualMachine) -> PyResult {
427+
pub fn getitem(&self, needle: Either<i32, PySliceRef>, vm: &VirtualMachine) -> PyResult {
446428
match needle {
447429
Either::A(int) => {
448-
if let Some(idx) = self.elements.get_pos(int.as_bigint().to_i32().unwrap()) {
430+
if let Some(idx) = self.elements.get_pos(int) {
449431
Ok(vm.new_int(self.elements[idx]))
450432
} else {
451433
Err(vm.new_index_error("index out of range".to_string()))
@@ -457,8 +439,8 @@ impl PyByteInner {
457439
}
458440
}
459441

460-
fn setindex(&mut self, int: PyIntRef, object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
461-
if let Some(idx) = self.elements.get_pos(int.as_bigint().to_i32().unwrap()) {
442+
fn setindex(&mut self, int: i32, object: PyObjectRef, vm: &VirtualMachine) -> PyResult {
443+
if let Some(idx) = self.elements.get_pos(int) {
462444
let result = match_class!(match object {
463445
i @ PyInt => {
464446
if let Some(value) = i.as_bigint().to_u8() {
@@ -511,7 +493,7 @@ impl PyByteInner {
511493

512494
pub fn setitem(
513495
&mut self,
514-
needle: Either<PyIntRef, PySliceRef>,
496+
needle: Either<i32, PySliceRef>,
515497
object: PyObjectRef,
516498
vm: &VirtualMachine,
517499
) -> PyResult {
@@ -1073,16 +1055,12 @@ impl PyByteInner {
10731055
res
10741056
}
10751057

1076-
pub fn repeat(&self, n: PyIntRef, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
1058+
pub fn repeat(&self, n: isize, _vm: &VirtualMachine) -> PyResult<Vec<u8>> {
10771059
if self.elements.is_empty() {
10781060
// We can multiple an empty vector by any integer, even if it doesn't fit in an isize.
10791061
return Ok(vec![]);
10801062
}
10811063

1082-
let n = n.as_bigint().to_isize().ok_or_else(|| {
1083-
vm.new_overflow_error("can't multiply bytes that many times".to_string())
1084-
})?;
1085-
10861064
if n <= 0 {
10871065
Ok(vec![])
10881066
} else {
@@ -1097,16 +1075,12 @@ impl PyByteInner {
10971075
}
10981076
}
10991077

1100-
pub fn irepeat(&mut self, n: PyIntRef, vm: &VirtualMachine) -> PyResult<()> {
1078+
pub fn irepeat(&mut self, n: isize, _vm: &VirtualMachine) -> PyResult<()> {
11011079
if self.elements.is_empty() {
11021080
// We can multiple an empty vector by any integer, even if it doesn't fit in an isize.
11031081
return Ok(());
11041082
}
11051083

1106-
let n = n.as_bigint().to_isize().ok_or_else(|| {
1107-
vm.new_overflow_error("can't multiply bytes that many times".to_string())
1108-
})?;
1109-
11101084
if n <= 0 {
11111085
self.elements.clear();
11121086
} else {

vm/src/obj/objbytes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ impl PyBytesRef {
168168
}
169169

170170
#[pymethod(name = "__getitem__")]
171-
fn getitem(self, needle: Either<PyIntRef, PySliceRef>, vm: &VirtualMachine) -> PyResult {
171+
fn getitem(self, needle: Either<i32, PySliceRef>, vm: &VirtualMachine) -> PyResult {
172172
self.inner.getitem(needle, vm)
173173
}
174174

@@ -421,12 +421,12 @@ impl PyBytesRef {
421421
}
422422

423423
#[pymethod(name = "__mul__")]
424-
fn repeat(self, n: PyIntRef, vm: &VirtualMachine) -> PyResult {
424+
fn repeat(self, n: isize, vm: &VirtualMachine) -> PyResult {
425425
Ok(vm.ctx.new_bytes(self.inner.repeat(n, vm)?))
426426
}
427427

428428
#[pymethod(name = "__rmul__")]
429-
fn rmul(self, n: PyIntRef, vm: &VirtualMachine) -> PyResult {
429+
fn rmul(self, n: isize, vm: &VirtualMachine) -> PyResult {
430430
self.repeat(n, vm)
431431
}
432432

vm/src/obj/objfloat.rs

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ use num_rational::Ratio;
44
use num_traits::{float::Float, pow, sign::Signed, ToPrimitive, Zero};
55

66
use super::objbytes;
7-
use super::objint;
7+
use super::objint::{self, PyIntRef};
88
use super::objstr::{self, PyStringRef};
99
use super::objtype::{self, PyClassRef};
10-
use crate::function::OptionalArg;
10+
use crate::function::{OptionalArg, OptionalOption};
1111
use crate::pyhash;
1212
use crate::pyobject::{
13-
IdProtocol, IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue,
14-
TryFromObject, TypeProtocol,
13+
IntoPyObject, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject,
14+
TypeProtocol,
1515
};
1616
use crate::vm::VirtualMachine;
1717

@@ -458,26 +458,10 @@ impl PyFloat {
458458
}
459459

460460
#[pymethod(name = "__round__")]
461-
fn round(&self, ndigits: OptionalArg<PyObjectRef>, vm: &VirtualMachine) -> PyResult {
462-
let ndigits = match ndigits {
463-
OptionalArg::Missing => None,
464-
OptionalArg::Present(ref value) => {
465-
if !vm.get_none().is(value) {
466-
if !objtype::isinstance(value, &vm.ctx.int_type()) {
467-
return Err(vm.new_type_error(format!(
468-
"'{}' object cannot be interpreted as an integer",
469-
value.class().name
470-
)));
471-
};
472-
// Only accept int type ndigits
473-
let ndigits = objint::get_value(value);
474-
Some(ndigits)
475-
} else {
476-
None
477-
}
478-
}
479-
};
461+
fn round(&self, ndigits: OptionalOption<PyIntRef>, vm: &VirtualMachine) -> PyResult {
462+
let ndigits = ndigits.flat_option();
480463
if let Some(ndigits) = ndigits {
464+
let ndigits = ndigits.as_bigint();
481465
if ndigits.is_zero() {
482466
let fract = self.value.fract();
483467
let value = if (fract.abs() - 0.5).abs() < std::f64::EPSILON {

vm/src/obj/objstr.rs

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@ use unicode_xid::UnicodeXID;
1717
use super::objbytes::PyBytes;
1818
use super::objdict::PyDict;
1919
use super::objfloat;
20-
use super::objint::{self, PyInt};
20+
use super::objint::{self, PyInt, PyIntRef};
2121
use super::objiter;
2222
use super::objnone::PyNone;
2323
use super::objsequence::PySliceableSequence;
24-
use super::objslice::PySlice;
24+
use super::objslice::PySliceRef;
2525
use super::objtuple;
2626
use super::objtype::{self, PyClassRef};
2727
use crate::cformat::{
@@ -32,8 +32,8 @@ use crate::format::{FormatParseError, FormatPart, FormatPreconversor, FormatStri
3232
use crate::function::{single_or_tuple_any, OptionalArg, PyFuncArgs};
3333
use crate::pyhash;
3434
use crate::pyobject::{
35-
IdProtocol, IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyIterable, PyObjectRef, PyRef,
36-
PyResult, PyValue, TryFromObject, TryIntoRef, TypeProtocol,
35+
Either, IdProtocol, IntoPyObject, ItemProtocol, PyClassImpl, PyContext, PyIterable,
36+
PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TryIntoRef, TypeProtocol,
3737
};
3838
use crate::vm::VirtualMachine;
3939

@@ -229,8 +229,34 @@ impl PyString {
229229
}
230230

231231
#[pymethod(name = "__getitem__")]
232-
fn getitem(&self, needle: PyObjectRef, vm: &VirtualMachine) -> PyResult {
233-
subscript(vm, &self.value, needle)
232+
fn getitem(&self, needle: Either<PyIntRef, PySliceRef>, vm: &VirtualMachine) -> PyResult {
233+
match needle {
234+
Either::A(pos) => match pos.as_bigint().to_isize() {
235+
Some(pos) => {
236+
let index: usize = if pos.is_negative() {
237+
(self.value.chars().count() as isize + pos) as usize
238+
} else {
239+
pos.abs() as usize
240+
};
241+
242+
if let Some(character) = self.value.chars().nth(index) {
243+
Ok(vm.new_str(character.to_string()))
244+
} else {
245+
Err(vm.new_index_error("string index out of range".to_string()))
246+
}
247+
}
248+
None => Err(
249+
vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string())
250+
),
251+
},
252+
Either::B(slice) => {
253+
let string = self
254+
.value
255+
.to_string()
256+
.get_slice_items(vm, slice.as_object())?;
257+
Ok(vm.new_str(string))
258+
}
259+
}
234260
}
235261

236262
#[pymethod(name = "__gt__")]
@@ -292,22 +318,18 @@ impl PyString {
292318
}
293319

294320
#[pymethod(name = "__mul__")]
295-
fn mul(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
296-
if !objtype::isinstance(&val, &vm.ctx.int_type()) {
297-
return Err(vm.new_type_error(format!("Cannot multiply {} and {}", self, val)));
298-
}
299-
objint::get_value(&val)
300-
.to_isize()
301-
.map(|multiplier| multiplier.max(0))
302-
.and_then(|multiplier| multiplier.to_usize())
321+
fn mul(&self, multiplier: isize, vm: &VirtualMachine) -> PyResult<String> {
322+
multiplier
323+
.max(0)
324+
.to_usize()
303325
.map(|multiplier| self.value.repeat(multiplier))
304326
.ok_or_else(|| {
305327
vm.new_overflow_error("cannot fit 'int' into an index-sized integer".to_string())
306328
})
307329
}
308330

309331
#[pymethod(name = "__rmul__")]
310-
fn rmul(&self, val: PyObjectRef, vm: &VirtualMachine) -> PyResult<String> {
332+
fn rmul(&self, val: isize, vm: &VirtualMachine) -> PyResult<String> {
311333
self.mul(val, vm)
312334
}
313335

@@ -1575,37 +1597,6 @@ impl PySliceableSequence for String {
15751597
}
15761598
}
15771599

1578-
pub fn subscript(vm: &VirtualMachine, value: &str, b: PyObjectRef) -> PyResult {
1579-
if objtype::isinstance(&b, &vm.ctx.int_type()) {
1580-
match objint::get_value(&b).to_isize() {
1581-
Some(pos) => {
1582-
let index: usize = if pos.is_negative() {
1583-
(value.chars().count() as isize + pos) as usize
1584-
} else {
1585-
pos.abs() as usize
1586-
};
1587-
1588-
if let Some(character) = value.chars().nth(index) {
1589-
Ok(vm.new_str(character.to_string()))
1590-
} else {
1591-
Err(vm.new_index_error("string index out of range".to_string()))
1592-
}
1593-
}
1594-
None => {
1595-
Err(vm.new_index_error("cannot fit 'int' into an index-sized integer".to_string()))
1596-
}
1597-
}
1598-
} else if b.payload::<PySlice>().is_some() {
1599-
let string = value.to_string().get_slice_items(vm, &b)?;
1600-
Ok(vm.new_str(string))
1601-
} else {
1602-
Err(vm.new_type_error(format!(
1603-
"indexing type {:?} with index {:?} is not supported",
1604-
value, b
1605-
)))
1606-
}
1607-
}
1608-
16091600
// help get optional string indices
16101601
fn adjust_indices(
16111602
start: OptionalArg<isize>,

0 commit comments

Comments
 (0)