Skip to content

Commit a91dd29

Browse files
committed
vm: align UNPACK_SEQUENCE specialization length guards with CPython
1 parent 0c72328 commit a91dd29

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

crates/vm/src/frame.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3110,8 +3110,9 @@ impl ExecutingFrame<'_> {
31103110
self.execute_unpack_ex(vm, args.before, args.after)
31113111
}
31123112
Instruction::UnpackSequence { count: size } => {
3113-
self.adaptive(|s, ii, cb| s.specialize_unpack_sequence(vm, ii, cb));
3114-
self.unpack_sequence(size.get(arg), vm)
3113+
let expected = size.get(arg);
3114+
self.adaptive(|s, ii, cb| s.specialize_unpack_sequence(vm, expected, ii, cb));
3115+
self.unpack_sequence(expected, vm)
31153116
}
31163117
Instruction::WithExceptStart => {
31173118
// Stack: [..., __exit__, lasti, prev_exc, exc]
@@ -8785,6 +8786,7 @@ impl ExecutingFrame<'_> {
87858786
fn specialize_unpack_sequence(
87868787
&mut self,
87878788
vm: &VirtualMachine,
8789+
expected_count: u32,
87888790
instr_idx: usize,
87898791
cache_base: usize,
87908792
) {
@@ -8796,13 +8798,19 @@ impl ExecutingFrame<'_> {
87968798
}
87978799
let obj = self.top_value();
87988800
let new_op = if let Some(tuple) = obj.downcast_ref_if_exact::<PyTuple>(vm) {
8799-
if tuple.len() == 2 {
8801+
if tuple.len() != expected_count as usize {
8802+
None
8803+
} else if expected_count == 2 {
88008804
Some(Instruction::UnpackSequenceTwoTuple)
88018805
} else {
88028806
Some(Instruction::UnpackSequenceTuple)
88038807
}
8804-
} else if obj.downcast_ref_if_exact::<PyList>(vm).is_some() {
8805-
Some(Instruction::UnpackSequenceList)
8808+
} else if let Some(list) = obj.downcast_ref_if_exact::<PyList>(vm) {
8809+
if list.borrow_vec().len() == expected_count as usize {
8810+
Some(Instruction::UnpackSequenceList)
8811+
} else {
8812+
None
8813+
}
88068814
} else {
88078815
None
88088816
};

0 commit comments

Comments
 (0)