Skip to content

Commit 94e3cb8

Browse files
authored
Merge pull request RustPython#682 from RustPython/prefer_pyvalue_into_ref
Prefer pyvalue into ref
2 parents dbce329 + 1f1b48c commit 94e3cb8

File tree

8 files changed

+75
-132
lines changed

8 files changed

+75
-132
lines changed

vm/src/frame.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use crate::obj::objslice::PySlice;
2020
use crate::obj::objstr;
2121
use crate::obj::objtype;
2222
use crate::pyobject::{
23-
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectRef,
24-
PyResult, PyValue, TryFromObject, TypeProtocol,
23+
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
24+
PyValue, TryFromObject, TypeProtocol,
2525
};
2626
use crate::vm::VirtualMachine;
2727

@@ -409,8 +409,8 @@ impl Frame {
409409
let stop = out[1].take();
410410
let step = if out.len() == 3 { out[2].take() } else { None };
411411

412-
let obj = PyObject::new(PySlice { start, stop, step }, vm.ctx.slice_type());
413-
self.push_value(obj);
412+
let obj = PySlice { start, stop, step }.into_ref(vm);
413+
self.push_value(obj.into_object());
414414
Ok(None)
415415
}
416416
bytecode::Instruction::ListAppend { i } => {
@@ -699,11 +699,9 @@ impl Frame {
699699
Ok(None)
700700
}
701701
bytecode::Instruction::LoadBuildClass => {
702-
let rustfunc = PyObject::new(
703-
PyBuiltinFunction::new(Box::new(builtins::builtin_build_class_)),
704-
vm.ctx.type_type(),
705-
);
706-
self.push_value(rustfunc);
702+
let rustfunc =
703+
PyBuiltinFunction::new(Box::new(builtins::builtin_build_class_)).into_ref(vm);
704+
self.push_value(rustfunc.into_object());
707705
Ok(None)
708706
}
709707
bytecode::Instruction::UnpackSequence { size } => {

vm/src/obj/objbytearray.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ use std::fmt::Write;
55
use std::ops::{Deref, DerefMut};
66

77
use crate::pyobject::{
8-
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
8+
OptionalArg, PyContext, PyFuncArgs, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
99
};
1010

1111
use super::objint;
1212

13-
use super::objtype;
13+
use super::objtype::{self, PyClassRef};
1414
use crate::vm::VirtualMachine;
1515
use num_traits::ToPrimitive;
1616

@@ -19,6 +19,7 @@ pub struct PyByteArray {
1919
// TODO: shouldn't be public
2020
pub value: RefCell<Vec<u8>>,
2121
}
22+
type PyByteArrayRef = PyRef<PyByteArray>;
2223

2324
impl PyByteArray {
2425
pub fn new(data: Vec<u8>) -> Self {
@@ -144,20 +145,14 @@ pub fn init(context: &PyContext) {
144145
);
145146
}
146147

147-
fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
148-
arg_check!(
149-
vm,
150-
args,
151-
required = [(cls, None)],
152-
optional = [(val_option, None)]
153-
);
154-
if !objtype::issubclass(cls, &vm.ctx.bytearray_type()) {
155-
return Err(vm.new_type_error(format!("{:?} is not a subtype of bytearray", cls)));
156-
}
157-
148+
fn bytearray_new(
149+
cls: PyClassRef,
150+
val_option: OptionalArg<PyObjectRef>,
151+
vm: &mut VirtualMachine,
152+
) -> PyResult<PyByteArrayRef> {
158153
// Create bytes data:
159-
let value = if let Some(ival) = val_option {
160-
let elements = vm.extract_elements(ival)?;
154+
let value = if let OptionalArg::Present(ival) = val_option {
155+
let elements = vm.extract_elements(&ival)?;
161156
let mut data_bytes = vec![];
162157
for elem in elements.iter() {
163158
let v = objint::to_int(vm, elem, 10)?;
@@ -172,7 +167,7 @@ fn bytearray_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
172167
} else {
173168
vec![]
174169
};
175-
Ok(PyObject::new(PyByteArray::new(value), cls.clone()))
170+
PyByteArray::new(value).into_ref_with_type(vm, cls.clone())
176171
}
177172

178173
fn bytesarray_len(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/obj/objbytes.rs

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use std::hash::{Hash, Hasher};
33
use std::ops::Deref;
44

55
use super::objint;
6-
use super::objtype;
6+
use super::objtype::{self, PyClassRef};
77
use crate::pyobject::{
8-
PyContext, PyFuncArgs, PyIteratorValue, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
8+
OptionalArg, PyContext, PyFuncArgs, PyIteratorValue, PyObjectRef, PyRef, PyResult, PyValue,
9+
TypeProtocol,
910
};
1011
use crate::vm::VirtualMachine;
1112
use num_traits::ToPrimitive;
@@ -14,6 +15,7 @@ use num_traits::ToPrimitive;
1415
pub struct PyBytes {
1516
value: Vec<u8>,
1617
}
18+
type PyBytesRef = PyRef<PyBytes>;
1719

1820
impl PyBytes {
1921
pub fn new(data: Vec<u8>) -> Self {
@@ -69,20 +71,14 @@ pub fn init(context: &PyContext) {
6971
);
7072
}
7173

72-
fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
73-
arg_check!(
74-
vm,
75-
args,
76-
required = [(cls, None)],
77-
optional = [(val_option, None)]
78-
);
79-
if !objtype::issubclass(cls, &vm.ctx.bytes_type()) {
80-
return Err(vm.new_type_error(format!("{:?} is not a subtype of bytes", cls)));
81-
}
82-
74+
fn bytes_new(
75+
cls: PyClassRef,
76+
val_option: OptionalArg<PyObjectRef>,
77+
vm: &mut VirtualMachine,
78+
) -> PyResult<PyBytesRef> {
8379
// Create bytes data:
84-
let value = if let Some(ival) = val_option {
85-
let elements = vm.extract_elements(ival)?;
80+
let value = if let OptionalArg::Present(ival) = val_option {
81+
let elements = vm.extract_elements(&ival)?;
8682
let mut data_bytes = vec![];
8783
for elem in elements.iter() {
8884
let v = objint::to_int(vm, elem, 10)?;
@@ -94,7 +90,7 @@ fn bytes_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
9490
vec![]
9591
};
9692

97-
Ok(PyObject::new(PyBytes::new(value), cls.clone()))
93+
PyBytes::new(value).into_ref_with_type(vm, cls)
9894
}
9995

10096
fn bytes_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -199,16 +195,9 @@ fn bytes_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
199195
Ok(vm.new_str(format!("b'{}'", data)))
200196
}
201197

202-
fn bytes_iter(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
203-
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bytes_type()))]);
204-
205-
let iter_obj = PyObject::new(
206-
PyIteratorValue {
207-
position: Cell::new(0),
208-
iterated_obj: obj.clone(),
209-
},
210-
vm.ctx.iter_type(),
211-
);
212-
213-
Ok(iter_obj)
198+
fn bytes_iter(obj: PyBytesRef, _vm: &mut VirtualMachine) -> PyIteratorValue {
199+
PyIteratorValue {
200+
position: Cell::new(0),
201+
iterated_obj: obj.into_object(),
202+
}
214203
}

vm/src/obj/objcomplex.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use super::objfloat;
22
use super::objint;
3-
use super::objtype;
3+
use super::objtype::{self, PyClassRef};
44
use crate::pyobject::{
5-
PyContext, PyFuncArgs, PyObject, PyObjectRef, PyResult, PyValue, TypeProtocol,
5+
OptionalArg, PyContext, PyFuncArgs, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol,
66
};
77
use crate::vm::VirtualMachine;
88
use num_complex::Complex64;
@@ -12,6 +12,7 @@ use num_traits::ToPrimitive;
1212
pub struct PyComplex {
1313
value: Complex64,
1414
}
15+
type PyComplexRef = PyRef<PyComplex>;
1516

1617
impl PyValue for PyComplex {
1718
fn class(vm: &mut VirtualMachine) -> PyObjectRef {
@@ -65,31 +66,24 @@ pub fn get_value(obj: &PyObjectRef) -> Complex64 {
6566
obj.payload::<PyComplex>().unwrap().value
6667
}
6768

68-
fn complex_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
69-
arg_check!(
70-
vm,
71-
args,
72-
required = [(cls, None)],
73-
optional = [(real, None), (imag, None)]
74-
);
75-
76-
if !objtype::issubclass(cls, &vm.ctx.complex_type()) {
77-
return Err(vm.new_type_error(format!("{:?} is not a subtype of complex", cls)));
78-
}
79-
69+
fn complex_new(
70+
cls: PyClassRef,
71+
real: OptionalArg<PyObjectRef>,
72+
imag: OptionalArg<PyObjectRef>,
73+
vm: &mut VirtualMachine,
74+
) -> PyResult<PyComplexRef> {
8075
let real = match real {
81-
None => 0.0,
82-
Some(value) => objfloat::make_float(vm, value)?,
76+
OptionalArg::Missing => 0.0,
77+
OptionalArg::Present(ref value) => objfloat::make_float(vm, value)?,
8378
};
8479

8580
let imag = match imag {
86-
None => 0.0,
87-
Some(value) => objfloat::make_float(vm, value)?,
81+
OptionalArg::Missing => 0.0,
82+
OptionalArg::Present(ref value) => objfloat::make_float(vm, value)?,
8883
};
8984

9085
let value = Complex64::new(real, imag);
91-
92-
Ok(PyObject::new(PyComplex { value }, cls.clone()))
86+
PyComplex { value }.into_ref_with_type(vm, cls)
9387
}
9488

9589
fn complex_real(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/obj/objproperty.rs

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,12 @@ impl PyPropertyRef {
5454
_doc: OptionalArg<PyStringRef>,
5555
vm: &mut VirtualMachine,
5656
) -> PyResult<PyPropertyRef> {
57-
Self::new_with_type(
58-
vm,
59-
PyProperty {
60-
getter: fget.into_option(),
61-
setter: fset.into_option(),
62-
deleter: fdel.into_option(),
63-
},
64-
cls,
65-
)
57+
PyProperty {
58+
getter: fget.into_option(),
59+
setter: fset.into_option(),
60+
deleter: fdel.into_option(),
61+
}
62+
.into_ref_with_type(vm, cls)
6663
}
6764

6865
// Descriptor methods
@@ -108,39 +105,30 @@ impl PyPropertyRef {
108105
// Python builder functions
109106

110107
fn getter(self, getter: Option<PyObjectRef>, vm: &mut VirtualMachine) -> PyResult<Self> {
111-
Self::new_with_type(
112-
vm,
113-
PyProperty {
114-
getter: getter.or_else(|| self.getter.clone()),
115-
setter: self.setter.clone(),
116-
deleter: self.deleter.clone(),
117-
},
118-
self.typ(),
119-
)
108+
PyProperty {
109+
getter: getter.or_else(|| self.getter.clone()),
110+
setter: self.setter.clone(),
111+
deleter: self.deleter.clone(),
112+
}
113+
.into_ref_with_type(vm, self.typ())
120114
}
121115

122116
fn setter(self, setter: Option<PyObjectRef>, vm: &mut VirtualMachine) -> PyResult<Self> {
123-
Self::new_with_type(
124-
vm,
125-
PyProperty {
126-
getter: self.getter.clone(),
127-
setter: setter.or_else(|| self.setter.clone()),
128-
deleter: self.deleter.clone(),
129-
},
130-
self.typ(),
131-
)
117+
PyProperty {
118+
getter: self.getter.clone(),
119+
setter: setter.or_else(|| self.setter.clone()),
120+
deleter: self.deleter.clone(),
121+
}
122+
.into_ref_with_type(vm, self.typ())
132123
}
133124

134125
fn deleter(self, deleter: Option<PyObjectRef>, vm: &mut VirtualMachine) -> PyResult<Self> {
135-
Self::new_with_type(
136-
vm,
137-
PyProperty {
138-
getter: self.getter.clone(),
139-
setter: self.setter.clone(),
140-
deleter: deleter.or_else(|| self.deleter.clone()),
141-
},
142-
self.typ(),
143-
)
126+
PyProperty {
127+
getter: self.getter.clone(),
128+
setter: self.setter.clone(),
129+
deleter: deleter.or_else(|| self.deleter.clone()),
130+
}
131+
.into_ref_with_type(vm, self.typ())
144132
}
145133
}
146134

vm/src/obj/objstr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ fn str_new(
801801
TryFromObject::try_from_object(vm, string)
802802
} else {
803803
let payload = string.payload::<PyString>().unwrap();
804-
PyRef::new_with_type(vm, payload.clone(), cls)
804+
payload.clone().into_ref_with_type(vm, cls)
805805
}
806806
}
807807

vm/src/obj/objweakref.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub type PyWeakRef = PyRef<PyWeak>;
3333
impl PyWeakRef {
3434
// TODO callbacks
3535
fn create(cls: PyClassRef, referent: PyObjectRef, vm: &mut VirtualMachine) -> PyResult<Self> {
36-
Self::new_with_type(vm, PyWeak::downgrade(referent), cls)
36+
PyWeak::downgrade(referent).into_ref_with_type(vm, cls)
3737
}
3838

3939
fn call(self, vm: &mut VirtualMachine) -> PyObjectRef {

vm/src/pyobject.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -713,27 +713,6 @@ pub struct PyRef<T> {
713713
}
714714

715715
impl<T: PyValue> PyRef<T> {
716-
pub fn new(vm: &mut VirtualMachine, payload: T) -> Self {
717-
PyRef {
718-
obj: PyObject::new(payload, T::class(vm)),
719-
_payload: PhantomData,
720-
}
721-
}
722-
723-
pub fn new_with_type(vm: &mut VirtualMachine, payload: T, cls: PyClassRef) -> PyResult<Self> {
724-
let class = T::class(vm);
725-
if objtype::issubclass(&cls.obj, &class) {
726-
Ok(PyRef {
727-
obj: PyObject::new(payload, cls.obj),
728-
_payload: PhantomData,
729-
})
730-
} else {
731-
let subtype = vm.to_pystr(&cls.obj)?;
732-
let basetype = vm.to_pystr(&class)?;
733-
Err(vm.new_type_error(format!("{} is not a subtype of {}", subtype, basetype)))
734-
}
735-
}
736-
737716
pub fn as_object(&self) -> &PyObjectRef {
738717
&self.obj
739718
}

0 commit comments

Comments
 (0)