Skip to content

Commit fb0dfa1

Browse files
committed
address review: invalidate init cache on type modification, add cspell words
1 parent 9df4787 commit fb0dfa1

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

.cspell.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,13 @@
6060
"dedentations",
6161
"dedents",
6262
"deduped",
63+
"compactlong",
64+
"compactlongs",
6365
"deoptimize",
66+
"descrs",
67+
"downcastable",
68+
"downcasted",
69+
"dumpable",
6470
"emscripten",
6571
"excs",
6672
"interps",

crates/vm/src/builtins/function.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,62 @@ impl Py<PyFunction> {
736736
frame
737737
}
738738

739+
pub(crate) fn prepare_exact_args_frame(
740+
&self,
741+
mut args: Vec<PyObjectRef>,
742+
vm: &VirtualMachine,
743+
) -> FrameRef {
744+
let code: PyRef<PyCode> = (*self.code).to_owned();
745+
746+
debug_assert_eq!(args.len(), code.arg_count as usize);
747+
debug_assert!(code.flags.contains(bytecode::CodeFlags::OPTIMIZED));
748+
debug_assert!(
749+
!code
750+
.flags
751+
.intersects(bytecode::CodeFlags::VARARGS | bytecode::CodeFlags::VARKEYWORDS)
752+
);
753+
debug_assert_eq!(code.kwonlyarg_count, 0);
754+
debug_assert!(
755+
!code
756+
.flags
757+
.intersects(bytecode::CodeFlags::GENERATOR | bytecode::CodeFlags::COROUTINE)
758+
);
759+
760+
let locals = if code.flags.contains(bytecode::CodeFlags::NEWLOCALS) {
761+
None
762+
} else {
763+
Some(ArgMapping::from_dict_exact(self.globals.clone()))
764+
};
765+
766+
let frame = Frame::new(
767+
code.clone(),
768+
Scope::new(locals, self.globals.clone()),
769+
self.builtins.clone(),
770+
self.closure.as_ref().map_or(&[], |c| c.as_slice()),
771+
Some(self.to_owned().into()),
772+
true, // Exact-args fast path is only used for non-gen/coro functions.
773+
vm,
774+
)
775+
.into_ref(&vm.ctx);
776+
777+
{
778+
let fastlocals = unsafe { frame.fastlocals_mut() };
779+
for (slot, arg) in fastlocals.iter_mut().zip(args.drain(..)) {
780+
*slot = Some(arg);
781+
}
782+
}
783+
784+
if let Some(cell2arg) = code.cell2arg.as_deref() {
785+
let fastlocals = unsafe { frame.fastlocals_mut() };
786+
for (cell_idx, arg_idx) in cell2arg.iter().enumerate().filter(|(_, i)| **i != -1) {
787+
let x = fastlocals[*arg_idx as usize].take();
788+
frame.set_cell_contents(cell_idx, x);
789+
}
790+
}
791+
792+
frame
793+
}
794+
739795
/// Fast path for calling a simple function with exact positional args.
740796
/// Skips FuncArgs allocation, prepend_arg, and fill_locals_from_args.
741797
/// Only valid when: CO_OPTIMIZED, no VARARGS, no VARKEYWORDS, no kwonlyargs,

0 commit comments

Comments
 (0)