forked from RustPython/RustPython
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecursion.rs
30 lines (26 loc) · 979 Bytes
/
recursion.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use crate::{AsObject, PyObject, VirtualMachine};
pub struct ReprGuard<'vm> {
vm: &'vm VirtualMachine,
id: usize,
}
/// A guard to protect repr methods from recursion into itself,
impl<'vm> ReprGuard<'vm> {
/// Returns None if the guard against 'obj' is still held otherwise returns the guard. The guard
/// which is released if dropped.
pub fn enter(vm: &'vm VirtualMachine, obj: &PyObject) -> Option<Self> {
let mut guards = vm.repr_guards.borrow_mut();
// Should this be a flag on the obj itself? putting it in a global variable for now until it
// decided the form of PyObject. https://github.com/RustPython/RustPython/issues/371
let id = obj.get_id();
if guards.contains(&id) {
return None;
}
guards.insert(id);
Some(ReprGuard { vm, id })
}
}
impl<'vm> Drop for ReprGuard<'vm> {
fn drop(&mut self) {
self.vm.repr_guards.borrow_mut().remove(&self.id);
}
}