Skip to content

Commit d9c35f9

Browse files
Convert dict payload
1 parent bf1fe9e commit d9c35f9

File tree

4 files changed

+62
-73
lines changed

4 files changed

+62
-73
lines changed

vm/src/frame.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use crate::import::{import, import_module};
1111
use crate::obj::objbool;
1212
use crate::obj::objcode;
1313
use crate::obj::objdict;
14+
use crate::obj::objdict::PyDict;
1415
use crate::obj::objiter;
1516
use crate::obj::objlist;
1617
use crate::obj::objstr;
@@ -1125,18 +1126,13 @@ impl fmt::Debug for Frame {
11251126
.map(|elem| format!("\n > {:?}", elem))
11261127
.collect::<Vec<_>>()
11271128
.join("");
1128-
let local_str = match self.scope.locals.payload {
1129-
PyObjectPayload::Dict { ref elements } => {
1130-
objdict::get_key_value_pairs_from_content(&elements.borrow())
1131-
.iter()
1132-
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1133-
.collect::<Vec<_>>()
1134-
.join("")
1135-
}
1136-
ref unexpected => panic!(
1137-
"locals unexpectedly not wrapping a dict! instead: {:?}",
1138-
unexpected
1139-
),
1129+
let local_str = match self.scope.locals.payload::<PyDict>() {
1130+
Some(dict) => objdict::get_key_value_pairs_from_content(&dict.entries.borrow())
1131+
.iter()
1132+
.map(|elem| format!("\n {:?} = {:?}", elem.0, elem.1))
1133+
.collect::<Vec<_>>()
1134+
.join(""),
1135+
None => panic!("locals unexpectedly not wrapping a dict!",),
11401136
};
11411137
write!(
11421138
f,

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::objdict::PyDict;
12
use super::objfloat::PyFloat;
23
use super::objstr::PyString;
34
use super::objtype;
@@ -20,10 +21,12 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
2021
if let Some(value) = obj.payload::<PyFloat>() {
2122
return Ok(*value != PyFloat::from(0.0));
2223
}
24+
if let Some(dict) = obj.payload::<PyDict>() {
25+
return Ok(!dict.entries.borrow().is_empty());
26+
}
2327
let result = match obj.payload {
2428
PyObjectPayload::Integer { ref value } => !value.is_zero(),
2529
PyObjectPayload::Sequence { ref elements } => !elements.borrow().is_empty(),
26-
PyObjectPayload::Dict { ref elements } => !elements.borrow().is_empty(),
2730
PyObjectPayload::None { .. } => false,
2831
_ => {
2932
if let Ok(f) = vm.get_method(obj.clone(), "__bool__") {

vm/src/obj/objdict.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,31 @@ use super::objiter;
66
use super::objstr;
77
use super::objtype;
88
use crate::pyobject::{
9-
PyAttributes, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectRef, PyResult,
10-
TypeProtocol,
9+
PyAttributes, PyContext, PyFuncArgs, PyObject, PyObjectPayload, PyObjectPayload2, PyObjectRef,
10+
PyResult, TypeProtocol,
1111
};
1212
use crate::vm::{ReprGuard, VirtualMachine};
1313

14-
// This typedef abstracts the actual dict type used.
15-
// pub type DictContentType = HashMap<usize, Vec<(PyObjectRef, PyObjectRef)>>;
16-
// pub type DictContentType = HashMap<String, PyObjectRef>;
1714
pub type DictContentType = HashMap<String, (PyObjectRef, PyObjectRef)>;
18-
// pub type DictContentType = HashMap<String, Vec<(PyObjectRef, PyObjectRef)>>;
1915

20-
pub fn new(dict_type: PyObjectRef) -> PyObjectRef {
21-
PyObject::new(
22-
PyObjectPayload::Dict {
23-
elements: RefCell::new(HashMap::new()),
24-
},
25-
dict_type.clone(),
26-
)
16+
#[derive(Default, Debug)]
17+
pub struct PyDict {
18+
// TODO: should be private
19+
pub entries: RefCell<DictContentType>,
2720
}
2821

29-
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = DictContentType> + 'a {
30-
if let PyObjectPayload::Dict { ref elements } = obj.payload {
31-
elements.borrow()
32-
} else {
33-
panic!("Cannot extract dict elements");
22+
impl PyObjectPayload2 for PyDict {
23+
fn required_type(ctx: &PyContext) -> PyObjectRef {
24+
ctx.dict_type()
3425
}
3526
}
3627

28+
pub fn get_elements<'a>(obj: &'a PyObjectRef) -> impl Deref<Target = DictContentType> + 'a {
29+
obj.payload::<PyDict>().unwrap().entries.borrow()
30+
}
31+
3732
fn get_mut_elements<'a>(obj: &'a PyObjectRef) -> impl DerefMut<Target = DictContentType> + 'a {
38-
if let PyObjectPayload::Dict { ref elements } = obj.payload {
39-
elements.borrow_mut()
40-
} else {
41-
panic!("Cannot extract dict elements");
42-
}
33+
obj.payload::<PyDict>().unwrap().entries.borrow_mut()
4334
}
4435

4536
pub fn set_item(

vm/src/pyobject.rs

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::obj::objbytearray;
1818
use crate::obj::objbytes;
1919
use crate::obj::objcode;
2020
use crate::obj::objcomplex::{self, PyComplex};
21-
use crate::obj::objdict;
21+
use crate::obj::objdict::{self, PyDict};
2222
use crate::obj::objenumerate;
2323
use crate::obj::objfilter;
2424
use crate::obj::objfloat::{self, PyFloat};
@@ -545,8 +545,8 @@ impl PyContext {
545545

546546
pub fn new_dict(&self) -> PyObjectRef {
547547
PyObject::new(
548-
PyObjectPayload::Dict {
549-
elements: RefCell::new(HashMap::new()),
548+
PyObjectPayload::AnyRustValue {
549+
value: Box::new(PyDict::default()),
550550
},
551551
self.dict_type(),
552552
)
@@ -654,12 +654,11 @@ impl PyContext {
654654

655655
// Item set/get:
656656
pub fn set_item(&self, obj: &PyObjectRef, key: &str, v: PyObjectRef) {
657-
match obj.payload {
658-
PyObjectPayload::Dict { ref elements } => {
659-
let key = self.new_str(key.to_string());
660-
objdict::set_item_in_content(&mut elements.borrow_mut(), &key, &v);
661-
}
662-
ref k => panic!("TODO {:?}", k),
657+
if let Some(dict) = obj.payload::<PyDict>() {
658+
let key = self.new_str(key.to_string());
659+
objdict::set_item_in_content(&mut dict.entries.borrow_mut(), &key, &v);
660+
} else {
661+
unimplemented!()
663662
};
664663
}
665664

@@ -816,44 +815,48 @@ pub trait DictProtocol {
816815

817816
impl DictProtocol for PyObjectRef {
818817
fn contains_key(&self, k: &str) -> bool {
819-
match self.payload {
820-
PyObjectPayload::Dict { ref elements } => {
821-
objdict::content_contains_key_str(&elements.borrow(), k)
822-
}
823-
ref payload => unimplemented!("TODO {:?}", payload),
818+
if let Some(dict) = self.payload::<PyDict>() {
819+
objdict::content_contains_key_str(&dict.entries.borrow(), k)
820+
} else {
821+
unimplemented!()
824822
}
825823
}
826824

827825
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
828-
match self.payload {
829-
PyObjectPayload::Dict { ref elements } => {
830-
objdict::content_get_key_str(&elements.borrow(), k)
826+
if let Some(dict) = self.payload::<PyDict>() {
827+
objdict::content_get_key_str(&dict.entries.borrow(), k)
828+
} else {
829+
match self.payload {
830+
PyObjectPayload::Module { ref scope, .. } => scope.locals.get_item(k),
831+
ref k => panic!("TODO {:?}", k),
831832
}
832-
PyObjectPayload::Module { ref scope, .. } => scope.locals.get_item(k),
833-
ref k => panic!("TODO {:?}", k),
834833
}
835834
}
836835

837836
fn get_key_value_pairs(&self) -> Vec<(PyObjectRef, PyObjectRef)> {
838-
match self.payload {
839-
PyObjectPayload::Dict { .. } => objdict::get_key_value_pairs(self),
840-
PyObjectPayload::Module { ref scope, .. } => scope.locals.get_key_value_pairs(),
841-
_ => panic!("TODO"),
837+
if let Some(_) = self.payload::<PyDict>() {
838+
objdict::get_key_value_pairs(self)
839+
} else {
840+
match self.payload {
841+
PyObjectPayload::Module { ref scope, .. } => scope.locals.get_key_value_pairs(),
842+
_ => panic!("TODO"),
843+
}
842844
}
843845
}
844846

845847
// Item set/get:
846848
fn set_item(&self, ctx: &PyContext, key: &str, v: PyObjectRef) {
847-
match &self.payload {
848-
PyObjectPayload::Dict { elements } => {
849-
let key = ctx.new_str(key.to_string());
850-
objdict::set_item_in_content(&mut elements.borrow_mut(), &key, &v);
851-
}
852-
PyObjectPayload::Module { scope, .. } => {
853-
scope.locals.set_item(ctx, key, v);
854-
}
855-
ref k => panic!("TODO {:?}", k),
856-
};
849+
if let Some(dict) = self.payload::<PyDict>() {
850+
let key = ctx.new_str(key.to_string());
851+
objdict::set_item_in_content(&mut dict.entries.borrow_mut(), &key, &v);
852+
} else {
853+
match &self.payload {
854+
PyObjectPayload::Module { scope, .. } => {
855+
scope.locals.set_item(ctx, key, v);
856+
}
857+
ref k => panic!("TODO {:?}", k),
858+
};
859+
}
857860
}
858861
}
859862

@@ -1417,9 +1420,6 @@ pub enum PyObjectPayload {
14171420
Sequence {
14181421
elements: RefCell<Vec<PyObjectRef>>,
14191422
},
1420-
Dict {
1421-
elements: RefCell<objdict::DictContentType>,
1422-
},
14231423
Iterator {
14241424
position: Cell<usize>,
14251425
iterated_obj: PyObjectRef,
@@ -1496,7 +1496,6 @@ impl fmt::Debug for PyObjectPayload {
14961496
PyObjectPayload::Integer { ref value } => write!(f, "int {}", value),
14971497
PyObjectPayload::MemoryView { ref obj } => write!(f, "bytes/bytearray {:?}", obj),
14981498
PyObjectPayload::Sequence { .. } => write!(f, "list or tuple"),
1499-
PyObjectPayload::Dict { .. } => write!(f, "dict"),
15001499
PyObjectPayload::WeakRef { .. } => write!(f, "weakref"),
15011500
PyObjectPayload::Iterator { .. } => write!(f, "iterator"),
15021501
PyObjectPayload::EnumerateIterator { .. } => write!(f, "enumerate"),

0 commit comments

Comments
 (0)