Skip to content

Commit eee6e78

Browse files
committed
PyRef::into_exact_or
1 parent aad9015 commit eee6e78

File tree

2 files changed

+42
-30
lines changed

2 files changed

+42
-30
lines changed

vm/src/builtins/int.rs

+27-30
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
},
1616
protocol::{PyNumber, PyNumberMethods},
1717
types::{AsNumber, Comparable, Constructor, Hashable, PyComparisonOp, Representable},
18-
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyResult,
18+
AsObject, Context, Py, PyObject, PyObjectRef, PyPayload, PyRef, PyRefExact, PyResult,
1919
TryFromBorrowedObject, VirtualMachine,
2020
};
2121
use num_bigint::{BigInt, Sign};
@@ -321,7 +321,7 @@ impl PyInt {
321321

322322
#[pyclass(
323323
flags(BASETYPE),
324-
with(Comparable, Hashable, Constructor, AsNumber, Representable)
324+
with(PyRef, Comparable, Hashable, Constructor, AsNumber, Representable)
325325
)]
326326
impl PyInt {
327327
#[pymethod(name = "__radd__")]
@@ -521,11 +521,6 @@ impl PyInt {
521521
Ok(zelf)
522522
}
523523

524-
#[pymethod(magic)]
525-
fn int(zelf: PyRef<Self>) -> PyRef<Self> {
526-
zelf
527-
}
528-
529524
#[pymethod(magic)]
530525
fn pos(&self) -> BigInt {
531526
self.value.clone()
@@ -537,23 +532,23 @@ impl PyInt {
537532
}
538533

539534
#[pymethod(magic)]
540-
fn trunc(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
541-
Self::clone_if_subclass(zelf, vm)
535+
fn trunc(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
536+
zelf.int(vm)
542537
}
543538

544539
#[pymethod(magic)]
545-
fn floor(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
546-
Self::clone_if_subclass(zelf, vm)
540+
fn floor(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
541+
zelf.int(vm)
547542
}
548543

549544
#[pymethod(magic)]
550-
fn ceil(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
551-
Self::clone_if_subclass(zelf, vm)
545+
fn ceil(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
546+
zelf.int(vm)
552547
}
553548

554549
#[pymethod(magic)]
555-
fn index(zelf: PyRef<Self>) -> PyRef<Self> {
556-
zelf
550+
fn index(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
551+
zelf.int(vm)
557552
}
558553

559554
#[pymethod(magic)]
@@ -589,8 +584,8 @@ impl PyInt {
589584
}
590585

591586
#[pymethod]
592-
fn conjugate(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
593-
Self::clone_if_subclass(zelf, vm)
587+
fn conjugate(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
588+
zelf.int(vm)
594589
}
595590

596591
#[pyclassmethod]
@@ -659,18 +654,9 @@ impl PyInt {
659654
Ok(bytes.into())
660655
}
661656

662-
#[inline]
663-
fn clone_if_subclass(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
664-
if zelf.class().is(vm.ctx.types.int_type) {
665-
return zelf;
666-
}
667-
668-
vm.ctx.new_bigint(&zelf.value)
669-
}
670-
671657
#[pygetset]
672-
fn real(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
673-
Self::clone_if_subclass(zelf, vm)
658+
fn real(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
659+
zelf.int(vm)
674660
}
675661

676662
#[pygetset]
@@ -679,8 +665,8 @@ impl PyInt {
679665
}
680666

681667
#[pygetset]
682-
fn numerator(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRef<Self> {
683-
Self::clone_if_subclass(zelf, vm)
668+
fn numerator(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyRefExact<Self> {
669+
zelf.int(vm)
684670
}
685671

686672
#[pygetset]
@@ -701,6 +687,17 @@ impl PyInt {
701687
}
702688
}
703689

690+
#[pyclass]
691+
impl PyRef<PyInt> {
692+
#[pymethod(magic)]
693+
fn int(self, vm: &VirtualMachine) -> PyRefExact<PyInt> {
694+
self.into_exact_or(&vm.ctx, |zelf| unsafe {
695+
// TODO: this is actually safe. we need better interface
696+
PyRefExact::new_unchecked(vm.ctx.new_bigint(&zelf.value))
697+
})
698+
}
699+
}
700+
704701
impl Comparable for PyInt {
705702
fn cmp(
706703
zelf: &Py<Self>,

vm/src/object/ext.rs

+15
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::common::{
99
use crate::{
1010
builtins::{PyBaseExceptionRef, PyStrInterned, PyType},
1111
convert::{IntoPyException, ToPyObject, ToPyResult, TryFromObject},
12+
vm::Context,
1213
VirtualMachine,
1314
};
1415
use std::{borrow::Borrow, fmt, marker::PhantomData, ops::Deref, ptr::null_mut};
@@ -107,6 +108,20 @@ impl<T: PyPayload> std::borrow::ToOwned for PyExact<T> {
107108
}
108109
}
109110

111+
impl<T: PyPayload> PyRef<T> {
112+
pub fn into_exact_or(
113+
self,
114+
ctx: &Context,
115+
f: impl FnOnce(Self) -> PyRefExact<T>,
116+
) -> PyRefExact<T> {
117+
if self.class().is(T::class(ctx)) {
118+
unsafe { PyRefExact::new_unchecked(self) }
119+
} else {
120+
f(self)
121+
}
122+
}
123+
}
124+
110125
/// PyRef but guaranteed not to be a subtype instance
111126
#[derive(Debug)]
112127
#[repr(transparent)]

0 commit comments

Comments
 (0)