Skip to content

Commit 7d8f0b9

Browse files
authored
Split TestOperator instruction (RustPython#6306)
* Split `TestOperator` inatruction * Update snapshot * Set as have label
1 parent a819128 commit 7d8f0b9

File tree

4 files changed

+123
-129
lines changed

4 files changed

+123
-129
lines changed

crates/codegen/src/compile.rs

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use rustpython_compiler_core::{
3636
Mode, OneIndexed, PositionEncoding, SourceFile, SourceLocation,
3737
bytecode::{
3838
self, Arg as OpArgMarker, BinaryOperator, CodeObject, ComparisonOperator, ConstantData,
39-
Instruction, OpArg, OpArgType, UnpackExArgs,
39+
Instruction, Invert, OpArg, OpArgType, UnpackExArgs,
4040
},
4141
};
4242
use rustpython_wtf8::Wtf8Buf;
@@ -2034,20 +2034,7 @@ impl Compiler {
20342034

20352035
// Check exception type:
20362036
self.compile_expression(exc_type)?;
2037-
emit!(
2038-
self,
2039-
Instruction::TestOperation {
2040-
op: bytecode::TestOperator::ExceptionMatch,
2041-
}
2042-
);
2043-
2044-
// We cannot handle this exception type:
2045-
emit!(
2046-
self,
2047-
Instruction::PopJumpIfFalse {
2048-
target: next_handler,
2049-
}
2050-
);
2037+
emit!(self, Instruction::JumpIfNotExcMatch(next_handler));
20512038

20522039
// We have a match, store in name (except x as y)
20532040
if let Some(alias) = name {
@@ -3477,12 +3464,7 @@ impl Compiler {
34773464
// 4. Load None.
34783465
self.emit_load_const(ConstantData::None);
34793466
// 5. Compare with IS_OP 1.
3480-
emit!(
3481-
self,
3482-
Instruction::TestOperation {
3483-
op: bytecode::TestOperator::IsNot
3484-
}
3485-
);
3467+
emit!(self, Instruction::IsOp(Invert::Yes));
34863468

34873469
// At this point the TOS is a tuple of (nargs + n_attrs) attributes (or None).
34883470
pc.on_top += 1;
@@ -3648,12 +3630,8 @@ impl Compiler {
36483630

36493631
// Check if copy is None (consumes the copy like POP_JUMP_IF_NONE)
36503632
self.emit_load_const(ConstantData::None);
3651-
emit!(
3652-
self,
3653-
Instruction::TestOperation {
3654-
op: bytecode::TestOperator::IsNot
3655-
}
3656-
);
3633+
emit!(self, Instruction::IsOp(Invert::Yes));
3634+
36573635
// Stack: [subject, keys_tuple, values_tuple, bool]
36583636
self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
36593637
// Stack: [subject, keys_tuple, values_tuple]
@@ -3948,12 +3926,7 @@ impl Compiler {
39483926
Singleton::True => ConstantData::Boolean { value: true },
39493927
});
39503928
// Compare using the "Is" operator.
3951-
emit!(
3952-
self,
3953-
Instruction::TestOperation {
3954-
op: bytecode::TestOperator::Is
3955-
}
3956-
);
3929+
emit!(self, Instruction::IsOp(Invert::No));
39573930
// Jump to the failure label if the comparison is false.
39583931
self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?;
39593932
Ok(())
@@ -4082,7 +4055,6 @@ impl Compiler {
40824055
let (last_val, mid_exprs) = exprs.split_last().unwrap();
40834056

40844057
use bytecode::ComparisonOperator::*;
4085-
use bytecode::TestOperator::*;
40864058
let compile_cmpop = |c: &mut Self, op: &CmpOp| match op {
40874059
CmpOp::Eq => emit!(c, Instruction::CompareOperation { op: Equal }),
40884060
CmpOp::NotEq => emit!(c, Instruction::CompareOperation { op: NotEqual }),
@@ -4092,10 +4064,10 @@ impl Compiler {
40924064
CmpOp::GtE => {
40934065
emit!(c, Instruction::CompareOperation { op: GreaterOrEqual })
40944066
}
4095-
CmpOp::In => emit!(c, Instruction::TestOperation { op: In }),
4096-
CmpOp::NotIn => emit!(c, Instruction::TestOperation { op: NotIn }),
4097-
CmpOp::Is => emit!(c, Instruction::TestOperation { op: Is }),
4098-
CmpOp::IsNot => emit!(c, Instruction::TestOperation { op: IsNot }),
4067+
CmpOp::In => emit!(c, Instruction::ContainsOp(Invert::No)),
4068+
CmpOp::NotIn => emit!(c, Instruction::ContainsOp(Invert::Yes)),
4069+
CmpOp::Is => emit!(c, Instruction::IsOp(Invert::No)),
4070+
CmpOp::IsNot => emit!(c, Instruction::IsOp(Invert::Yes)),
40994071
};
41004072

41014073
// a == b == c == d

crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap

Lines changed: 34 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/compiler-core/src/bytecode.rs

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@ pub enum Instruction {
577577
Subscript,
578578
StoreSubscript,
579579
DeleteSubscript,
580+
/// Performs `is` comparison, or `is not` if `invert` is 1.
581+
IsOp(Arg<Invert>),
582+
/// Performs `in` comparison, or `not in` if `invert` is 1.
583+
ContainsOp(Arg<Invert>),
580584
StoreAttr {
581585
idx: Arg<NameIdx>,
582586
},
@@ -600,9 +604,6 @@ pub enum Instruction {
600604
LoadAttr {
601605
idx: Arg<NameIdx>,
602606
},
603-
TestOperation {
604-
op: Arg<TestOperator>,
605-
},
606607
CompareOperation {
607608
op: Arg<ComparisonOperator>,
608609
},
@@ -628,6 +629,10 @@ pub enum Instruction {
628629
Break {
629630
target: Arg<Label>,
630631
},
632+
/// Performs exception matching for except.
633+
/// Tests whether the STACK[-2] is an exception matching STACK[-1].
634+
/// Pops STACK[-1] and pushes the boolean result of the test.
635+
JumpIfNotExcMatch(Arg<Label>),
631636
Jump {
632637
target: Arg<Label>,
633638
},
@@ -1088,19 +1093,6 @@ op_arg_enum!(
10881093
}
10891094
);
10901095

1091-
op_arg_enum!(
1092-
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1093-
#[repr(u8)]
1094-
pub enum TestOperator {
1095-
In = 0,
1096-
NotIn = 1,
1097-
Is = 2,
1098-
IsNot = 3,
1099-
/// two exceptions that match?
1100-
ExceptionMatch = 4,
1101-
}
1102-
);
1103-
11041096
op_arg_enum!(
11051097
/// The possible Binary operators
11061098
/// # Examples
@@ -1141,6 +1133,24 @@ op_arg_enum!(
11411133
}
11421134
);
11431135

1136+
op_arg_enum!(
1137+
/// Whether or not to invert the operation.
1138+
#[repr(u8)]
1139+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
1140+
pub enum Invert {
1141+
/// ```py
1142+
/// foo is bar
1143+
/// x in lst
1144+
/// ```
1145+
No = 0,
1146+
/// ```py
1147+
/// foo is not bar
1148+
/// x not in lst
1149+
/// ```
1150+
Yes = 1,
1151+
}
1152+
);
1153+
11441154
#[derive(Copy, Clone)]
11451155
pub struct UnpackExArgs {
11461156
pub before: u8,
@@ -1395,6 +1405,7 @@ impl Instruction {
13951405
pub const fn label_arg(&self) -> Option<Arg<Label>> {
13961406
match self {
13971407
Jump { target: l }
1408+
| JumpIfNotExcMatch(l)
13981409
| PopJumpIfTrue { target: l }
13991410
| PopJumpIfFalse { target: l }
14001411
| JumpIfTrueOrPop { target: l }
@@ -1462,10 +1473,7 @@ impl Instruction {
14621473
DeleteAttr { .. } => -1,
14631474
LoadConst { .. } => 1,
14641475
UnaryOperation { .. } => 0,
1465-
BinaryOperation { .. }
1466-
| BinaryOperationInplace { .. }
1467-
| TestOperation { .. }
1468-
| CompareOperation { .. } => -1,
1476+
BinaryOperation { .. } | BinaryOperationInplace { .. } | CompareOperation { .. } => -1,
14691477
BinarySubscript => -1,
14701478
CopyItem { .. } => 1,
14711479
Pop => -1,
@@ -1508,6 +1516,8 @@ impl Instruction {
15081516
1
15091517
}
15101518
}
1519+
IsOp(_) | ContainsOp(_) => -1,
1520+
JumpIfNotExcMatch(_) => -2,
15111521
ReturnValue => -1,
15121522
ReturnConst { .. } => 0,
15131523
Resume { .. } => 0,
@@ -1654,6 +1664,9 @@ impl Instruction {
16541664
DeleteGlobal(idx) => w!(DeleteGlobal, name = idx),
16551665
DeleteDeref(idx) => w!(DeleteDeref, cell_name = idx),
16561666
LoadClosure(i) => w!(LoadClosure, cell_name = i),
1667+
IsOp(inv) => w!(IS_OP, ?inv),
1668+
ContainsOp(inv) => w!(CONTAINS_OP, ?inv),
1669+
JumpIfNotExcMatch(target) => w!(JUMP_IF_NOT_EXC_MATCH, target),
16571670
Subscript => w!(Subscript),
16581671
StoreSubscript => w!(StoreSubscript),
16591672
DeleteSubscript => w!(DeleteSubscript),
@@ -1665,7 +1678,6 @@ impl Instruction {
16651678
BinaryOperationInplace { op } => w!(BinaryOperationInplace, ?op),
16661679
BinarySubscript => w!(BinarySubscript),
16671680
LoadAttr { idx } => w!(LoadAttr, name = idx),
1668-
TestOperation { op } => w!(TestOperation, ?op),
16691681
CompareOperation { op } => w!(CompareOperation, ?op),
16701682
CopyItem { index } => w!(CopyItem, index),
16711683
Pop => w!(Pop),

0 commit comments

Comments
 (0)