(
&self,
mut args: Vec<PyObjectRef>,
vm: &VirtualMachine,
)
| 674 | } |
| 675 | |
| 676 | pub(crate) fn prepare_exact_args_frame( |
| 677 | &self, |
| 678 | mut args: Vec<PyObjectRef>, |
| 679 | vm: &VirtualMachine, |
| 680 | ) -> FrameRef { |
| 681 | let code: PyRef<PyCode> = (*self.code).to_owned(); |
| 682 | |
| 683 | debug_assert_eq!(args.len(), code.arg_count as usize); |
| 684 | debug_assert!(code.flags.contains(bytecode::CodeFlags::OPTIMIZED)); |
| 685 | debug_assert!( |
| 686 | !code |
| 687 | .flags |
| 688 | .intersects(bytecode::CodeFlags::VARARGS | bytecode::CodeFlags::VARKEYWORDS) |
| 689 | ); |
| 690 | debug_assert_eq!(code.kwonlyarg_count, 0); |
| 691 | debug_assert!( |
| 692 | !code |
| 693 | .flags |
| 694 | .intersects(bytecode::CodeFlags::GENERATOR | bytecode::CodeFlags::COROUTINE) |
| 695 | ); |
| 696 | |
| 697 | let locals = if code.flags.contains(bytecode::CodeFlags::NEWLOCALS) { |
| 698 | None |
| 699 | } else { |
| 700 | Some(ArgMapping::from_dict_exact(self.globals.clone())) |
| 701 | }; |
| 702 | |
| 703 | let frame = Frame::new( |
| 704 | code.clone(), |
| 705 | Scope::new(locals, self.globals.clone()), |
| 706 | self.builtins.clone(), |
| 707 | self.closure.as_ref().map_or(&[], |c| c.as_slice()), |
| 708 | Some(self.to_owned().into()), |
| 709 | true, // Exact-args fast path is only used for non-gen/coro functions. |
| 710 | vm, |
| 711 | ) |
| 712 | .into_ref(&vm.ctx); |
| 713 | |
| 714 | { |
| 715 | let fastlocals = unsafe { frame.fastlocals_mut() }; |
| 716 | for (slot, arg) in fastlocals.iter_mut().zip(args.drain(..)) { |
| 717 | *slot = Some(arg); |
| 718 | } |
| 719 | } |
| 720 | |
| 721 | frame |
| 722 | } |
| 723 | |
| 724 | /// Fast path for calling a simple function with exact positional args. |
| 725 | /// Skips FuncArgs allocation, prepend_arg, and fill_locals_from_args. |
no test coverage detected