Skip to content

Commit 09c3bb1

Browse files
committed
address review: invalidate init cache on type modification, add cspell words
1 parent 94e8d54 commit 09c3bb1

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

.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
@@ -734,6 +734,62 @@ impl Py<PyFunction> {
734734
frame
735735
}
736736

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

0 commit comments

Comments
 (0)