Skip to content

Commit 1d1a931

Browse files
committed
Move attributes dictionary to PyObject.
1 parent 2d78425 commit 1d1a931

File tree

5 files changed

+62
-60
lines changed

5 files changed

+62
-60
lines changed

vm/src/obj/objdict.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,9 @@ pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, dict_type:
311311
unsafe {
312312
(*ptr).payload = PyObjectPayload::Class {
313313
name: String::from("dict"),
314-
dict: RefCell::new(HashMap::new()),
315314
mro: vec![object_type],
316315
};
316+
(*ptr).dict = Some(RefCell::new(HashMap::new()));
317317
(*ptr).typ = Some(type_type.clone());
318318
}
319319
}

vm/src/obj/objobject.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ pub fn create_object(type_type: PyObjectRef, object_type: PyObjectRef, _dict_typ
2121
unsafe {
2222
(*ptr).payload = PyObjectPayload::Class {
2323
name: String::from("object"),
24-
dict: RefCell::new(HashMap::new()),
2524
mro: vec![],
2625
};
26+
(*ptr).dict = Some(RefCell::new(HashMap::new()));
2727
(*ptr).typ = Some(type_type.clone());
2828
}
2929
}
@@ -105,13 +105,13 @@ fn object_delattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
105105
]
106106
);
107107

108-
match zelf.payload {
109-
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
108+
match zelf.dict {
109+
Some(ref dict) => {
110110
let attr_name = objstr::get_value(attr);
111111
dict.borrow_mut().remove(&attr_name);
112112
Ok(vm.get_none())
113113
}
114-
_ => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
114+
None => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
115115
}
116116
}
117117

@@ -178,15 +178,14 @@ fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
178178
}
179179

180180
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
181-
match args.args[0].payload {
182-
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
183-
let new_dict = vm.new_dict();
184-
for (attr, value) in dict.borrow().iter() {
185-
new_dict.set_item(&vm.ctx, &attr, value.clone());
186-
}
187-
Ok(new_dict)
181+
if let Some(ref dict) = args.args[0].dict {
182+
let new_dict = vm.new_dict();
183+
for (attr, value) in dict.borrow().iter() {
184+
new_dict.set_item(&vm.ctx, &attr, value.clone());
188185
}
189-
_ => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
186+
Ok(new_dict)
187+
} else {
188+
Err(vm.new_type_error("TypeError: no dictionary.".to_string()))
190189
}
191190
}
192191

vm/src/obj/objtype.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type:
1919
unsafe {
2020
(*ptr).payload = PyObjectPayload::Class {
2121
name: String::from("type"),
22-
dict: RefCell::new(PyAttributes::new()),
2322
mro: vec![object_type],
2423
};
24+
(*ptr).dict = Some(RefCell::new(PyAttributes::new()));
2525
(*ptr).typ = Some(type_type);
2626
}
2727
}
@@ -264,26 +264,26 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
264264
let mut base_classes = objtype::base_classes(obj);
265265
base_classes.reverse();
266266
for bc in base_classes {
267-
if let PyObjectPayload::Class { dict, .. } = &bc.payload {
267+
if let Some(ref dict) = &bc.dict {
268268
for (name, value) in dict.borrow().iter() {
269269
attributes.insert(name.to_string(), value.clone());
270270
}
271271
}
272272
}
273273

274-
// Get instance attributes:
275-
if let PyObjectPayload::Instance { dict } = &obj.payload {
276-
for (name, value) in dict.borrow().iter() {
277-
attributes.insert(name.to_string(), value.clone());
278-
}
279-
}
280-
281274
// Get module attributes:
282275
if let PyObjectPayload::Module { ref scope, .. } = &obj.payload {
283276
for (name, value) in scope.locals.get_key_value_pairs().iter() {
284277
attributes.insert(objstr::get_value(name).to_string(), value.clone());
285278
}
279+
} else {
280+
if let Some(ref dict) = &obj.dict {
281+
for (name, value) in dict.borrow().iter() {
282+
attributes.insert(name.to_string(), value.clone());
283+
}
284+
}
286285
}
286+
287287
attributes
288288
}
289289

@@ -342,14 +342,15 @@ pub fn new(
342342
) -> PyResult {
343343
let mros = bases.into_iter().map(|x| _mro(x).unwrap()).collect();
344344
let mro = linearise_mro(mros).unwrap();
345-
Ok(PyObject::new(
346-
PyObjectPayload::Class {
345+
Ok(PyObject {
346+
payload: PyObjectPayload::Class {
347347
name: String::from(name),
348-
dict: RefCell::new(dict),
349348
mro,
350349
},
351-
typ,
352-
))
350+
dict: Some(RefCell::new(dict)),
351+
typ: Some(typ),
352+
}
353+
.into_ref())
353354
}
354355

355356
fn type_repr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/pyobject.rs

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -655,12 +655,12 @@ impl PyContext {
655655
} else {
656656
PyAttributes::new()
657657
};
658-
PyObject::new(
659-
PyObjectPayload::Instance {
660-
dict: RefCell::new(dict),
661-
},
662-
class,
663-
)
658+
PyObject {
659+
payload: PyObjectPayload::NoPayload,
660+
typ: Some(class),
661+
dict: Some(RefCell::new(dict)),
662+
}
663+
.into_ref()
664664
}
665665

666666
// Item set/get:
@@ -682,14 +682,12 @@ impl PyContext {
682682
}
683683

