Skip to content

Commit 5b13848

Browse files
committed
Move attributes dictionary to PyObject.
1 parent 303f9b9 commit 5b13848

File tree

5 files changed

+57
-51
lines changed

5 files changed

+57
-51
lines changed

vm/src/obj/objdict.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, dict_type:
342342
unsafe {
343343
(*ptr).payload = PyObjectPayload::Class {
344344
name: String::from("dict"),
345-
dict: RefCell::new(HashMap::new()),
346345
mro: vec![object_type],
347346
};
347+
(*ptr).dict = Some(RefCell::new(HashMap::new()));
348348
(*ptr).typ = Some(type_type.clone());
349349
}
350350
}

vm/src/obj/objobject.rs

Lines changed: 12 additions & 13 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

@@ -191,15 +191,14 @@ fn object_init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
191191
}
192192

193193
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
194-
match args.args[0].payload {
195-
PyObjectPayload::Class { ref dict, .. } | PyObjectPayload::Instance { ref dict, .. } => {
196-
let new_dict = vm.new_dict();
197-
for (attr, value) in dict.borrow().iter() {
198-
new_dict.set_item(&vm.ctx, &attr, value.clone());
199-
}
200-
Ok(new_dict)
194+
if let Some(ref dict) = args.args[0].dict {
195+
let new_dict = vm.new_dict();
196+
for (attr, value) in dict.borrow().iter() {
197+
new_dict.set_item(&vm.ctx, &attr, value.clone());
201198
}
202-
_ => Err(vm.new_type_error("TypeError: no dictionary.".to_string())),
199+
Ok(new_dict)
200+
} else {
201+
Err(vm.new_type_error("TypeError: no dictionary.".to_string()))
203202
}
204203
}
205204

@@ -245,7 +244,7 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
245244
let mut attributes = objtype::get_attributes(&obj.typ());
246245

247246
// Get instance attributes:
248-
if let PyObjectPayload::Instance { dict } = &obj.payload {
247+
if let Some(dict) = &obj.dict {
249248
for (name, value) in dict.borrow().iter() {
250249
attributes.insert(name.to_string(), value.clone());
251250
}

vm/src/obj/objtype.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ pub fn create_type(type_type: PyObjectRef, object_type: PyObjectRef, _dict_type:
1818
unsafe {
1919
(*ptr).payload = PyObjectPayload::Class {
2020
name: String::from("type"),
21-
dict: RefCell::new(PyAttributes::new()),
2221
mro: vec![object_type],
2322
};
23+
(*ptr).dict = Some(RefCell::new(PyAttributes::new()));
2424
(*ptr).typ = Some(type_type);
2525
}
2626
}
@@ -253,7 +253,7 @@ pub fn get_attributes(obj: &PyObjectRef) -> PyAttributes {
253253
let mut base_classes = _mro(obj.clone()).expect("Type get_attributes on non-type");
254254
base_classes.reverse();
255255
for bc in base_classes {
256-
if let PyObjectPayload::Class { dict, .. } = &bc.payload {
256+
if let Some(ref dict) = &bc.dict {
257257
for (name, value) in dict.borrow().iter() {
258258
attributes.insert(name.to_string(), value.clone());
259259
}
@@ -318,14 +318,15 @@ pub fn new(
318318
) -> PyResult {
319319
let mros = bases.into_iter().map(|x| _mro(x).unwrap()).collect();
320320
let mro = linearise_mro(mros).unwrap();
321-
Ok(PyObject::new(
322-
PyObjectPayload::Class {
321+
Ok(PyObject {
322+
payload: PyObjectPayload::Class {
323323
name: String::from(name),
324-
dict: RefCell::new(dict),
325324
mro,
326325
},
327-
typ,
328-
))
326+
dict: Some(RefCell::new(dict)),
327+
typ: Some(typ),
328+
}
329+
.into_ref())
329330
}
330331

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

vm/src/pyobject.rs

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -672,12 +672,14 @@ impl PyContext {
672672
} else {
673673
PyAttributes::new()
674674
};
675-
PyObject::new(
676-
PyObjectPayload::Instance {
677-
dict: RefCell::new(dict),
675+
PyObject {
676+
payload: PyObjectPayload::AnyRustValue {
677+
value: Box::new(()),
678678
},
679-
class,
680-
)
679+
typ: Some(class),
680+
dict: Some(RefCell::new(dict)),
681+
}
682+
.into_ref()
681683
}
682684

683685
// Item set/get:
@@ -698,14 +700,12 @@ impl PyContext {
698700
}
699701

700702
pub fn set_attr(&self, obj: &PyObjectRef, attr_name: &str, value: PyObjectRef) {
701-
match obj.payload {
702-
PyObjectPayload::Module { ref scope, .. } => {
703-
scope.locals.set_item(self, attr_name, value)
704-
}
705-
PyObjectPayload::Instance { ref dict } | PyObjectPayload::Class { ref dict, .. } => {
706-
dict.borrow_mut().insert(attr_name.to_string(), value);
707-
}
708-
ref payload => unimplemented!("set_attr unimplemented for: {:?}", payload),
703+
if let PyObjectPayload::Module { ref scope, .. } = obj.payload {
704+
scope.locals.set_item(self, attr_name, value)
705+
} else if let Some(ref dict) = obj.dict {
706+
dict.borrow_mut().insert(attr_name.to_string(), value);
707+
} else {
708+
unimplemented!("set_attr unimplemented for: {:?}", obj);
709709
};
710710
}
711711

@@ -744,7 +744,7 @@ impl Default for PyContext {
744744
pub struct PyObject {
745745
pub payload: PyObjectPayload,
746746
pub typ: Option<PyObjectRef>,
747-
pub dict: Option<HashMap<String, PyObjectRef>>, // __dict__ member
747+
pub dict: Option<RefCell<PyAttributes>>, // __dict__ member
748748
}
749749

750750
pub trait IdProtocol {
@@ -791,16 +791,18 @@ pub trait AttributeProtocol {
791791
}
792792

793793
fn class_get_item(class: &PyObjectRef, attr_name: &str) -> Option<PyObjectRef> {
794-
match class.payload {
795-
PyObjectPayload::Class { ref dict, .. } => dict.borrow().get(attr_name).cloned(),
796-
_ => panic!("Only classes should be in MRO!"),
794+
if let Some(ref dict) = class.dict {
795+
dict.borrow().get(attr_name).cloned()
796+
} else {
797+
panic!("Only classes should be in MRO!");
797798
}
798799
}
799800

800801
fn class_has_item(class: &PyObjectRef, attr_name: &str) -> bool {
801-
match class.payload {
802-
PyObjectPayload::Class { ref dict, .. } => dict.borrow().contains_key(attr_name),
803-
_ => panic!("Only classes should be in MRO!"),
802+
if let Some(ref dict) = class.dict {
803+
dict.borrow().contains_key(attr_name)
804+
} else {
805+
panic!("Only classes should be in MRO!");
804806
}
805807
}
806808

@@ -819,8 +821,13 @@ impl AttributeProtocol for PyObjectRef {
819821
}
820822
None
821823
}
822-
PyObjectPayload::Instance { ref dict } => dict.borrow().get(attr_name).cloned(),
823-
_ => None,
824+
_ => {
825+
if let Some(ref dict) = self.dict {
826+
dict.borrow().get(attr_name).cloned()
827+
} else {
828+
None
829+
}
830+
}
824831
}
825832
}
826833

@@ -830,8 +837,13 @@ impl AttributeProtocol for PyObjectRef {
830837
PyObjectPayload::Class { ref mro, .. } => {
831838
class_has_item(self, attr_name) || mro.iter().any(|d| class_has_item(d, attr_name))
832839
}
833-
PyObjectPayload::Instance { ref dict } => dict.borrow().contains_key(attr_name),
834-
_ => false,
840+
_ => {
841+
if let Some(ref dict) = self.dict {
842+
dict.borrow().contains_key(attr_name)
843+
} else {
844+
false
845+
}
846+
}
835847
}
836848
}
837849
}
@@ -1517,15 +1529,11 @@ pub enum PyObjectPayload {
15171529
},
15181530
Class {
15191531
name: String,
1520-
dict: RefCell<PyAttributes>,
15211532
mro: Vec<PyObjectRef>,
15221533
},
15231534
WeakRef {
15241535
referent: PyObjectWeakRef,
15251536
},
1526-
Instance {
1527-
dict: RefCell<PyAttributes>,
1528-
},
15291537
RustFunction {
15301538
function: PyNativeFunc,
15311539
},
@@ -1563,7 +1571,6 @@ impl fmt::Debug for PyObjectPayload {
15631571
} => write!(f, "bound-method: {:?} of {:?}", function, object),
15641572
PyObjectPayload::Module { .. } => write!(f, "module"),
15651573
PyObjectPayload::Class { ref name, .. } => write!(f, "class {:?}", name),
1566-
PyObjectPayload::Instance { .. } => write!(f, "instance"),
15671574
PyObjectPayload::RustFunction { .. } => write!(f, "rust function"),
15681575
PyObjectPayload::Frame { .. } => write!(f, "frame"),
15691576
PyObjectPayload::AnyRustValue { .. } => write!(f, "some rust value"),

vm/src/vm.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ impl VirtualMachine {
303303
ref function,
304304
ref object,
305305
} => self.invoke(function.clone(), args.insert(object.clone())),
306-
PyObjectPayload::Instance { .. } => self.call_method(&func_ref, "__call__", args),
307306
ref payload => {
308307
// TODO: is it safe to just invoke __call__ otherwise?
309308
trace!("invoke __call__ for: {:?}", payload);

0 commit comments

Comments
 (0)