diff --git a/vm/src/obj/objdict.rs b/vm/src/obj/objdict.rs index 6c159ab933..a5330bdbcf 100644 --- a/vm/src/obj/objdict.rs +++ b/vm/src/obj/objdict.rs @@ -1,4 +1,4 @@ -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::fmt; use super::objiter; @@ -9,7 +9,7 @@ use crate::exceptions::PyBaseExceptionRef; use crate::function::{KwArgs, OptionalArg, PyFuncArgs}; use crate::pyobject::{ IdProtocol, IntoPyObject, ItemProtocol, PyAttributes, PyClassImpl, PyContext, PyIterable, - PyObjectRef, PyRef, PyResult, PyValue, + PyObjectRef, PyRef, PyResult, PyValue, ThreadSafe, }; use crate::vm::{ReprGuard, VirtualMachine}; @@ -20,9 +20,10 @@ pub type DictContentType = dictdatatype::Dict; #[pyclass] #[derive(Default)] pub struct PyDict { - entries: RefCell, + entries: DictContentType, } pub type PyDictRef = PyRef; +impl ThreadSafe for PyDict {} impl fmt::Debug for PyDict { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -43,7 +44,7 @@ impl PyDictRef { #[pyslot] fn tp_new(class: PyClassRef, _args: PyFuncArgs, vm: &VirtualMachine) -> PyResult { PyDict { - entries: RefCell::new(DictContentType::default()), + entries: DictContentType::default(), } .into_ref_with_type(vm, class) } @@ -59,7 +60,7 @@ impl PyDictRef { } fn merge( - dict: &RefCell, + dict: &DictContentType, dict_obj: OptionalArg, kwargs: KwArgs, vm: &VirtualMachine, @@ -68,13 +69,13 @@ impl PyDictRef { let dicted: Result = dict_obj.clone().downcast(); if let Ok(dict_obj) = dicted { for (key, value) in dict_obj { - dict.borrow_mut().insert(vm, &key, value)?; + dict.insert(vm, &key, value)?; } } else if let Some(keys) = vm.get_method(dict_obj.clone(), "keys") { let keys = objiter::get_iter(vm, &vm.invoke(&keys?, vec![])?)?; while let Some(key) = objiter::get_next_object(vm, &keys)? { let val = dict_obj.get_item(&key, vm)?; - dict.borrow_mut().insert(vm, &key, val)?; + dict.insert(vm, &key, val)?; } } else { let iter = objiter::get_iter(vm, &dict_obj)?; @@ -92,14 +93,13 @@ impl PyDictRef { if objiter::get_next_object(vm, &elem_iter)?.is_some() { return Err(err(vm)); } - dict.borrow_mut().insert(vm, &key, value)?; + dict.insert(vm, &key, value)?; } } } - let mut dict_borrowed = dict.borrow_mut(); for (key, value) in kwargs.into_iter() { - dict_borrowed.insert(vm, &vm.new_str(key), value)?; + dict.insert(vm, &vm.new_str(key), value)?; } Ok(()) } @@ -111,27 +111,26 @@ impl PyDictRef { value: OptionalArg, vm: &VirtualMachine, ) -> PyResult { - let mut dict = DictContentType::default(); + let dict = DictContentType::default(); let value = value.unwrap_or_else(|| vm.ctx.none()); for elem in iterable.iter(vm)? { let elem = elem?; dict.insert(vm, &elem, value.clone())?; } - let entries = RefCell::new(dict); - PyDict { entries }.into_ref_with_type(vm, class) + PyDict { entries: dict }.into_ref_with_type(vm, class) } #[pymethod(magic)] fn bool(self) -> bool { - !self.entries.borrow().is_empty() + !self.entries.is_empty() } fn inner_eq(self, other: &PyDict, vm: &VirtualMachine) -> PyResult { - if other.entries.borrow().len() != self.entries.borrow().len() { + if other.entries.len() != self.entries.len() { return Ok(false); } for (k, v1) in self { - match other.entries.borrow().get(vm, &k)? { + match other.entries.get(vm, &k)? { Some(v2) => { if v1.is(&v2) { continue; @@ -170,12 +169,12 @@ impl PyDictRef { #[pymethod(magic)] fn len(self) -> usize { - self.entries.borrow().len() + self.entries.len() } #[pymethod(magic)] fn sizeof(self) -> usize { - size_of::() + self.entries.borrow().sizeof() + size_of::() + self.entries.sizeof() } #[pymethod(magic)] @@ -197,17 +196,17 @@ impl PyDictRef { #[pymethod(magic)] fn contains(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult { - self.entries.borrow().contains(vm, &key) + self.entries.contains(vm, &key) } #[pymethod(magic)] fn delitem(self, key: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { - self.entries.borrow_mut().delete(vm, &key) + self.entries.delete(vm, &key) } #[pymethod] fn clear(self) { - self.entries.borrow_mut().clear() + self.entries.clear() } #[pymethod(magic)] @@ -243,7 +242,7 @@ impl PyDictRef { value: PyObjectRef, vm: &VirtualMachine, ) -> PyResult<()> { - self.entries.borrow_mut().insert(vm, key, value) + self.entries.insert(vm, key, value) } #[pymethod(magic)] @@ -262,7 +261,7 @@ impl PyDictRef { key: K, vm: &VirtualMachine, ) -> PyResult> { - if let Some(value) = self.entries.borrow().get(vm, key)? { + if let Some(value) = self.entries.get(vm, key)? { return Ok(Some(value)); } @@ -281,7 +280,7 @@ impl PyDictRef { default: OptionalArg, vm: &VirtualMachine, ) -> PyResult { - match self.entries.borrow().get(vm, &key)? { + match self.entries.get(vm, &key)? { Some(value) => Ok(value), None => Ok(default.unwrap_or_else(|| vm.ctx.none())), } @@ -294,12 +293,11 @@ impl PyDictRef { default: OptionalArg, vm: &VirtualMachine, ) -> PyResult { - let mut entries = self.entries.borrow_mut(); - match entries.get(vm, &key)? { + match self.entries.get(vm, &key)? { Some(value) => Ok(value), None => { let set_value = default.unwrap_or_else(|| vm.ctx.none()); - entries.insert(vm, &key, set_value.clone())?; + self.entries.insert(vm, &key, set_value.clone())?; Ok(set_value) } } @@ -329,7 +327,7 @@ impl PyDictRef { default: OptionalArg, vm: &VirtualMachine, ) -> PyResult { - match self.entries.borrow_mut().pop(vm, &key)? { + match self.entries.pop(vm, &key)? { Some(value) => Ok(value), None => match default { OptionalArg::Present(default) => Ok(default), @@ -340,8 +338,7 @@ impl PyDictRef { #[pymethod] fn popitem(self, vm: &VirtualMachine) -> PyResult { - let mut entries = self.entries.borrow_mut(); - if let Some((key, value)) = entries.pop_front() { + if let Some((key, value)) = self.entries.pop_front() { Ok(vm.ctx.new_tuple(vec![key, value])) } else { let err_msg = vm.new_str("popitem(): dictionary is empty".to_owned()); @@ -360,14 +357,13 @@ impl PyDictRef { } pub fn from_attributes(attrs: PyAttributes, vm: &VirtualMachine) -> PyResult { - let mut dict = DictContentType::default(); + let dict = DictContentType::default(); for (key, value) in attrs { dict.insert(vm, &vm.ctx.new_str(key), value)?; } - let entries = RefCell::new(dict); - Ok(PyDict { entries }.into_ref(vm)) + Ok(PyDict { entries: dict }.into_ref(vm)) } #[pymethod(magic)] @@ -377,11 +373,11 @@ impl PyDictRef { pub fn contains_key(&self, key: T, vm: &VirtualMachine) -> bool { let key = key.into_pyobject(vm).unwrap(); - self.entries.borrow().contains(vm, &key).unwrap() + self.entries.contains(vm, &key).unwrap() } pub fn size(&self) -> dictdatatype::DictSize { - self.entries.borrow().size() + self.entries.size() } /// This function can be used to get an item without raising the @@ -487,7 +483,7 @@ impl Iterator for DictIter { type Item = (PyObjectRef, PyObjectRef); fn next(&mut self) -> Option { - match self.dict.entries.borrow().next_entry(&mut self.position) { + match self.dict.entries.next_entry(&mut self.position) { Some((key, value)) => Some((key, value)), None => None, } @@ -563,13 +559,12 @@ macro_rules! dict_iterator { #[allow(clippy::redundant_closure_call)] fn next(&self, vm: &VirtualMachine) -> PyResult { let mut position = self.position.get(); - let dict = self.dict.entries.borrow(); - if dict.has_changed_size(&self.size) { + if self.dict.entries.has_changed_size(&self.size) { return Err( vm.new_runtime_error("dictionary changed size during iteration".to_owned()) ); } - match dict.next_entry(&mut position) { + match self.dict.entries.next_entry(&mut position) { Some((key, value)) => { self.position.set(position); Ok($result_fn(vm, key, value)) @@ -585,10 +580,7 @@ macro_rules! dict_iterator { #[pymethod(name = "__length_hint__")] fn length_hint(&self) -> usize { - self.dict - .entries - .borrow() - .len_from_entry_index(self.position.get()) + self.dict.entries.len_from_entry_index(self.position.get()) } }