Skip to content

Commit e7fb116

Browse files
Convert more objects to Any payload
1 parent 4558dbf commit e7fb116

File tree

5 files changed

+94
-66
lines changed

5 files changed

+94
-66
lines changed

vm/src/obj/objbool.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use super::objfloat::PyFloat;
12
use super::objstr::PyString;
23
use super::objtype;
34
use crate::pyobject::{
@@ -16,9 +17,11 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
1617
if let Some(s) = obj.payload::<PyString>() {
1718
return Ok(!s.value.is_empty());
1819
}
20+
if let Some(value) = obj.payload::<PyFloat>() {
21+
return Ok(*value != PyFloat::from(0.0));
22+
}
1923
let result = match obj.payload {
2024
PyObjectPayload::Integer { ref value } => !value.is_zero(),
21-
PyObjectPayload::Float { value } => value != 0.0,
2225
PyObjectPayload::Sequence { ref elements } => !elements.borrow().is_empty(),
2326
PyObjectPayload::Dict { ref elements } => !elements.borrow().is_empty(),
2427
PyObjectPayload::None { .. } => false,

vm/src/obj/objfloat.rs

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,30 @@ use super::objint;
33
use super::objstr;
44
use super::objtype;
55
use crate::pyobject::{
6-
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
6+
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
7+
TypeProtocol,
78
};
89
use crate::vm::VirtualMachine;
910
use num_bigint::ToBigInt;
1011
use num_traits::ToPrimitive;
1112

13+
#[derive(Debug, Copy, Clone, PartialEq)]
14+
pub struct PyFloat {
15+
value: f64,
16+
}
17+
18+
impl PyObjectPayload2 for PyFloat {
19+
fn required_type(ctx: &PyContext) -> PyObjectRef {
20+
ctx.float_type()
21+
}
22+
}
23+
24+
impl From<f64> for PyFloat {
25+
fn from(value: f64) -> Self {
26+
PyFloat { value }
27+
}
28+
}
29+
1230
fn float_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1331
arg_check!(vm, args, required = [(float, Some(vm.ctx.float_type()))]);
1432
let v = get_value(float);
@@ -50,16 +68,18 @@ fn float_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5068
let type_name = objtype::get_type_name(&arg.typ());
5169
return Err(vm.new_type_error(format!("can't convert {} to float", type_name)));
5270
};
53-
Ok(PyObject::new(PyObjectPayload::Float { value }, cls.clone()))
71+
72+
Ok(PyObject::new(
73+
PyObjectPayload::AnyRustValue {
74+
value: Box::new(PyFloat { value }),
75+
},
76+
cls.clone(),
77+
))
5478
}
5579

5680
// Retrieve inner float value:
5781
pub fn get_value(obj: &PyObjectRef) -> f64 {
58-
if let PyObjectPayload::Float { value } = &obj.payload {
59-
*value
60-
} else {
61-
panic!("Inner error getting float: {}", obj);
62-
}
82+
obj.payload::<PyFloat>().unwrap().value
6383
}
6484

