Skip to content

Commit 62c53d8

Browse files
committed
Try to make it simpler to switch dict storage types.
1 parent 521f664 commit 62c53d8

File tree

4 files changed

+61
-15
lines changed

4 files changed

+61
-15
lines changed

vm/src/frame.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -1090,11 +1090,15 @@ impl fmt::Debug for Frame {
10901090
.join("");
10911091
let local_str = match self.locals.borrow().kind {
10921092
PyObjectKind::Scope { ref scope } => match scope.locals.borrow().kind {
1093-
PyObjectKind::Dict { ref elements } => elements
1094-
.iter()
1095-
.map(|elem| format!("\n {} = {}", elem.0, (elem.1).1.borrow().str()))
1096-
.collect::<Vec<_>>()
1097-
.join(""),
1093+
PyObjectKind::Dict { ref elements } => {
1094+
objdict::get_key_value_pairs_from_content(elements)
1095+
.iter()
1096+
.map(|elem| {
1097+
format!("\n {} = {}", elem.0.borrow().str(), elem.1.borrow().str())
1098+
})
1099+
.collect::<Vec<_>>()
1100+
.join("")
1101+
}
10981102
ref unexpected => panic!(
10991103
"locals unexpectedly not wrapping a dict! instead: {:?}",
11001104
unexpected

vm/src/obj/objdict.rs

+44-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use std::ops::{Deref, DerefMut};
1313
// pub type DictContentType = HashMap<usize, Vec<(PyObjectRef, PyObjectRef)>>;
1414
// pub type DictContentType = HashMap<String, PyObjectRef>;
1515
pub type DictContentType = HashMap<String, (PyObjectRef, PyObjectRef)>;
16+
// pub type DictContentType = HashMap<String, Vec<(PyObjectRef, PyObjectRef)>>;
1617

1718
pub fn new(dict_type: PyObjectRef) -> PyObjectRef {
1819
PyObject::new(
@@ -56,20 +57,62 @@ pub fn set_item_in_content(
5657
// XXX: Currently, we only support String keys, so we have to unwrap the
5758
// PyObject (and ensure it is a String).
5859

60+
// TODO: invoke __hash__ function here!
5961
let needle_str = objstr::get_value(needle);
6062
elements.insert(needle_str, (needle.clone(), value.clone()));
6163
}
6264

6365
pub fn get_key_value_pairs(dict: &PyObjectRef) -> Vec<(PyObjectRef, PyObjectRef)> {
6466
let dict_elements = get_elements(dict);
67+
get_key_value_pairs_from_content(&dict_elements)
68+
}
69+
70+
pub fn get_key_value_pairs_from_content(
71+
dict_content: &DictContentType,
72+
) -> Vec<(PyObjectRef, PyObjectRef)> {
6573
let mut pairs: Vec<(PyObjectRef, PyObjectRef)> = Vec::new();
66-
for (_str_key, pair) in dict_elements.iter() {
74+
for (_str_key, pair) in dict_content.iter() {
6775
let (key, obj) = pair;
6876
pairs.push((key.clone(), obj.clone()));
6977
}
7078
pairs
7179
}
7280

81+
pub fn get_item(dict: &PyObjectRef, key: &PyObjectRef) -> Option<PyObjectRef> {
82+
let needle_str = objstr::get_value(key);
83+
get_key_str(dict, &needle_str)
84+
}
85+
86+
// Special case for the case when requesting a str key from a dict:
87+
pub fn get_key_str(dict: &PyObjectRef, key: &str) -> Option<PyObjectRef> {
88+
let elements = get_elements(dict);
89+
content_get_key_str(&elements, key)
90+
}
91+
92+
/// Retrieve a key from dict contents:
93+
pub fn content_get_key_str(elements: &DictContentType, key: &str) -> Option<PyObjectRef> {
94+
// TODO: let hash: usize = key;
95+
match elements.get(key) {
96+
Some(v) => Some(v.1.clone()),
97+
None => None,
98+
}
99+
}
100+
101+
pub fn contains_key_str(dict: &PyObjectRef, key: &str) -> bool {
102+
let elements = get_elements(dict);
103+
content_contains_key_str(&elements, key)
104+
}
105+
106+
pub fn content_contains_key_str(elements: &DictContentType, key: &str) -> bool {
107+
// TODO: let hash: usize = key;
108+
match elements.get(key) {
109+
Some(_) => true,
110+
None => false,
111+
}
112+
}
113+
114+
// Python dict methods:
115+
73116
fn dict_new(_vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
74117
Ok(new(args.args[0].clone()))
75118
}

vm/src/obj/objtype.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -225,18 +225,20 @@ pub fn get_attributes(obj: &PyObjectRef) -> HashMap<String, PyObjectRef> {
225225
mro: _,
226226
} = &bc.borrow().kind
227227
{
228-
let elements = objdict::get_elements(dict);
228+
let elements = objdict::get_key_value_pairs(dict);
229229
for (name, value) in elements.iter() {
230-
attributes.insert(name.to_string(), value.1.clone());
230+
let name = objstr::get_value(name);
231+
attributes.insert(name.to_string(), value.clone());
231232
}
232233
}
233234
}
234235

235236
// Get instance attributes:
236237
if let PyObjectKind::Instance { dict } = &obj.borrow().kind {
237-
let elements = objdict::get_elements(dict);
238+
let elements = objdict::get_key_value_pairs(dict);
238239
for (name, value) in elements.iter() {
239-
attributes.insert(name.to_string(), value.1.clone());
240+
let name = objstr::get_value(name);
241+
attributes.insert(name.to_string(), value.clone());
240242
}
241243
}
242244
attributes

vm/src/pyobject.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ pub trait DictProtocol {
686686
impl DictProtocol for PyObjectRef {
687687
fn contains_key(&self, k: &str) -> bool {
688688
match self.borrow().kind {
689-
PyObjectKind::Dict { ref elements } => elements.contains_key(k),
689+
PyObjectKind::Dict { ref elements } => objdict::content_contains_key_str(elements, k),
690690
PyObjectKind::Module { name: _, ref dict } => dict.contains_key(k),
691691
PyObjectKind::Scope { ref scope } => scope.locals.contains_key(k),
692692
ref kind => unimplemented!("TODO {:?}", kind),
@@ -695,10 +695,7 @@ impl DictProtocol for PyObjectRef {
695695

696696
fn get_item(&self, k: &str) -> Option<PyObjectRef> {
697697
match self.borrow().kind {
698-
PyObjectKind::Dict { ref elements } => match elements.get(k) {
699-
Some(v) => Some(v.1.clone()),
700-
None => None,
701-
},
698+
PyObjectKind::Dict { ref elements } => objdict::content_get_key_str(elements, k),
702699
PyObjectKind::Module { name: _, ref dict } => dict.get_item(k),
703700
PyObjectKind::Scope { ref scope } => scope.locals.get_item(k),
704701
_ => panic!("TODO"),

0 commit comments

Comments
 (0)