Skip to content

Commit 94c80c5

Browse files
committed
Separate fallback queueing from subclass priority in op dispatch
1 parent 131e5aa commit 94c80c5

File tree

1 file changed

+34
-30
lines changed

1 file changed

+34
-30
lines changed

crates/vm/src/vm/vm_ops.rs

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ use num_traits::ToPrimitive;
1313
fn method_is_overloaded(
1414
class_a: &Py<PyType>,
1515
class_b: &Py<PyType>,
16-
rop_name: &'static PyStrInterned,
16+
rop_name: Option<&'static PyStrInterned>,
1717
vm: &VirtualMachine,
18-
) -> bool {
18+
) -> PyResult<bool> {
19+
let Some(rop_name) = rop_name else {
20+
return Ok(false);
21+
};
1922
let Some(method_b) = class_b.get_attr(rop_name) else {
20-
return false;
23+
return Ok(false);
2124
};
22-
class_a
23-
.get_attr(rop_name)
24-
.is_none_or(|method_a| !vm.identical_or_equal(&method_a, &method_b).unwrap_or(false))
25+
class_a.get_attr(rop_name).map_or(Ok(true), |method_a| {
26+
vm.identical_or_equal(&method_a, &method_b)
27+
.map(|eq| !eq)
28+
})
2529
}
2630

2731
macro_rules! binary_func {
@@ -177,29 +181,29 @@ impl VirtualMachine {
177181

178182
// Number slots are inherited, direct access is O(1)
179183
let slot_a = class_a.slots.as_number.left_binary_op(op_slot);
184+
let slot_a_addr = slot_a.map(|x| x as usize);
180185
let mut slot_b = None;
186+
let left_b_addr;
181187

182188
if !class_a.is(class_b) {
183189
let slot_bb = class_b.slots.as_number.right_binary_op(op_slot);
184-
if slot_a.map(|x| x as usize)
185-
!= class_b
186-
.slots
187-
.as_number
188-
.left_binary_op(op_slot)
189-
.map(|x| x as usize)
190-
{
191-
slot_b = slot_bb;
192-
} else if class_b.fast_issubclass(class_a)
193-
&& let Some(rop_name) = op_slot.right_method_name(self)
194-
&& method_is_overloaded(class_a, class_b, rop_name, self)
195-
{
190+
if slot_bb.map(|x| x as usize) != slot_a_addr {
196191
slot_b = slot_bb;
197192
}
193+
left_b_addr = class_b
194+
.slots
195+
.as_number
196+
.left_binary_op(op_slot)
197+
.map(|x| x as usize);
198+
} else {
199+
left_b_addr = slot_a_addr;
198200
}
199201

200202
if let Some(slot_a) = slot_a {
201203
if let Some(slot_bb) = slot_b
202204
&& class_b.fast_issubclass(class_a)
205+
&& (slot_a_addr != left_b_addr
206+
|| method_is_overloaded(class_a, class_b, op_slot.right_method_name(self), self)?)
203207
{
204208
let ret = slot_bb(a, b, self)?;
205209
if !ret.is(&self.ctx.not_implemented) {
@@ -295,29 +299,29 @@ impl VirtualMachine {
295299

296300
// Number slots are inherited, direct access is O(1)
297301
let slot_a = class_a.slots.as_number.left_ternary_op(op_slot);
302+
let slot_a_addr = slot_a.map(|x| x as usize);
298303
let mut slot_b = None;
304+
let left_b_addr;
299305

300306
if !class_a.is(class_b) {
301307
let slot_bb = class_b.slots.as_number.right_ternary_op(op_slot);
302-
if slot_a.map(|x| x as usize)
303-
!= class_b
304-
.slots
305-
.as_number
306-
.left_ternary_op(op_slot)
307-
.map(|x| x as usize)
308-
{
309-
slot_b = slot_bb;
310-
} else if class_b.fast_issubclass(class_a)
311-
&& let Some(rop_name) = op_slot.right_method_name(self)
312-
&& method_is_overloaded(class_a, class_b, rop_name, self)
313-
{
308+
if slot_bb.map(|x| x as usize) != slot_a_addr {
314309
slot_b = slot_bb;
315310
}
311+
left_b_addr = class_b
312+
.slots
313+
.as_number
314+
.left_ternary_op(op_slot)
315+
.map(|x| x as usize);
316+
} else {
317+
left_b_addr = slot_a_addr;
316318
}
317319

318320
if let Some(slot_a) = slot_a {
319321
if let Some(slot_bb) = slot_b
320322
&& class_b.fast_issubclass(class_a)
323+
&& (slot_a_addr != left_b_addr
324+
|| method_is_overloaded(class_a, class_b, op_slot.right_method_name(self), self)?)
321325
{
322326
let ret = slot_bb(a, b, c, self)?;
323327
if !ret.is(&self.ctx.not_implemented) {

0 commit comments

Comments
 (0)