|
1 | 1 | use crate::common::lock::PyRwLockReadGuard; |
2 | 2 | use crate::{ |
3 | | - builtins::{ |
4 | | - builtinfunc::{PyBuiltinFunction, PyBuiltinMethod, PyNativeFuncDef}, |
5 | | - bytes, |
6 | | - getset::{IntoPyGetterFunc, IntoPySetterFunc, PyGetSet}, |
7 | | - object, pystr, |
8 | | - pytype::PyAttributes, |
9 | | - PyBaseException, PyBaseExceptionRef, PyDict, PyDictRef, PyEllipsis, PyFloat, PyFrozenSet, |
10 | | - PyInt, PyIntRef, PyList, PyListRef, PyNone, PyNotImplemented, PyStr, PyTuple, PyTupleRef, |
11 | | - PyType, PyTypeRef, |
12 | | - }, |
13 | | - convert::TryFromObject, |
14 | | - convert::{ToPyObject, ToPyResult}, |
15 | | - exceptions, |
16 | | - function::{IntoFuncArgs, IntoPyNativeFunc}, |
17 | | - intern::{Internable, StringPool}, |
18 | | - pyclass::{PyClassImpl, StaticType}, |
19 | | - types::{PyTypeFlags, PyTypeSlots, TypeZoo}, |
| 3 | + builtins::{object, pystr, PyBaseExceptionRef, PyType, PyTypeRef}, |
| 4 | + convert::{ToPyObject, ToPyResult, TryFromObject}, |
| 5 | + function::IntoFuncArgs, |
| 6 | + types::PyTypeFlags, |
20 | 7 | VirtualMachine, |
21 | 8 | _pyobjectrc::{Py, PyObject, PyObjectRef, PyRef}, |
22 | 9 | }; |
23 | | -use num_bigint::BigInt; |
24 | | -use num_traits::ToPrimitive; |
25 | 10 | use std::{any::Any, borrow::Borrow, fmt, ops::Deref}; |
26 | 11 |
|
27 | 12 | /* Python objects and references. |
@@ -55,303 +40,6 @@ impl fmt::Display for PyObject { |
55 | 40 | } |
56 | 41 | } |
57 | 42 |
|
58 | | -#[derive(Debug, Clone)] |
59 | | -pub struct PyContext { |
60 | | - pub true_value: PyIntRef, |
61 | | - pub false_value: PyIntRef, |
62 | | - pub none: PyRef<PyNone>, |
63 | | - pub empty_tuple: PyTupleRef, |
64 | | - pub empty_frozenset: PyRef<PyFrozenSet>, |
65 | | - pub ellipsis: PyRef<PyEllipsis>, |
66 | | - pub not_implemented: PyRef<PyNotImplemented>, |
67 | | - |
68 | | - pub(crate) true_str: PyRef<PyStr>, |
69 | | - pub(crate) false_str: PyRef<PyStr>, |
70 | | - |
71 | | - pub types: TypeZoo, |
72 | | - pub exceptions: exceptions::ExceptionZoo, |
73 | | - pub int_cache_pool: Vec<PyIntRef>, |
74 | | - // there should only be exact objects of str in here, no non-strs and no subclasses |
75 | | - pub(crate) string_pool: StringPool, |
76 | | - pub(super) slot_new_wrapper: PyObjectRef, |
77 | | -} |
78 | | - |
79 | | -// Basic objects: |
80 | | -impl PyContext { |
81 | | - pub const INT_CACHE_POOL_MIN: i32 = -5; |
82 | | - pub const INT_CACHE_POOL_MAX: i32 = 256; |
83 | | - |
84 | | - fn init() -> Self { |
85 | | - flame_guard!("init PyContext"); |
86 | | - let types = TypeZoo::init(); |
87 | | - let exceptions = exceptions::ExceptionZoo::init(); |
88 | | - |
89 | | - #[inline] |
90 | | - fn create_object<T: PyObjectPayload + PyPayload>(payload: T, cls: &PyTypeRef) -> PyRef<T> { |
91 | | - PyRef::new_ref(payload, cls.clone(), None) |
92 | | - } |
93 | | - |
94 | | - let none = create_object(PyNone, PyNone::static_type()); |
95 | | - let ellipsis = create_object(PyEllipsis, PyEllipsis::static_type()); |
96 | | - let not_implemented = create_object(PyNotImplemented, PyNotImplemented::static_type()); |
97 | | - |
98 | | - let int_cache_pool = (Self::INT_CACHE_POOL_MIN..=Self::INT_CACHE_POOL_MAX) |
99 | | - .map(|v| PyRef::new_ref(PyInt::from(BigInt::from(v)), types.int_type.clone(), None)) |
100 | | - .collect(); |
101 | | - |
102 | | - let true_value = create_object(PyInt::from(1), &types.bool_type); |
103 | | - let false_value = create_object(PyInt::from(0), &types.bool_type); |
104 | | - |
105 | | - let empty_tuple = create_object( |
106 | | - PyTuple::new_unchecked(Vec::new().into_boxed_slice()), |
107 | | - &types.tuple_type, |
108 | | - ); |
109 | | - let empty_frozenset = |
110 | | - PyRef::new_ref(PyFrozenSet::default(), types.frozenset_type.clone(), None); |
111 | | - |
112 | | - let string_pool = StringPool::default(); |
113 | | - |
114 | | - let new_str = unsafe { string_pool.intern("__new__", types.str_type.clone()) }; |
115 | | - let slot_new_wrapper = create_object( |
116 | | - PyNativeFuncDef::new(PyType::__new__.into_func(), new_str.into_pyref()).into_function(), |
117 | | - &types.builtin_function_or_method_type, |
118 | | - ) |
119 | | - .into(); |
120 | | - |
121 | | - let true_str = unsafe { string_pool.intern("True", types.str_type.clone()) }.into_pyref(); |
122 | | - let false_str = unsafe { string_pool.intern("False", types.str_type.clone()) }.into_pyref(); |
123 | | - |
124 | | - let context = PyContext { |
125 | | - true_value, |
126 | | - false_value, |
127 | | - none, |
128 | | - empty_tuple, |
129 | | - empty_frozenset, |
130 | | - ellipsis, |
131 | | - not_implemented, |
132 | | - |
133 | | - true_str, |
134 | | - false_str, |
135 | | - |
136 | | - types, |
137 | | - exceptions, |
138 | | - int_cache_pool, |
139 | | - string_pool, |
140 | | - slot_new_wrapper, |
141 | | - }; |
142 | | - TypeZoo::extend(&context); |
143 | | - exceptions::ExceptionZoo::extend(&context); |
144 | | - context |
145 | | - } |
146 | | - |
147 | | - pub fn intern_string<S: Internable>(&self, s: S) -> PyRefExact<PyStr> { |
148 | | - unsafe { self.string_pool.intern(s, self.types.str_type.clone()) } |
149 | | - } |
150 | | - |
151 | | - #[inline(always)] |
152 | | - pub fn none(&self) -> PyObjectRef { |
153 | | - self.none.clone().into() |
154 | | - } |
155 | | - |
156 | | - #[inline(always)] |
157 | | - pub fn ellipsis(&self) -> PyObjectRef { |
158 | | - self.ellipsis.clone().into() |
159 | | - } |
160 | | - |
161 | | - #[inline(always)] |
162 | | - pub fn not_implemented(&self) -> PyObjectRef { |
163 | | - self.not_implemented.clone().into() |
164 | | - } |
165 | | - |
166 | | - // shortcuts for common type |
167 | | - |
168 | | - #[inline] |
169 | | - pub fn new_int<T: Into<BigInt> + ToPrimitive>(&self, i: T) -> PyIntRef { |
170 | | - if let Some(i) = i.to_i32() { |
171 | | - if i >= Self::INT_CACHE_POOL_MIN && i <= Self::INT_CACHE_POOL_MAX { |
172 | | - let inner_idx = (i - Self::INT_CACHE_POOL_MIN) as usize; |
173 | | - return self.int_cache_pool[inner_idx].clone(); |
174 | | - } |
175 | | - } |
176 | | - PyRef::new_ref(PyInt::from(i), self.types.int_type.clone(), None) |
177 | | - } |
178 | | - |
179 | | - #[inline] |
180 | | - pub fn new_bigint(&self, i: &BigInt) -> PyIntRef { |
181 | | - if let Some(i) = i.to_i32() { |
182 | | - if i >= Self::INT_CACHE_POOL_MIN && i <= Self::INT_CACHE_POOL_MAX { |
183 | | - let inner_idx = (i - Self::INT_CACHE_POOL_MIN) as usize; |
184 | | - return self.int_cache_pool[inner_idx].clone(); |
185 | | - } |
186 | | - } |
187 | | - PyRef::new_ref(PyInt::from(i.clone()), self.types.int_type.clone(), None) |
188 | | - } |
189 | | - |
190 | | - #[inline] |
191 | | - pub fn new_float(&self, value: f64) -> PyRef<PyFloat> { |
192 | | - PyRef::new_ref(PyFloat::from(value), self.types.float_type.clone(), None) |
193 | | - } |
194 | | - |
195 | | - #[inline] |
196 | | - pub fn new_str(&self, s: impl Into<pystr::PyStr>) -> PyRef<PyStr> { |
197 | | - pystr::PyStr::new_ref(s, self) |
198 | | - } |
199 | | - |
200 | | - #[inline] |
201 | | - pub fn new_bytes(&self, data: Vec<u8>) -> PyRef<bytes::PyBytes> { |
202 | | - bytes::PyBytes::new_ref(data, self) |
203 | | - } |
204 | | - |
205 | | - #[inline(always)] |
206 | | - pub fn new_bool(&self, b: bool) -> PyIntRef { |
207 | | - let value = if b { |
208 | | - &self.true_value |
209 | | - } else { |
210 | | - &self.false_value |
211 | | - }; |
212 | | - value.clone() |
213 | | - } |
214 | | - |
215 | | - #[inline(always)] |
216 | | - pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyTupleRef { |
217 | | - PyTuple::new_ref(elements, self) |
218 | | - } |
219 | | - |
220 | | - #[inline(always)] |
221 | | - pub fn new_list(&self, elements: Vec<PyObjectRef>) -> PyListRef { |
222 | | - PyList::new_ref(elements, self) |
223 | | - } |
224 | | - |
225 | | - #[inline(always)] |
226 | | - pub fn new_dict(&self) -> PyDictRef { |
227 | | - PyDict::new_ref(self) |
228 | | - } |
229 | | - |
230 | | - pub fn new_class( |
231 | | - &self, |
232 | | - module: Option<&str>, |
233 | | - name: &str, |
234 | | - base: &PyTypeRef, |
235 | | - slots: PyTypeSlots, |
236 | | - ) -> PyTypeRef { |
237 | | - let mut attrs = PyAttributes::default(); |
238 | | - if let Some(module) = module { |
239 | | - attrs.insert("__module__".to_string(), self.new_str(module).into()); |
240 | | - }; |
241 | | - PyType::new_ref( |
242 | | - name, |
243 | | - vec![base.clone()], |
244 | | - attrs, |
245 | | - slots, |
246 | | - self.types.type_type.clone(), |
247 | | - ) |
248 | | - .unwrap() |
249 | | - } |
250 | | - |
251 | | - pub fn new_exception_type( |
252 | | - &self, |
253 | | - module: &str, |
254 | | - name: &str, |
255 | | - bases: Option<Vec<PyTypeRef>>, |
256 | | - ) -> PyTypeRef { |
257 | | - let bases = if let Some(bases) = bases { |
258 | | - bases |
259 | | - } else { |
260 | | - vec![self.exceptions.exception_type.clone()] |
261 | | - }; |
262 | | - let mut attrs = PyAttributes::default(); |
263 | | - attrs.insert("__module__".to_owned(), self.new_str(module).into()); |
264 | | - |
265 | | - PyType::new_ref( |
266 | | - name, |
267 | | - bases, |
268 | | - attrs, |
269 | | - PyBaseException::make_slots(), |
270 | | - self.types.type_type.clone(), |
271 | | - ) |
272 | | - .unwrap() |
273 | | - } |
274 | | - |
275 | | - #[inline] |
276 | | - pub fn make_funcdef<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyNativeFuncDef |
277 | | - where |
278 | | - F: IntoPyNativeFunc<FKind>, |
279 | | - { |
280 | | - PyNativeFuncDef::new(f.into_func(), PyStr::new_ref(name, self)) |
281 | | - } |
282 | | - |
283 | | - // #[deprecated] |
284 | | - pub fn new_function<F, FKind>(&self, name: impl Into<PyStr>, f: F) -> PyRef<PyBuiltinFunction> |
285 | | - where |
286 | | - F: IntoPyNativeFunc<FKind>, |
287 | | - { |
288 | | - self.make_funcdef(name, f).build_function(self) |
289 | | - } |
290 | | - |
291 | | - pub fn new_method<F, FKind>( |
292 | | - &self, |
293 | | - name: impl Into<PyStr>, |
294 | | - class: PyTypeRef, |
295 | | - f: F, |
296 | | - ) -> PyRef<PyBuiltinMethod> |
297 | | - where |
298 | | - F: IntoPyNativeFunc<FKind>, |
299 | | - { |
300 | | - PyBuiltinMethod::new_ref(name, class, f, self) |
301 | | - } |
302 | | - |
303 | | - pub fn new_readonly_getset<F, T>( |
304 | | - &self, |
305 | | - name: impl Into<String>, |
306 | | - class: PyTypeRef, |
307 | | - f: F, |
308 | | - ) -> PyRef<PyGetSet> |
309 | | - where |
310 | | - F: IntoPyGetterFunc<T>, |
311 | | - { |
312 | | - PyRef::new_ref( |
313 | | - PyGetSet::new(name.into(), class).with_get(f), |
314 | | - self.types.getset_type.clone(), |
315 | | - None, |
316 | | - ) |
317 | | - } |
318 | | - |
319 | | - pub fn new_getset<G, S, T, U>( |
320 | | - &self, |
321 | | - name: impl Into<String>, |
322 | | - class: PyTypeRef, |
323 | | - g: G, |
324 | | - s: S, |
325 | | - ) -> PyRef<PyGetSet> |
326 | | - where |
327 | | - G: IntoPyGetterFunc<T>, |
328 | | - S: IntoPySetterFunc<U>, |
329 | | - { |
330 | | - PyRef::new_ref( |
331 | | - PyGetSet::new(name.into(), class).with_get(g).with_set(s), |
332 | | - self.types.getset_type.clone(), |
333 | | - None, |
334 | | - ) |
335 | | - } |
336 | | - |
337 | | - pub fn new_base_object(&self, class: PyTypeRef, dict: Option<PyDictRef>) -> PyObjectRef { |
338 | | - debug_assert_eq!( |
339 | | - class.slots.flags.contains(PyTypeFlags::HAS_DICT), |
340 | | - dict.is_some() |
341 | | - ); |
342 | | - PyRef::new_ref(object::PyBaseObject, class, dict).into() |
343 | | - } |
344 | | -} |
345 | | - |
346 | | -impl Default for PyContext { |
347 | | - fn default() -> Self { |
348 | | - rustpython_common::static_cell! { |
349 | | - static CONTEXT: PyContext; |
350 | | - } |
351 | | - CONTEXT.get_or_init(Self::init).clone() |
352 | | - } |
353 | | -} |
354 | | - |
355 | 43 | impl<T: fmt::Display> fmt::Display for PyRef<T> |
356 | 44 | where |
357 | 45 | T: PyObjectPayload + fmt::Display, |
|
0 commit comments