6585
pub fn make_float(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyResult<f64> {

vm/src/obj/objiter.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22
* Various types to support iteration.
33
*/
44

5-
use super::objbool;
65
use crate::pyobject::{
76
PyContext, PyFuncArgs, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
87
};
98
use crate::vm::VirtualMachine;
10-
// use super::objstr;
11-
use super::objtype; // Required for arg_check! to use isinstance
9+
10+
use super::objbool;
11+
use super::objrange::PyRange;
12+
use super::objtype;
1213

1314
/*
1415
* This helper function is called at multiple places. First, it is called
@@ -129,38 +130,37 @@ fn iter_next(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
129130
iterated_obj: ref iterated_obj_ref,
130131
} = iter.payload
131132
{
132-
match iterated_obj_ref.payload {
133-
PyObjectPayload::Sequence { ref elements } => {
134-
if position.get() < elements.borrow().len() {
135-
let obj_ref = elements.borrow()[position.get()].clone();
136-
position.set(position.get() + 1);
137-
Ok(obj_ref)
138-
} else {
139-
Err(new_stop_iteration(vm))
140-
}
133+
if let Some(range) = iterated_obj_ref.payload::<PyRange>() {
134+
if let Some(int) = range.get(position.get()) {
135+
position.set(position.get() + 1);
136+
Ok(vm.ctx.new_int(int))
137+
} else {
138+
Err(new_stop_iteration(vm))
141139
}
142-
143-
PyObjectPayload::Range { ref range } => {
144-
if let Some(int) = range.get(position.get()) {
145-
position.set(position.get() + 1);
146-
Ok(vm.ctx.new_int(int))
147-
} else {
148-
Err(new_stop_iteration(vm))
140+
} else {
141+
match iterated_obj_ref.payload {
142+
PyObjectPayload::Sequence { ref elements } => {
143+
if position.get() < elements.borrow().len() {
144+
let obj_ref = elements.borrow()[position.get()].clone();
145+
position.set(position.get() + 1);
146+
Ok(obj_ref)
147+
} else {
148+
Err(new_stop_iteration(vm))
149+
}
149150
}
150-
}
151-
152-
PyObjectPayload::Bytes { ref value } => {
153-
if position.get() < value.borrow().len() {
154-
let obj_ref = vm.ctx.new_int(value.borrow()[position.get()]);
155-
position.set(position.get() + 1);
156-
Ok(obj_ref)
157-
} else {
158-
Err(new_stop_iteration(vm))
151+
PyObjectPayload::Bytes { ref value } => {
152+
if position.get() < value.borrow().len() {
153+
let obj_ref = vm.ctx.new_int(value.borrow()[position.get()]);
154+
position.set(position.get() + 1);
155+
Ok(obj_ref)
156+
} else {
157+
Err(new_stop_iteration(vm))
158+
}
159159
}
160-
}
161160

162-
_ => {
163-
panic!("NOT IMPL");
161+
_ => {
162+
panic!("NOT IMPL");
163+
}
164164
}
165165
}
166166
} else {

vm/src/obj/objrange.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,30 @@ use std::ops::Mul;
44
use super::objint;
55
use super::objtype;
66
use crate::pyobject::{
7-
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult, TypeProtocol,
7+
PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef, PyResult,
8+
TypeProtocol,
89
};
910
use crate::vm::VirtualMachine;
1011
use num_bigint::{BigInt, Sign};
1112
use num_integer::Integer;
1213
use num_traits::{One, Signed, ToPrimitive, Zero};
1314

1415
#[derive(Debug, Clone)]
15-
pub struct RangeType {
16+
pub struct PyRange {
1617
// Unfortunately Rust's built in range type doesn't support things like indexing
1718
// or ranges where start > end so we need to roll our own.
1819
pub start: BigInt,
1920
pub end: BigInt,
2021
pub step: BigInt,
2122
}
2223

23-
impl RangeType {
24+
impl PyObjectPayload2 for PyRange {
25+
fn required_type(ctx: &PyContext) -> PyObjectRef {
26+
ctx.range_type()
27+
}
28+
}
29+
30+
impl PyRange {
2431
#[inline]
2532
pub fn try_len(&self) -> Option<usize> {
2633
match self.step.sign() {
@@ -116,12 +123,12 @@ impl RangeType {
116123
};
117124

118125
match self.step.sign() {
119-
Sign::Plus => RangeType {
126+
Sign::Plus => PyRange {
120127
start,
121128
end: &self.start - 1,
122129
step: -&self.step,
123130
},
124-
Sign::Minus => RangeType {
131+
Sign::Minus => PyRange {
125132
start,
126133
end: &self.start + 1,
127134
step: -&self.step,
@@ -139,12 +146,8 @@ impl RangeType {
139146
}
140147
}
141148

142-
pub fn get_value(obj: &PyObjectRef) -> RangeType {
143-
if let PyObjectPayload::Range { range } = &obj.payload {
144-
range.clone()
145-
} else {
146-
panic!("Inner error getting range {:?}", obj);
147-
}
149+
pub fn get_value(obj: &PyObjectRef) -> PyRange {
150+
obj.payload::<PyRange>().unwrap().clone()
148151
}
149152

150153
pub fn init(context: &PyContext) {
@@ -223,8 +226,8 @@ fn range_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
223226
Err(vm.new_value_error("range with 0 step size".to_string()))
224227
} else {
225228
Ok(PyObject::new(
226-
PyObjectPayload::Range {
227-
range: RangeType { start, end, step },
229+
PyObjectPayload::AnyRustValue {
230+
value: Box::new(PyRange { start, end, step }),
228231
},
229232
cls.clone(),
230233
))
@@ -251,7 +254,12 @@ fn range_reversed(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
251254
Ok(PyObject::new(
252255
PyObjectPayload::Iterator {
253256
position: Cell::new(0),
254-
iterated_obj: PyObject::new(PyObjectPayload::Range { range }, vm.ctx.range_type()),
257+
iterated_obj: PyObject::new(
258+
PyObjectPayload::AnyRustValue {
259+
value: Box::new(range),
260+
},
261+
vm.ctx.range_type(),
262+
),
255263
},
256264
vm.ctx.iter_type(),
257265
))
@@ -316,12 +324,12 @@ fn range_getitem(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
316324
};
317325

318326
Ok(PyObject::new(
319-
PyObjectPayload::Range {
320-
range: RangeType {
327+
PyObjectPayload::AnyRustValue {
328+
value: Box::new(PyRange {
321329
start: new_start,
322330
end: new_end,
323331
step: new_step,
324-
},
332+
}),
325333
},
326334
vm.ctx.range_type(),
327335
))

vm/src/pyobject.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -459,8 +459,13 @@ impl PyContext {
459459
)
460460
}
461461

462-
pub fn new_float(&self, i: f64) -> PyObjectRef {
463-
PyObject::new(PyObjectPayload::Float { value: i }, self.float_type())
462+
pub fn new_float(&self, value: f64) -> PyObjectRef {
463+
PyObject::new(
464+
PyObjectPayload::AnyRustValue {
465+
value: Box::new(objfloat::PyFloat::from(value)),
466+
},
467+
self.float_type(),
468+
)
464469
}
465470

466471
pub fn new_complex(&self, i: Complex64) -> PyObjectRef {
@@ -1245,9 +1250,6 @@ pub enum PyObjectPayload {
12451250
Integer {
12461251
value: BigInt,
12471252
},
1248-
Float {
1249-
value: f64,
1250-
},
12511253
Complex {
12521254
value: Complex64,
12531255
},
@@ -1284,9 +1286,6 @@ pub enum PyObjectPayload {
12841286
stop: Option<BigInt>,
12851287
step: Option<BigInt>,
12861288
},
1287-
Range {
1288-
range: objrange::RangeType,
1289-
},
12901289
MemoryView {
12911290
obj: PyObjectRef,
12921291
},
@@ -1340,15 +1339,13 @@ impl fmt::Debug for PyObjectPayload {
13401339
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
13411340
match self {
13421341
PyObjectPayload::Integer { ref value } => write!(f, "int {}", value),
1343-
PyObjectPayload::Float { ref value } => write!(f, "float {}", value),
13441342
PyObjectPayload::Complex { ref value } => write!(f, "complex {}", value),
13451343
PyObjectPayload::Bytes { ref value } => write!(f, "bytes/bytearray {:?}", value),
13461344
PyObjectPayload::MemoryView { ref obj } => write!(f, "bytes/bytearray {:?}", obj),
13471345
PyObjectPayload::Sequence { .. } => write!(f, "list or tuple"),
13481346
PyObjectPayload::Dict { .. } => write!(f, "dict"),
13491347
PyObjectPayload::Set { .. } => write!(f, "set"),
13501348
PyObjectPayload::WeakRef { .. } => write!(f, "weakref"),
1351-
PyObjectPayload::Range { .. } => write!(f, "range"),
13521349
PyObjectPayload::Iterator { .. } => write!(f, "iterator"),
13531350
PyObjectPayload::EnumerateIterator { .. } => write!(f, "enumerate"),
13541351
PyObjectPayload::FilterIterator { .. } => write!(f, "filter"),

0 commit comments

Comments
 (0)