diff --git a/vm/src/builtins/iter.rs b/vm/src/builtins/iter.rs index 6b5e2da55..1405f4bf5 100644 --- a/vm/src/builtins/iter.rs +++ b/vm/src/builtins/iter.rs @@ -10,7 +10,7 @@ use crate::{ ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TypeProtocol, VirtualMachine, }; -use rustpython_common::lock::{PyMutex, PyRwLock, PyRwLockUpgradableReadGuard}; +use rustpython_common::lock::{OnceCell, PyMutex, PyRwLock, PyRwLockUpgradableReadGuard}; /// Marks status of iterator. #[derive(Debug, Clone)] @@ -69,7 +69,7 @@ impl PositionIterInternal { where F: FnOnce(&T) -> PyObjectRef, { - let iter = vm.get_attribute(vm.builtins.clone(), "iter").unwrap(); + let iter = get_builtin_attribute_iter(vm).clone(); self._reduce(iter, f, vm) } @@ -77,7 +77,7 @@ impl PositionIterInternal { where F: FnOnce(&T) -> PyObjectRef, { - let reversed = vm.get_attribute(vm.builtins.clone(), "reversed").unwrap(); + let reversed = get_builtin_attribute_reversed(vm).clone(); self._reduce(reversed, f, vm) } @@ -167,6 +167,16 @@ impl PositionIterInternal { } } +pub fn get_builtin_attribute_iter(vm: &VirtualMachine) -> &PyObjectRef { + static INSTANCE: OnceCell = OnceCell::new(); + INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "iter").unwrap()) +} + +pub fn get_builtin_attribute_reversed(vm: &VirtualMachine) -> &PyObjectRef { + static INSTANCE: OnceCell = OnceCell::new(); + INSTANCE.get_or_init(|| vm.get_attribute(vm.builtins.clone(), "reversed").unwrap()) +} + #[pyclass(module = false, name = "iterator")] #[derive(Debug)] pub struct PySequenceIterator { diff --git a/vm/src/builtins/pystr.rs b/vm/src/builtins/pystr.rs index dc154b11b..e1802c23e 100644 --- a/vm/src/builtins/pystr.rs +++ b/vm/src/builtins/pystr.rs @@ -25,6 +25,7 @@ use rustpython_common::{ ascii, atomic::{self, PyAtomic, Radium}, hash, + lock::PyMutex, }; use std::mem::size_of; use std::ops::Range; diff --git a/vm/src/builtins/range.rs b/vm/src/builtins/range.rs index 4f6db0a59..d7b115ee5 100644 --- a/vm/src/builtins/range.rs +++ b/vm/src/builtins/range.rs @@ -1,4 +1,5 @@ use super::{PyInt, PyIntRef, PySlice, PySliceRef, PyTypeRef}; +use crate::builtins::get_builtin_attribute_iter; use crate::common::hash::PyHash; use crate::{ function::{FuncArgs, OptionalArg}, @@ -608,7 +609,7 @@ fn range_iter_reduce( index: usize, vm: &VirtualMachine, ) -> PyResult { - let iter = vm.get_attribute(vm.builtins.clone(), "iter")?; + let iter = get_builtin_attribute_iter(vm).clone(); let stop = start.clone() + length * step.clone(); let range = PyRange { start: PyInt::from(start).into_ref(vm), diff --git a/vm/src/builtins/set.rs b/vm/src/builtins/set.rs index 7bb510968..1f1b4fdbf 100644 --- a/vm/src/builtins/set.rs +++ b/vm/src/builtins/set.rs @@ -1,9 +1,8 @@ -use super::PositionIterInternal; /* * Builtin set type with a sequence of unique items. */ -use super::{IterStatus, PyDictRef, PyTypeRef}; -use crate::common::{ascii, hash::PyHash, rc::PyRc}; +use super::{get_builtin_attribute_iter, IterStatus, PositionIterInternal, PyDictRef, PyTypeRef}; +use crate::common::{ascii, hash::PyHash, lock::PyMutex, rc::PyRc}; use crate::{ dictdatatype::{self, DictSize}, function::{ArgIterable, FuncArgs, OptionalArg, PosArgs}, @@ -16,7 +15,6 @@ use crate::{ IdProtocol, PyClassImpl, PyComparisonValue, PyContext, PyObjectRef, PyRef, PyResult, PyValue, TryFromObject, TypeProtocol, }; -use rustpython_common::lock::PyMutex; use std::fmt; pub type SetContentType = dictdatatype::Dict<()>; @@ -842,7 +840,7 @@ impl PySetIterator { fn reduce(zelf: PyRef, vm: &VirtualMachine) -> PyResult<(PyObjectRef, (PyObjectRef,))> { let internal = zelf.internal.lock(); Ok(( - vm.get_attribute(vm.builtins.clone(), "iter")?, + get_builtin_attribute_iter(vm).clone(), (vm.ctx.new_list(match &internal.status { IterStatus::Exhausted => vec![], IterStatus::Active(dict) => { diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index cfc6426b3..8a5cd5a37 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -1,8 +1,8 @@ -use crate::builtins::{PyStr, PyStrRef}; /// Ordered dictionary implementation. /// Inspired by: https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html /// And: https://www.youtube.com/watch?v=p33CVV29OG8 /// And: http://code.activestate.com/recipes/578375/ +use crate::builtins::{PyStr, PyStrRef}; use crate::common::{ hash, lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard},