Skip to content

Commit ee124eb

Browse files
committed
Make ReprGuard vm-local
1 parent 076bab9 commit ee124eb

File tree

7 files changed

+27
-29
lines changed

7 files changed

+27
-29
lines changed

vm/src/obj/objdict.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ impl PyDictRef {
194194

195195
#[pymethod(magic)]
196196
fn repr(self, vm: &VirtualMachine) -> PyResult<String> {
197-
let s = if let Some(_guard) = ReprGuard::enter(self.as_object()) {
197+
let s = if let Some(_guard) = ReprGuard::enter(vm, self.as_object()) {
198198
let mut str_parts = vec![];
199199
for (key, value) in self {
200200
let key_repr = vm.to_repr(&key)?;
@@ -571,7 +571,7 @@ macro_rules! dict_iterator {
571571
#[pymethod(name = "__repr__")]
572572
#[allow(clippy::redundant_closure_call)]
573573
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
574-
let s = if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
574+
let s = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
575575
let mut str_parts = vec![];
576576
for (key, value) in zelf.dict.clone() {
577577
let s = vm.to_repr(&$result_fn(vm, key, value))?;

vm/src/obj/objlist.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ impl PyList {
420420

421421
#[pymethod(name = "__repr__")]
422422
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
423-
let s = if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
423+
let s = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
424424
let elements = zelf.borrow_value().clone();
425425
let mut str_parts = Vec::with_capacity(elements.len());
426426
for elem in elements.iter() {

vm/src/obj/objset.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ impl PySet {
513513
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult {
514514
let s = if zelf.inner.len() == 0 {
515515
"set()".to_owned()
516-
} else if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
516+
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
517517
zelf.inner.repr(vm)?
518518
} else {
519519
"set(...)".to_owned()
@@ -783,7 +783,7 @@ impl PyFrozenSet {
783783
let inner = &zelf.inner;
784784
let s = if inner.len() == 0 {
785785
"frozenset()".to_owned()
786-
} else if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
786+
} else if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
787787
format!("frozenset({})", inner.repr(vm)?)
788788
} else {
789789
"frozenset(...)".to_owned()

vm/src/obj/objtuple.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl PyTuple {
179179

180180
#[pymethod(name = "__repr__")]
181181
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
182-
let s = if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
182+
let s = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
183183
let mut str_parts = Vec::with_capacity(zelf.elements.len());
184184
for elem in zelf.elements.iter() {
185185
let s = vm.to_repr(elem)?;

vm/src/pyobject.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,7 +1454,7 @@ pub trait PyStructSequenceImpl: PyClassImpl {
14541454
Ok(format!("{}: {}", name, s))
14551455
};
14561456
let (body, suffix) =
1457-
if let Some(_guard) = rustpython_vm::vm::ReprGuard::enter(zelf.as_object()) {
1457+
if let Some(_guard) = rustpython_vm::vm::ReprGuard::enter(vm, zelf.as_object()) {
14581458
if Self::FIELD_NAMES.len() == 1 {
14591459
let value = zelf.borrow_value().first().unwrap();
14601460
let formatted = format_field((value, Self::FIELD_NAMES[0]))?;

vm/src/stdlib/collections.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ mod _collections {
248248

249249
#[pymethod(name = "__repr__")]
250250
fn repr(zelf: PyRef<Self>, vm: &VirtualMachine) -> PyResult<String> {
251-
let repr = if let Some(_guard) = ReprGuard::enter(zelf.as_object()) {
251+
let repr = if let Some(_guard) = ReprGuard::enter(vm, zelf.as_object()) {
252252
let elements = zelf
253253
.borrow_deque()
254254
.iter()

vm/src/vm.rs

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ pub struct VirtualMachine {
6363
pub use_tracing: Cell<bool>,
6464
pub recursion_limit: Cell<usize>,
6565
pub signal_handlers: Option<Box<RefCell<[PyObjectRef; NSIG]>>>,
66+
pub repr_guards: RefCell<HashSet<usize>>,
6667
pub state: PyRc<PyGlobalState>,
6768
pub initialized: bool,
6869
}
@@ -199,6 +200,7 @@ impl VirtualMachine {
199200
use_tracing: Cell::new(false),
200201
recursion_limit: Cell::new(if cfg!(debug_assertions) { 256 } else { 512 }),
201202
signal_handlers: Some(Box::new(signal_handlers)),
203+
repr_guards: RefCell::default(),
202204
state: PyRc::new(PyGlobalState {
203205
settings,
204206
stdlib_inits,
@@ -293,6 +295,7 @@ impl VirtualMachine {
293295
use_tracing: Cell::new(false),
294296
recursion_limit: self.recursion_limit.clone(),
295297
signal_handlers: None,
298+
repr_guards: RefCell::default(),
296299
state: self.state.clone(),
297300
initialized: self.initialized,
298301
}
@@ -1489,37 +1492,32 @@ impl Default for VirtualMachine {
14891492
}
14901493
}
14911494

1492-
thread_local! {
1493-
static REPR_GUARDS: RefCell<HashSet<usize>> = RefCell::default();
1494-
}
1495-
1496-
pub struct ReprGuard {
1495+
pub struct ReprGuard<'vm> {
1496+
vm: &'vm VirtualMachine,
14971497
id: usize,
14981498
}
14991499

15001500
/// A guard to protect repr methods from recursion into itself,
1501-
impl ReprGuard {
1501+
impl<'vm> ReprGuard<'vm> {
15021502
/// Returns None if the guard against 'obj' is still held otherwise returns the guard. The guard
15031503
/// which is released if dropped.
1504-
pub fn enter(obj: &PyObjectRef) -> Option<ReprGuard> {
1505-
REPR_GUARDS.with(|guards| {
1506-
let mut guards = guards.borrow_mut();
1507-
1508-
// Should this be a flag on the obj itself? putting it in a global variable for now until it
1509-
// decided the form of the PyObject. https://github.com/RustPython/RustPython/issues/371
1510-
let id = obj.get_id();
1511-
if guards.contains(&id) {
1512-
return None;
1513-
}
1514-
guards.insert(id);
1515-
Some(ReprGuard { id })
1516-
})
1504+
pub fn enter(vm: &'vm VirtualMachine, obj: &PyObjectRef) -> Option<Self> {
1505+
let mut guards = vm.repr_guards.borrow_mut();
1506+
1507+
// Should this be a flag on the obj itself? putting it in a global variable for now until it
1508+
// decided the form of the PyObject. https://github.com/RustPython/RustPython/issues/371
1509+
let id = obj.get_id();
1510+
if guards.contains(&id) {
1511+
return None;
1512+
}
1513+
guards.insert(id);
1514+
Some(ReprGuard { vm, id })
15171515
}
15181516
}
15191517

1520-
impl Drop for ReprGuard {
1518+
impl<'vm> Drop for ReprGuard<'vm> {
15211519
fn drop(&mut self) {
1522-
REPR_GUARDS.with(|guards| guards.borrow_mut().remove(&self.id));
1520+
self.vm.repr_guards.borrow_mut().remove(&self.id);
15231521
}
15241522
}
15251523

0 commit comments

Comments
 (0)