Skip to content

Commit 7df0acd

Browse files
committed
share comparisonop between bytecode and vm
1 parent 53d835f commit 7df0acd

File tree

7 files changed

+83
-82
lines changed

7 files changed

+83
-82
lines changed

bytecode/src/lib.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ pub enum Instruction {
264264
op: TestOperator,
265265
},
266266
CompareOperation {
267-
op: CompareOperator,
267+
op: ComparisonOperator,
268268
},
269269
Pop,
270270
Rotate2,
@@ -584,17 +584,19 @@ impl<C: Constant> BorrowedConstant<'_, C> {
584584
}
585585

586586
/// The possible comparison operators
587-
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
588-
pub enum CompareOperator {
589-
Greater,
590-
GreaterOrEqual,
591-
Less,
592-
LessOrEqual,
593-
Equal,
594-
NotEqual,
587+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
588+
pub enum ComparisonOperator {
589+
// be intentional with bits so that we can do eval_ord with just a bitwise and
590+
// bits: | Equal | Greater | Less |
591+
Less = 0b001,
592+
Greater = 0b010,
593+
NotEqual = 0b011,
594+
Equal = 0b100,
595+
LessOrEqual = 0b101,
596+
GreaterOrEqual = 0b110,
595597
}
596598

597-
#[derive(Debug, Copy, Clone, PartialEq, Serialize, Deserialize)]
599+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
598600
pub enum TestOperator {
599601
In,
600602
NotIn,

compiler/src/compile.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,22 +1469,22 @@ impl Compiler {
14691469

14701470
let compile_cmpop = |op: &ast::Cmpop| match op {
14711471
ast::Cmpop::Eq => Instruction::CompareOperation {
1472-
op: bytecode::CompareOperator::Equal,
1472+
op: bytecode::ComparisonOperator::Equal,
14731473
},
14741474
ast::Cmpop::NotEq => Instruction::CompareOperation {
1475-
op: bytecode::CompareOperator::NotEqual,
1475+
op: bytecode::ComparisonOperator::NotEqual,
14761476
},
14771477
ast::Cmpop::Lt => Instruction::CompareOperation {
1478-
op: bytecode::CompareOperator::Less,
1478+
op: bytecode::ComparisonOperator::Less,
14791479
},
14801480
ast::Cmpop::LtE => Instruction::CompareOperation {
1481-
op: bytecode::CompareOperator::LessOrEqual,
1481+
op: bytecode::ComparisonOperator::LessOrEqual,
14821482
},
14831483
ast::Cmpop::Gt => Instruction::CompareOperation {
1484-
op: bytecode::CompareOperator::Greater,
1484+
op: bytecode::ComparisonOperator::Greater,
14851485
},
14861486
ast::Cmpop::GtE => Instruction::CompareOperation {
1487-
op: bytecode::CompareOperator::GreaterOrEqual,
1487+
op: bytecode::ComparisonOperator::GreaterOrEqual,
14881488
},
14891489
ast::Cmpop::In => Instruction::TestOperation {
14901490
op: bytecode::TestOperator::In,

jit/src/instructions.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use cranelift::prelude::*;
22
use num_traits::cast::ToPrimitive;
33
use rustpython_bytecode::{
4-
self as bytecode, BinaryOperator, BorrowedConstant, CodeObject, CompareOperator, Instruction,
5-
Label, UnaryOperator,
4+
self as bytecode, BinaryOperator, BorrowedConstant, CodeObject, ComparisonOperator,
5+
Instruction, Label, UnaryOperator,
66
};
77
use std::collections::HashMap;
88

@@ -260,13 +260,12 @@ impl<'a, 'b> FunctionCompiler<'a, 'b> {
260260
match (a.ty, b.ty) {
261261
(JitType::Int, JitType::Int) => {
262262
let cond = match op {
263-
CompareOperator::Equal => IntCC::Equal,
264-
CompareOperator::NotEqual => IntCC::NotEqual,
265-
CompareOperator::Less => IntCC::SignedLessThan,
266-
CompareOperator::LessOrEqual => IntCC::SignedLessThanOrEqual,
267-
CompareOperator::Greater => IntCC::SignedGreaterThan,
268-
CompareOperator::GreaterOrEqual => IntCC::SignedLessThanOrEqual,
269-
_ => return Err(JitCompileError::NotSupported),
263+
ComparisonOperator::Equal => IntCC::Equal,
264+
ComparisonOperator::NotEqual => IntCC::NotEqual,
265+
ComparisonOperator::Less => IntCC::SignedLessThan,
266+
ComparisonOperator::LessOrEqual => IntCC::SignedLessThanOrEqual,
267+
ComparisonOperator::Greater => IntCC::SignedGreaterThan,
268+
ComparisonOperator::GreaterOrEqual => IntCC::SignedLessThanOrEqual,
270269
};
271270

272271
let val = self.builder.ins().icmp(cond, a.val, b.val);

stdlib/src/bisect.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ pub(crate) use _bisect::make_module;
33
#[pymodule]
44
mod _bisect {
55
use crate::vm::{
6-
function::OptionalArg, types::PyComparisonOp::Lt, PyObjectRef, PyResult, VirtualMachine,
6+
function::OptionalArg, types::PyComparisonOp, PyObjectRef, PyResult, VirtualMachine,
77
};
88

99
#[derive(FromArgs)]
@@ -74,7 +74,9 @@ mod _bisect {
7474
while lo < hi {
7575
// Handles issue 13496.
7676
let mid = (lo + hi) / 2;
77-
if a.get_item(mid, vm)?.rich_compare_bool(&x, Lt, vm)? {
77+
if a.get_item(mid, vm)?
78+
.rich_compare_bool(&x, PyComparisonOp::Lt, vm)?
79+
{
7880
lo = mid + 1;
7981
} else {
8082
hi = mid;
@@ -102,7 +104,7 @@ mod _bisect {
102104
while lo < hi {
103105
// Handles issue 13496.
104106
let mid = (lo + hi) / 2;
105-
if x.rich_compare_bool(&*a.get_item(mid, vm)?, Lt, vm)? {
107+
if x.rich_compare_bool(&*a.get_item(mid, vm)?, PyComparisonOp::Lt, vm)? {
106108
hi = mid;
107109
} else {
108110
lo = mid + 1;

vm/src/frame.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -720,7 +720,7 @@ impl ExecutingFrame<'_> {
720720
bytecode::Instruction::DeleteAttr { idx } => self.delete_attr(vm, *idx),
721721
bytecode::Instruction::UnaryOperation { ref op } => self.execute_unop(vm, op),
722722
bytecode::Instruction::TestOperation { ref op } => self.execute_test(vm, op),
723-
bytecode::Instruction::CompareOperation { ref op } => self.execute_compare(vm, op),
723+
bytecode::Instruction::CompareOperation { op } => self.execute_compare(vm, *op),
724724
bytecode::Instruction::ReturnValue => {
725725
let value = self.pop_value();
726726
self.unwind_blocks(vm, UnwindReason::Returning { value })
@@ -1725,18 +1725,11 @@ impl ExecutingFrame<'_> {
17251725
fn execute_compare(
17261726
&mut self,
17271727
vm: &VirtualMachine,
1728-
op: &bytecode::CompareOperator,
1728+
op: bytecode::ComparisonOperator,
17291729
) -> FrameResult {
17301730
let b = self.pop_value();
17311731
let a = self.pop_value();
1732-
let op = match *op {
1733-
bytecode::CompareOperator::Equal => PyComparisonOp::Eq,
1734-
bytecode::CompareOperator::NotEqual => PyComparisonOp::Ne,
1735-
bytecode::CompareOperator::Less => PyComparisonOp::Lt,
1736-
bytecode::CompareOperator::LessOrEqual => PyComparisonOp::Le,
1737-
bytecode::CompareOperator::Greater => PyComparisonOp::Gt,
1738-
bytecode::CompareOperator::GreaterOrEqual => PyComparisonOp::Ge,
1739-
};
1732+
let op = PyComparisonOp::from(op);
17401733
let value = a.rich_compare(b, op, vm)?;
17411734
self.push_value(value);
17421735
Ok(None)

vm/src/stdlib/operator.rs

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,47 +16,44 @@ mod _operator {
1616
function::{ArgBytesLike, FuncArgs, KwArgs, OptionalArg},
1717
protocol::PyIter,
1818
recursion::ReprGuard,
19-
types::{
20-
Callable, Constructor,
21-
PyComparisonOp::{Eq, Ge, Gt, Le, Lt, Ne},
22-
},
19+
types::{Callable, Constructor, PyComparisonOp},
2320
AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, VirtualMachine,
2421
};
2522

2623
/// Same as a < b.
2724
#[pyfunction]
2825
fn lt(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
29-
a.rich_compare(b, Lt, vm)
26+
a.rich_compare(b, PyComparisonOp::Lt, vm)
3027
}
3128

3229
/// Same as a <= b.
3330
#[pyfunction]
3431
fn le(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
35-
a.rich_compare(b, Le, vm)
32+
a.rich_compare(b, PyComparisonOp::Le, vm)
3633
}
3734

3835
/// Same as a > b.
3936
#[pyfunction]
4037
fn gt(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
41-
a.rich_compare(b, Gt, vm)
38+
a.rich_compare(b, PyComparisonOp::Gt, vm)
4239
}
4340

4441
/// Same as a >= b.
4542
#[pyfunction]
4643
fn ge(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
47-
a.rich_compare(b, Ge, vm)
44+
a.rich_compare(b, PyComparisonOp::Ge, vm)
4845
}
4946

5047
/// Same as a == b.
5148
#[pyfunction]
5249
fn eq(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
53-
a.rich_compare(b, Eq, vm)
50+
a.rich_compare(b, PyComparisonOp::Eq, vm)
5451
}
5552

5653
/// Same as a != b.
5754
#[pyfunction]
5855
fn ne(a: PyObjectRef, b: PyObjectRef, vm: &VirtualMachine) -> PyResult {
59-
a.rich_compare(b, Ne, vm)
56+
a.rich_compare(b, PyComparisonOp::Ne, vm)
6057
}
6158

6259
/// Same as not a.

vm/src/types/slot.rs

Lines changed: 42 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::common::{hash::PyHash, lock::PyRwLock};
22
use crate::{
33
builtins::{PyInt, PyStrRef, PyType, PyTypeRef},
4+
bytecode::ComparisonOperator,
45
convert::{ToPyObject, ToPyResult},
56
function::Either,
67
function::{FromArgs, FuncArgs, OptionalArg, PyComparisonValue},
@@ -687,18 +688,25 @@ pub trait Comparable: PyPayload {
687688
}
688689

689690
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
690-
pub enum PyComparisonOp {
691-
// be intentional with bits so that we can do eval_ord with just a bitwise and
692-
// bits: | Equal | Greater | Less |
693-
Lt = 0b001,
694-
Gt = 0b010,
695-
Ne = 0b011,
696-
Eq = 0b100,
697-
Le = 0b101,
698-
Ge = 0b110,
699-
}
700-
701-
use PyComparisonOp::*;
691+
#[repr(transparent)]
692+
pub struct PyComparisonOp(ComparisonOperator);
693+
694+
impl From<ComparisonOperator> for PyComparisonOp {
695+
fn from(op: ComparisonOperator) -> Self {
696+
Self(op)
697+
}
698+
}
699+
700+
#[allow(non_upper_case_globals)]
701+
impl PyComparisonOp {
702+
pub const Lt: Self = Self(ComparisonOperator::Less);
703+
pub const Gt: Self = Self(ComparisonOperator::Greater);
704+
pub const Ne: Self = Self(ComparisonOperator::NotEqual);
705+
pub const Eq: Self = Self(ComparisonOperator::Equal);
706+
pub const Le: Self = Self(ComparisonOperator::LessOrEqual);
707+
pub const Ge: Self = Self(ComparisonOperator::GreaterOrEqual);
708+
}
709+
702710
impl PyComparisonOp {
703711
pub fn eq_only(
704712
self,
@@ -713,43 +721,43 @@ impl PyComparisonOp {
713721

714722
pub fn eval_ord(self, ord: Ordering) -> bool {
715723
let bit = match ord {
716-
Ordering::Less => Lt,
717-
Ordering::Equal => Eq,
718-
Ordering::Greater => Gt,
724+
Ordering::Less => Self::Lt,
725+
Ordering::Equal => Self::Eq,
726+
Ordering::Greater => Self::Gt,
719727
};
720-
self as u8 & bit as u8 != 0
728+
self.0 as u8 & bit.0 as u8 != 0
721729
}
722730

723731
pub fn swapped(self) -> Self {
724732
match self {
725-
Lt => Gt,
726-
Le => Ge,
727-
Eq => Eq,
728-
Ne => Ne,
729-
Ge => Le,
730-
Gt => Lt,
733+
Self::Lt => Self::Gt,
734+
Self::Le => Self::Ge,
735+
Self::Eq => Self::Eq,
736+
Self::Ne => Self::Ne,
737+
Self::Ge => Self::Le,
738+
Self::Gt => Self::Lt,
731739
}
732740
}
733741

734742
pub fn method_name(self) -> &'static str {
735743
match self {
736-
Lt => "__lt__",
737-
Le => "__le__",
738-
Eq => "__eq__",
739-
Ne => "__ne__",
740-
Ge => "__ge__",
741-
Gt => "__gt__",
744+
Self::Lt => "__lt__",
745+
Self::Le => "__le__",
746+
Self::Eq => "__eq__",
747+
Self::Ne => "__ne__",
748+
Self::Ge => "__ge__",
749+
Self::Gt => "__gt__",
742750
}
743751
}
744752

745753
pub fn operator_token(self) -> &'static str {
746754
match self {
747-
Lt => "<",
748-
Le => "<=",
749-
Eq => "==",
750-
Ne => "!=",
751-
Ge => ">=",
752-
Gt => ">",
755+
Self::Lt => "<",
756+
Self::Le => "<=",
757+
Self::Eq => "==",
758+
Self::Ne => "!=",
759+
Self::Ge => ">=",
760+
Self::Gt => ">",
753761
}
754762
}
755763

0 commit comments

Comments
 (0)