Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
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
  • Loading branch information
youknowone committed Mar 4, 2026
commit 2885f80785ac9f7ff3303393fdc54ee2996f33d4
31 changes: 15 additions & 16 deletions crates/vm/src/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3931,12 +3931,11 @@ impl ExecutingFrame<'_> {
let nargs: u32 = arg.into();
let callable = self.nth_value(nargs + 1);
let callable_tag = callable as *const PyObject as u32;
if cached_tag == callable_tag && callable.downcast_ref::<PyType>().is_some() {
return self.execute_call_vectorcall(nargs, vm);
if !(cached_tag == callable_tag && callable.downcast_ref::<PyType>().is_some()) {
self.deoptimize(Instruction::Call {
argc: Arg::marker(),
});
}
self.deoptimize(Instruction::Call {
argc: Arg::marker(),
});
self.execute_call_vectorcall(nargs, vm)
}
Instruction::CallAllocAndEnterInit => {
Expand Down Expand Up @@ -4078,12 +4077,11 @@ impl ExecutingFrame<'_> {
let nargs: u32 = arg.into();
let callable = self.nth_value(nargs + 1);
let callable_tag = callable as *const PyObject as u32;
if cached_tag == callable_tag {
return self.execute_call_vectorcall(nargs, vm);
if cached_tag != callable_tag {
self.deoptimize(Instruction::Call {
argc: Arg::marker(),
});
}
self.deoptimize(Instruction::Call {
argc: Arg::marker(),
});
self.execute_call_vectorcall(nargs, vm)
}
Instruction::CallKwPy => {
Expand Down Expand Up @@ -4175,12 +4173,11 @@ impl ExecutingFrame<'_> {
let nargs: u32 = arg.into();
let callable = self.nth_value(nargs + 2);
let callable_tag = callable as *const PyObject as u32;
if cached_tag == callable_tag {
return self.execute_call_kw_vectorcall(nargs, vm);
if cached_tag != callable_tag {
self.deoptimize(Instruction::CallKw {
argc: Arg::marker(),
});
}
self.deoptimize(Instruction::CallKw {
argc: Arg::marker(),
});
self.execute_call_kw_vectorcall(nargs, vm)
}
Instruction::LoadSuperAttrAttr => {
Expand Down Expand Up @@ -5668,7 +5665,9 @@ impl ExecutingFrame<'_> {
.map(|sr| sr.to_pyobj());
let has_self = self_or_null.is_some();

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

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