Skip to content

Commit 770f166

Browse files
committed
Fix slot call deadlock
1 parent 60598b6 commit 770f166

File tree

7 files changed

+23
-21
lines changed

7 files changed

+23
-21
lines changed

vm/src/builtins/type.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -667,11 +667,12 @@ impl GetAttr for PyType {
667667

668668
if let Some(ref attr) = mcl_attr {
669669
let attr_class = attr.class();
670-
if attr_class
670+
let has_descr_set = attr_class
671671
.mro_find_map(|cls| cls.slots.descr_set.load())
672-
.is_some()
673-
{
674-
if let Some(descr_get) = attr_class.mro_find_map(|cls| cls.slots.descr_get.load()) {
672+
.is_some();
673+
if has_descr_set {
674+
let descr_get = attr_class.mro_find_map(|cls| cls.slots.descr_get.load());
675+
if let Some(descr_get) = descr_get {
675676
let mcl = mcl.into_owned().into();
676677
return descr_get(attr.clone(), Some(zelf.to_owned().into()), Some(mcl), vm);
677678
}
@@ -681,7 +682,8 @@ impl GetAttr for PyType {
681682
let zelf_attr = zelf.get_attr(name);
682683

683684
if let Some(ref attr) = zelf_attr {
684-
if let Some(descr_get) = attr.class().mro_find_map(|cls| cls.slots.descr_get.load()) {
685+
let descr_get = attr.class().mro_find_map(|cls| cls.slots.descr_get.load());
686+
if let Some(descr_get) = descr_get {
685687
drop(mcl);
686688
return descr_get(attr.clone(), None, Some(zelf.to_owned().into()), vm);
687689
}
@@ -745,7 +747,8 @@ impl Callable for PyType {
745747
return Ok(obj);
746748
}
747749

748-
if let Some(init_method) = obj.class().mro_find_map(|cls| cls.slots.init.load()) {
750+
let init = obj.class().mro_find_map(|cls| cls.slots.init.load());
751+
if let Some(init_method) = init {
749752
init_method(obj.clone(), args, vm)?;
750753
}
751754
Ok(obj)

vm/src/function/protocol.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,14 @@ where
8484
T: TryFromObject,
8585
{
8686
fn try_from_object(vm: &VirtualMachine, obj: PyObjectRef) -> PyResult<Self> {
87-
let iterfn;
88-
{
87+
let iterfn = {
8988
let cls = obj.class();
90-
iterfn = cls.mro_find_map(|x| x.slots.iter.load());
89+
let iterfn = cls.mro_find_map(|x| x.slots.iter.load());
9190
if iterfn.is_none() && !cls.has_attr(identifier!(vm, __getitem__)) {
9291
return Err(vm.new_type_error(format!("'{}' object is not iterable", cls.name())));
9392
}
94-
}
93+
iterfn
94+
};
9595
Ok(Self {
9696
iterable: obj,
9797
iterfn,

vm/src/object/core.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,8 @@ impl PyObject {
762762
}
763763

764764
// CPython-compatible drop implementation
765-
if let Some(slot_del) = self.class().mro_find_map(|cls| cls.slots.del.load()) {
765+
let del = self.class().mro_find_map(|cls| cls.slots.del.load());
766+
if let Some(slot_del) = del {
766767
call_slot_del(self, slot_del)?;
767768
}
768769
if let Some(wrl) = self.weak_ref_list() {

vm/src/protocol/buffer.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ impl PyBuffer {
140140
impl TryFromBorrowedObject for PyBuffer {
141141
fn try_from_borrowed_object(vm: &VirtualMachine, obj: &PyObject) -> PyResult<Self> {
142142
let cls = obj.class();
143-
if let Some(f) = cls.mro_find_map(|cls| cls.slots.as_buffer) {
143+
let as_buffer = cls.mro_find_map(|cls| cls.slots.as_buffer);
144+
if let Some(f) = as_buffer {
144145
return f(obj, vm);
145146
}
146147
Err(vm.new_type_error(format!(

vm/src/protocol/mapping.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,8 @@ impl PyMapping<'_> {
146146
}
147147

148148
pub fn find_methods(obj: &PyObject, vm: &VirtualMachine) -> Option<&'static PyMappingMethods> {
149-
if let Some(f) = obj.class().mro_find_map(|cls| cls.slots.as_mapping.load()) {
150-
Some(f(obj, vm))
151-
} else {
152-
None
153-
}
149+
let as_mapping = obj.class().mro_find_map(|cls| cls.slots.as_mapping.load());
150+
as_mapping.map(|f| f(obj, vm))
154151
}
155152

156153
pub fn length_opt(&self, vm: &VirtualMachine) -> Option<PyResult<usize>> {

vm/src/protocol/number.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,8 @@ impl<'a> PyNumber<'a> {
163163

164164
impl PyNumber<'_> {
165165
pub fn find_methods(obj: &PyObject, vm: &VirtualMachine) -> Option<&'static PyNumberMethods> {
166-
obj.class()
167-
.mro_find_map(|x| x.slots.as_number.load())
168-
.map(|f| f(obj, vm))
166+
let as_number = obj.class().mro_find_map(|x| x.slots.as_number.load());
167+
as_number.map(|f| f(obj, vm))
169168
}
170169

171170
pub fn methods(&self) -> &'static PyNumberMethods {

vm/src/protocol/sequence.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ impl PySequence<'_> {
145145
pub fn find_methods(obj: &PyObject, vm: &VirtualMachine) -> Option<&'static PySequenceMethods> {
146146
let cls = obj.class();
147147
if !cls.is(vm.ctx.types.dict_type) {
148-
if let Some(f) = cls.mro_find_map(|x| x.slots.as_sequence.load()) {
148+
let as_sequence = cls.mro_find_map(|x| x.slots.as_sequence.load());
149+
if let Some(f) = as_sequence {
149150
return Some(f(obj, vm));
150151
}
151152
}

0 commit comments

Comments
 (0)