Skip to content

Commit 29ee656

Browse files
committed
Force BuildSlice oparg to be either 2 or 3
1 parent 6782fa2 commit 29ee656

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

crates/codegen/src/compile.rs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use ruff_text_size::{Ranged, TextRange};
3535
use rustpython_compiler_core::{
3636
Mode, OneIndexed, PositionEncoding, SourceFile, SourceLocation,
3737
bytecode::{
38-
self, Arg as OpArgMarker, BinaryOperator, CodeObject, ComparisonOperator, ConstantData,
39-
Instruction, Invert, OpArg, OpArgType, UnpackExArgs,
38+
self, Arg as OpArgMarker, BinaryOperator, BuildSliceArgCount, CodeObject,
39+
ComparisonOperator, ConstantData, Instruction, Invert, OpArg, OpArgType, UnpackExArgs,
4040
},
4141
};
4242
use rustpython_wtf8::Wtf8Buf;
@@ -456,12 +456,22 @@ impl Compiler {
456456
match ctx {
457457
ExprContext::Load => {
458458
// CPython uses BINARY_SLICE
459-
emit!(self, Instruction::BuildSlice { step: n == 3 });
459+
emit!(
460+
self,
461+
Instruction::BuildSlice {
462+
argc: BuildSliceArgCount::from_op_arg(n).unwrap()
463+
}
464+
);
460465
emit!(self, Instruction::Subscript);
461466
}
462467
ExprContext::Store => {
463468
// CPython uses STORE_SLICE
464-
emit!(self, Instruction::BuildSlice { step: n == 3 });
469+
emit!(
470+
self,
471+
Instruction::BuildSlice {
472+
argc: BuildSliceArgCount::from_op_arg(n).unwrap()
473+
}
474+
);
465475
emit!(self, Instruction::StoreSubscript);
466476
}
467477
_ => unreachable!(),
@@ -4587,8 +4597,11 @@ impl Compiler {
45874597
if let Some(step) = step {
45884598
self.compile_expression(step)?;
45894599
}
4590-
let step = step.is_some();
4591-
emit!(self, Instruction::BuildSlice { step });
4600+
let argc = match step {
4601+
Some(_) => BuildSliceArgCount::Three,
4602+
None => BuildSliceArgCount::Two,
4603+
};
4604+
emit!(self, Instruction::BuildSlice { argc });
45924605
}
45934606
Expr::Yield(ExprYield { value, .. }) => {
45944607
if !self.ctx.in_func() {

crates/compiler-core/src/bytecode.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -760,8 +760,7 @@ pub enum Instruction {
760760
index: Arg<u32>,
761761
},
762762
BuildSlice {
763-
/// whether build a slice with a third step argument
764-
step: Arg<bool>,
763+
argc: Arg<BuildSliceArgCount>,
765764
},
766765
ListAppend {
767766
i: Arg<u32>,
@@ -1151,6 +1150,22 @@ op_arg_enum!(
11511150
}
11521151
);
11531152

1153+
op_arg_enum!(
1154+
/// Specifies if a slice is built with either 2 or 3 arguments.
1155+
#[repr(u8)]
1156+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
1157+
pub enum BuildSliceArgCount {
1158+
/// ```py
1159+
/// x[5:10]
1160+
/// ```
1161+
Two = 2,
1162+
/// ```py
1163+
/// x[5:10:2]
1164+
/// ```
1165+
Three = 3,
1166+
}
1167+
);
1168+
11541169
#[derive(Copy, Clone)]
11551170
pub struct UnpackExArgs {
11561171
pub before: u8,
@@ -1547,7 +1562,11 @@ impl Instruction {
15471562
-(nargs as i32) + 1
15481563
}
15491564
DictUpdate { .. } => -1,
1550-
BuildSlice { step } => -2 - (step.get(arg) as i32) + 1,
1565+
BuildSlice { argc } => {
1566+
// push 1
1567+
// pops either 2/3
1568+
1 - (argc.get(arg) as i32)
1569+
}
15511570
ListAppend { .. } | SetAdd { .. } => -1,
15521571
MapAdd { .. } => -2,
15531572
PrintExpr => -1,
@@ -1734,7 +1753,7 @@ impl Instruction {
17341753
BuildMap { size } => w!(BuildMap, size),
17351754
BuildMapForCall { size } => w!(BuildMapForCall, size),
17361755
DictUpdate { index } => w!(DictUpdate, index),
1737-
BuildSlice { step } => w!(BuildSlice, step),
1756+
BuildSlice { argc } => w!(BuildSlice, ?argc),
17381757
ListAppend { i } => w!(ListAppend, i),
17391758
SetAdd { i } => w!(SetAdd, i),
17401759
MapAdd { i } => w!(MapAdd, i),

crates/vm/src/frame.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,8 @@ impl ExecutingFrame<'_> {
834834
dict.merge_object(source, vm)?;
835835
Ok(None)
836836
}
837-
bytecode::Instruction::BuildSlice { step } => {
838-
self.execute_build_slice(vm, step.get(arg))
837+
bytecode::Instruction::BuildSlice { argc } => {
838+
self.execute_build_slice(vm, argc.get(arg))
839839
}
840840
bytecode::Instruction::ListAppend { i } => {
841841
let item = self.pop_value();
@@ -1777,8 +1777,15 @@ impl ExecutingFrame<'_> {
17771777
Ok(None)
17781778
}
17791779

1780-
fn execute_build_slice(&mut self, vm: &VirtualMachine, step: bool) -> FrameResult {
1781-
let step = if step { Some(self.pop_value()) } else { None };
1780+
fn execute_build_slice(
1781+
&mut self,
1782+
vm: &VirtualMachine,
1783+
argc: bytecode::BuildSliceArgCount,
1784+
) -> FrameResult {
1785+
let step = match argc {
1786+
bytecode::BuildSliceArgCount::Two => None,
1787+
bytecode::BuildSliceArgCount::Three => Some(self.pop_value()),
1788+
};
17821789
let stop = self.pop_value();
17831790
let start = self.pop_value();
17841791

0 commit comments

Comments
 (0)