684684
pub fn set_attr(&self, obj: &PyObjectRef, attr_name: &str, value: PyObjectRef) {
685-
match obj.payload {
686-
PyObjectPayload::Module { ref scope, .. } => {
687-
scope.locals.set_item(self, attr_name, value)
688-
}
689-
PyObjectPayload::Instance { ref dict } | PyObjectPayload::Class { ref dict, .. } => {
690-
dict.borrow_mut().insert(attr_name.to_string(), value);
691-
}
692-
ref payload => unimplemented!("set_attr unimplemented for: {:?}", payload),
685+
if let PyObjectPayload::Module { ref scope, .. } = obj.payload {
686+
scope.locals.set_item(self, attr_name, value)
687+
} else if let Some(ref dict) = obj.dict {
688+
dict.borrow_mut().insert(attr_name.to_string(), value);
689+
} else {
690+
unimplemented!("set_attr unimplemented for: {:?}", obj);
693691
};
694692
}
695693

@@ -728,7 +726,7 @@ impl Default for PyContext {
728726
pub struct PyObject {
729727
pub payload: PyObjectPayload,
730728
pub typ: Option<PyObjectRef>,
731-
pub dict: Option<HashMap<String, PyObjectRef>>, // __dict__ member
729+
pub dict: Option<RefCell<PyAttributes>>, // __dict__ member
732730
}
733731

734732
pub trait IdProtocol {
@@ -775,16 +773,18 @@ pub trait AttributeProtocol {
775773
}
776774

777775
fn class_get_item(class: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
778-
match class.payload {
779-
PyObjectPayload::Class { ref dict, .. } => dict.borrow().get(attr_name).cloned(),
780-
_ => panic!("Only classes should be in MRO!"),
776+
if let Some(ref dict) = class.dict {
777+
dict.borrow().get(attr_name).cloned()
778+
} else {
779+
panic!("Only classes should be in MRO!");
781780
}
782781
}
783782

784783
fn class_has_item(class: &PyObjectRef, attr_name: &str) -> bool {
785-
match class.payload {
786-
PyObjectPayload::Class { ref dict, .. } => dict.borrow().contains_key(attr_name),
787-
_ => panic!("Only classes should be in MRO!"),
784+
if let Some(ref dict) = class.dict {
785+
dict.borrow().contains_key(attr_name)
786+
} else {
787+
panic!("Only classes should be in MRO!");
788788
}
789789
}
790790

@@ -803,8 +803,13 @@ impl AttributeProtocol for PyObjectRef {
803803
}
804804
None
805805
}
806-
PyObjectPayload::Instance { ref dict } => dict.borrow().get(attr_name).cloned(),
807-
_ => None,
806+
_ => {
807+
if let Some(ref dict) = self.dict {
808+
dict.borrow().get(attr_name).cloned()
809+
} else {
810+
None
811+
}
812+
}
808813
}
809814
}
810815

@@ -814,8 +819,13 @@ impl AttributeProtocol for PyObjectRef {
814819
PyObjectPayload::Class { ref mro, .. } => {
815820
class_has_item(self, attr_name) || mro.iter().any(|d| class_has_item(d, attr_name))
816821
}
817-
PyObjectPayload::Instance { ref dict } => dict.borrow().contains_key(attr_name),
818-
_ => false,
822+
_ => {
823+
if let Some(ref dict) = self.dict {
824+
dict.borrow().contains_key(attr_name)
825+
} else {
826+
false
827+
}
828+
}
819829
}
820830
}
821831
}
@@ -1485,7 +1495,6 @@ pub enum PyObjectPayload {
14851495
NoPayload,
14861496
Class {
14871497
name: String,
1488-
dict: RefCell<PyAttributes>,
14891498
mro: Vec<PyObjectRef>,
14901499
},
14911500
Set {
@@ -1494,9 +1503,6 @@ pub enum PyObjectPayload {
14941503
WeakRef {
14951504
referent: PyObjectWeakRef,
14961505
},
1497-
Instance {
1498-
dict: RefCell<PyAttributes>,
1499-
},
15001506
RustFunction {
15011507
function: PyNativeFunc,
15021508
},
@@ -1536,7 +1542,6 @@ impl fmt::Debug for PyObjectPayload {
15361542
PyObjectPayload::Module { .. } => write!(f, "module"),
15371543
PyObjectPayload::NoPayload => write!(f, "NoPayload"),
15381544
PyObjectPayload::Class { ref name, .. } => write!(f, "class {:?}", name),
1539-
PyObjectPayload::Instance { .. } => write!(f, "instance"),
15401545
PyObjectPayload::RustFunction { .. } => write!(f, "rust function"),
15411546
PyObjectPayload::Frame { .. } => write!(f, "frame"),
15421547
PyObjectPayload::AnyRustValue { .. } => write!(f, "some rust value"),

vm/src/vm.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,6 @@ impl VirtualMachine {
330330
ref function,
331331
ref object,
332332
} => self.invoke(function.clone(), args.insert(object.clone())),
333-
PyObjectPayload::Instance { .. } => {
334-
self.call_method_pyargs(&func_ref, "__call__", args)
335-
}
336333
ref payload => {
337334
// TODO: is it safe to just invoke __call__ otherwise?
338335
trace!("invoke __call__ for: {:?}", payload);

0 commit comments

Comments
 (0)