|
1 | | -use core::ffi::c_ulong; |
2 | | - |
3 | 1 | use crate::PyObject; |
| 2 | +use core::ffi::c_ulong; |
4 | 3 | use rustpython_vm::builtins::PyType; |
5 | 4 | use rustpython_vm::{AsObject, Context, Py}; |
6 | 5 | use std::sync::LazyLock; |
7 | 6 |
|
8 | 7 | pub struct PyTypeObject { |
9 | 8 | ty: LazyLock<&'static Py<PyType>>, |
10 | | - flags: c_ulong, |
11 | 9 | } |
12 | 10 |
|
13 | 11 | impl PyTypeObject { |
14 | | - const fn new(f: fn() -> &'static Py<PyType>, flags: c_ulong) -> PyTypeObject { |
| 12 | + const fn new(f: fn() -> &'static Py<PyType>) -> PyTypeObject { |
15 | 13 | PyTypeObject { |
16 | 14 | ty: LazyLock::new(f), |
17 | | - flags, |
18 | 15 | } |
19 | 16 | } |
20 | 17 | } |
21 | 18 |
|
22 | | -const PY_TPFLAGS_HAVE_STACKLESS_EXTENSION: c_ulong = 0; |
23 | | -const PY_TPFLAGS_HAVE_VERSION_TAG: c_ulong = 1 << 18; |
24 | | -const PY_TPFLAGS_DEFAULT: c_ulong = |
25 | | - PY_TPFLAGS_HAVE_STACKLESS_EXTENSION | PY_TPFLAGS_HAVE_VERSION_TAG; |
26 | | -const PY_TPFLAGS_IMMUTABLETYPE: c_ulong = 1 << 8; |
27 | | -const PY_TPFLAGS_BASETYPE: c_ulong = 1 << 10; |
28 | 19 | const PY_TPFLAGS_LONG_SUBCLASS: c_ulong = 1 << 24; |
| 20 | +const PY_TPFLAGS_LIST_SUBCLASS: c_ulong = 1 << 25; |
29 | 21 | const PY_TPFLAGS_TUPLE_SUBCLASS: c_ulong = 1 << 26; |
| 22 | +const PY_TPFLAGS_BYTES_SUBCLASS: c_ulong = 1 << 27; |
30 | 23 | const PY_TPFLAGS_UNICODE_SUBCLASS: c_ulong = 1 << 28; |
| 24 | +const PY_TPFLAGS_DICT_SUBCLASS: c_ulong = 1 << 29; |
| 25 | +const PY_TPFLAGS_BASE_EXC_SUBCLASS: c_ulong = 1 << 30; |
31 | 26 | const PY_TPFLAGS_TYPE_SUBCLASS: c_ulong = 1 << 31; |
32 | 27 |
|
33 | 28 | #[unsafe(no_mangle)] |
34 | | -pub static mut PyType_Type: PyTypeObject = PyTypeObject::new( |
35 | | - || { |
36 | | - let zoo = &Context::genesis().types; |
37 | | - zoo.type_type |
38 | | - }, |
39 | | - PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_TYPE_SUBCLASS, |
40 | | -); |
| 29 | +pub static mut PyType_Type: PyTypeObject = PyTypeObject::new(|| { |
| 30 | + let zoo = &Context::genesis().types; |
| 31 | + zoo.type_type |
| 32 | +}); |
41 | 33 |
|
42 | 34 | #[unsafe(no_mangle)] |
43 | | -pub static mut PyLong_Type: PyTypeObject = PyTypeObject::new( |
44 | | - || { |
45 | | - let zoo = &Context::genesis().types; |
46 | | - zoo.int_type |
47 | | - }, |
48 | | - PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_LONG_SUBCLASS, |
49 | | -); |
| 35 | +pub static mut PyLong_Type: PyTypeObject = PyTypeObject::new(|| { |
| 36 | + let zoo = &Context::genesis().types; |
| 37 | + zoo.int_type |
| 38 | +}); |
50 | 39 |
|
51 | 40 | #[unsafe(no_mangle)] |
52 | | -pub static mut PyTuple_Type: PyTypeObject = PyTypeObject::new( |
53 | | - || { |
54 | | - let zoo = &Context::genesis().types; |
55 | | - zoo.tuple_type |
56 | | - }, |
57 | | - PY_TPFLAGS_DEFAULT | PY_TPFLAGS_IMMUTABLETYPE | PY_TPFLAGS_BASETYPE | PY_TPFLAGS_TUPLE_SUBCLASS, |
58 | | -); |
| 41 | +pub static mut PyTuple_Type: PyTypeObject = PyTypeObject::new(|| { |
| 42 | + let zoo = &Context::genesis().types; |
| 43 | + zoo.tuple_type |
| 44 | +}); |
59 | 45 |
|
60 | 46 | #[unsafe(no_mangle)] |
61 | | -pub static mut PyUnicode_Type: PyTypeObject = PyTypeObject::new( |
62 | | - || { |
63 | | - let zoo = &Context::genesis().types; |
64 | | - zoo.str_type |
65 | | - }, |
66 | | - PY_TPFLAGS_DEFAULT |
67 | | - | PY_TPFLAGS_IMMUTABLETYPE |
68 | | - | PY_TPFLAGS_BASETYPE |
69 | | - | PY_TPFLAGS_UNICODE_SUBCLASS, |
70 | | -); |
| 47 | +pub static mut PyUnicode_Type: PyTypeObject = PyTypeObject::new(|| { |
| 48 | + let zoo = &Context::genesis().types; |
| 49 | + zoo.str_type |
| 50 | +}); |
71 | 51 |
|
72 | 52 | #[unsafe(no_mangle)] |
73 | 53 | pub extern "C" fn Py_TYPE(op: *mut PyObject) -> *mut PyTypeObject { |
@@ -98,8 +78,38 @@ pub extern "C" fn PyType_GetFlags(ty: *mut PyTypeObject) -> c_ulong { |
98 | 78 | panic!("PyType_GetFlags called with null type pointer"); |
99 | 79 | } |
100 | 80 |
|
101 | | - // SAFETY: caller guarantees this is a valid exported type object pointer. |
102 | | - unsafe { (*ty).flags } |
| 81 | + let ctx =Context::genesis(); |
| 82 | + let zoo = &ctx.types; |
| 83 | + let exp_zoo = &ctx.exceptions; |
| 84 | + let ty_inner = unsafe { *(*ty).ty }; |
| 85 | + let mut flags = ty_inner.slots.flags.bits(); |
| 86 | + |
| 87 | + if ty_inner.is_subtype(zoo.int_type) { |
| 88 | + flags |= PY_TPFLAGS_LONG_SUBCLASS; |
| 89 | + } |
| 90 | + if ty_inner.is_subtype(zoo.list_type) { |
| 91 | + flags |= PY_TPFLAGS_LIST_SUBCLASS |
| 92 | + } |
| 93 | + if ty_inner.is_subtype(zoo.tuple_type) { |
| 94 | + flags |= PY_TPFLAGS_TUPLE_SUBCLASS; |
| 95 | + } |
| 96 | + if ty_inner.is_subtype(zoo.bytes_type) { |
| 97 | + flags |= PY_TPFLAGS_BYTES_SUBCLASS; |
| 98 | + } |
| 99 | + if ty_inner.is_subtype(zoo.str_type) { |
| 100 | + flags |= PY_TPFLAGS_UNICODE_SUBCLASS; |
| 101 | + } |
| 102 | + if ty_inner.is_subtype(zoo.dict_type) { |
| 103 | + flags |= PY_TPFLAGS_DICT_SUBCLASS; |
| 104 | + } |
| 105 | + if ty_inner.is_subtype(exp_zoo.base_exception_type) { |
| 106 | + flags |= PY_TPFLAGS_BASE_EXC_SUBCLASS; |
| 107 | + } |
| 108 | + if ty_inner.is_subtype(zoo.type_type) { |
| 109 | + flags |= PY_TPFLAGS_TYPE_SUBCLASS; |
| 110 | + } |
| 111 | + |
| 112 | + flags |
103 | 113 | } |
104 | 114 |
|
105 | 115 | #[unsafe(no_mangle)] |
|
0 commit comments