Skip to content

Commit 2885f80

Browse files
committed
Collapse duplicated branch tails and use checked_sub in CALL_KW
- Collapse conditional deopt + unconditional vectorcall pattern in CallBuiltinClass, CallNonPyGeneral, CallKwNonPy - Use checked_sub for nargs_usize - kw_count in execute_call_kw_vectorcall to prevent silent underflow in release builds
1 parent c47d1f2 commit 2885f80

File tree

1 file changed

+15
-16
lines changed

1 file changed

+15
-16
lines changed

crates/vm/src/frame.rs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3931,12 +3931,11 @@ impl ExecutingFrame<'_> {
39313931
let nargs: u32 = arg.into();
39323932
let callable = self.nth_value(nargs + 1);
39333933
let callable_tag = callable as *const PyObject as u32;
3934-
if cached_tag == callable_tag && callable.downcast_ref::<PyType>().is_some() {
3935-
return self.execute_call_vectorcall(nargs, vm);
3934+
if !(cached_tag == callable_tag && callable.downcast_ref::<PyType>().is_some()) {
3935+
self.deoptimize(Instruction::Call {
3936+
argc: Arg::marker(),
3937+
});
39363938
}
3937-
self.deoptimize(Instruction::Call {
3938-
argc: Arg::marker(),
3939-
});
39403939
self.execute_call_vectorcall(nargs, vm)
39413940
}
39423941
Instruction::CallAllocAndEnterInit => {
@@ -4078,12 +4077,11 @@ impl ExecutingFrame<'_> {
40784077
let nargs: u32 = arg.into();
40794078
let callable = self.nth_value(nargs + 1);
40804079
let callable_tag = callable as *const PyObject as u32;
4081-
if cached_tag == callable_tag {
4082-
return self.execute_call_vectorcall(nargs, vm);
4080+
if cached_tag != callable_tag {
4081+
self.deoptimize(Instruction::Call {
4082+
argc: Arg::marker(),
4083+
});
40834084
}
4084-
self.deoptimize(Instruction::Call {
4085-
argc: Arg::marker(),
4086-
});
40874085
self.execute_call_vectorcall(nargs, vm)
40884086
}
40894087
Instruction::CallKwPy => {
@@ -4175,12 +4173,11 @@ impl ExecutingFrame<'_> {
41754173
let nargs: u32 = arg.into();
41764174
let callable = self.nth_value(nargs + 2);
41774175
let callable_tag = callable as *const PyObject as u32;
4178-
if cached_tag == callable_tag {
4179-
return self.execute_call_kw_vectorcall(nargs, vm);
4176+
if cached_tag != callable_tag {
4177+
self.deoptimize(Instruction::CallKw {
4178+
argc: Arg::marker(),
4179+
});
41804180
}
4181-
self.deoptimize(Instruction::CallKw {
4182-
argc: Arg::marker(),
4183-
});
41844181
self.execute_call_kw_vectorcall(nargs, vm)
41854182
}
41864183
Instruction::LoadSuperAttrAttr => {
@@ -5668,7 +5665,9 @@ impl ExecutingFrame<'_> {
56685665
.map(|sr| sr.to_pyobj());
56695666
let has_self = self_or_null.is_some();
56705667

5671-
let pos_count = nargs_usize - kw_count;
5668+
let pos_count = nargs_usize
5669+
.checked_sub(kw_count)
5670+
.expect("CALL_KW: kw_count exceeds nargs");
56725671
let effective_nargs = if has_self { pos_count + 1 } else { pos_count };
56735672

56745673
// Build the full args slice: positional (including self) + kwarg values

0 commit comments

Comments
 (0)