(&self, vm: &VirtualMachine)
| 714 | |
| 715 | #[pygetset] |
| 716 | pub fn f_back(&self, vm: &VirtualMachine) -> Option<PyRef<Frame>> { |
| 717 | let previous = self.previous_frame(); |
| 718 | if previous.is_null() { |
| 719 | return None; |
| 720 | } |
| 721 | |
| 722 | if let Some(frame) = vm |
| 723 | .frames |
| 724 | .borrow() |
| 725 | .iter() |
| 726 | .find(|fp| { |
| 727 | // SAFETY: the caller keeps the FrameRef alive while it's in the Vec |
| 728 | let py: &crate::Py<Frame> = unsafe { fp.as_ref() }; |
| 729 | let ptr: *const Frame = &**py; |
| 730 | core::ptr::eq(ptr, previous) |
| 731 | }) |
| 732 | .map(|fp| unsafe { fp.as_ref() }.to_owned()) |
| 733 | { |
| 734 | return Some(frame); |
| 735 | } |
| 736 | |
| 737 | #[cfg(feature = "threading")] |
| 738 | { |
| 739 | let registry = vm.state.thread_frames.lock(); |
| 740 | for slot in registry.values() { |
| 741 | let frames = slot.frames.lock(); |
| 742 | // SAFETY: the owning thread can't pop while we hold the Mutex, |
| 743 | // so FramePtr is valid for the duration of the lock. |
| 744 | if let Some(frame) = frames.iter().find_map(|fp| { |
| 745 | let f = unsafe { fp.as_ref() }; |
| 746 | let ptr: *const Frame = &**f; |
| 747 | core::ptr::eq(ptr, previous).then(|| f.to_owned()) |
| 748 | }) { |
| 749 | return Some(frame); |
| 750 | } |
| 751 | } |
| 752 | } |
| 753 | |
| 754 | None |
| 755 | } |
| 756 | } |
no test coverage detected