From fb0dfa102cee20642baa37cd1f636cc59053830f Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" Date: Mon, 9 Mar 2026 00:02:12 +0900 Subject: [PATCH] address review: invalidate init cache on type modification, add cspell words --- .cspell.json | 6 ++++ crates/vm/src/builtins/function.rs | 56 ++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/.cspell.json b/.cspell.json index f6887a7bb..f82920c6c 100644 --- a/.cspell.json +++ b/.cspell.json @@ -60,7 +60,13 @@ "dedentations", "dedents", "deduped", + "compactlong", + "compactlongs", "deoptimize", + "descrs", + "downcastable", + "downcasted", + "dumpable", "emscripten", "excs", "interps", diff --git a/crates/vm/src/builtins/function.rs b/crates/vm/src/builtins/function.rs index 0003720c6..8a2b5c417 100644 --- a/crates/vm/src/builtins/function.rs +++ b/crates/vm/src/builtins/function.rs @@ -736,6 +736,62 @@ impl Py { frame } + pub(crate) fn prepare_exact_args_frame( + &self, + mut args: Vec, + vm: &VirtualMachine, + ) -> FrameRef { + let code: PyRef = (*self.code).to_owned(); + + debug_assert_eq!(args.len(), code.arg_count as usize); + debug_assert!(code.flags.contains(bytecode::CodeFlags::OPTIMIZED)); + debug_assert!( + !code + .flags + .intersects(bytecode::CodeFlags::VARARGS | bytecode::CodeFlags::VARKEYWORDS) + ); + debug_assert_eq!(code.kwonlyarg_count, 0); + debug_assert!( + !code + .flags + .intersects(bytecode::CodeFlags::GENERATOR | bytecode::CodeFlags::COROUTINE) + ); + + let locals = if code.flags.contains(bytecode::CodeFlags::NEWLOCALS) { + None + } else { + Some(ArgMapping::from_dict_exact(self.globals.clone())) + }; + + let frame = Frame::new( + code.clone(), + Scope::new(locals, self.globals.clone()), + self.builtins.clone(), + self.closure.as_ref().map_or(&[], |c| c.as_slice()), + Some(self.to_owned().into()), + true, // Exact-args fast path is only used for non-gen/coro functions. + vm, + ) + .into_ref(&vm.ctx); + + { + let fastlocals = unsafe { frame.fastlocals_mut() }; + for (slot, arg) in fastlocals.iter_mut().zip(args.drain(..)) { + *slot = Some(arg); + } + } + + if let Some(cell2arg) = code.cell2arg.as_deref() { + let fastlocals = unsafe { frame.fastlocals_mut() }; + for (cell_idx, arg_idx) in cell2arg.iter().enumerate().filter(|(_, i)| **i != -1) { + let x = fastlocals[*arg_idx as usize].take(); + frame.set_cell_contents(cell_idx, x); + } + } + + frame + } + /// Fast path for calling a simple function with exact positional args. /// Skips FuncArgs allocation, prepend_arg, and fill_locals_from_args. /// Only valid when: CO_OPTIMIZED, no VARARGS, no VARKEYWORDS, no kwonlyargs,