@@ -9,7 +9,10 @@ use core::ffi::{c_char, c_int, c_uint, c_ulong, c_void};
99use core:: ptr;
1010use rustpython_vm:: builtins:: { PyStr , PyType } ;
1111use rustpython_vm:: function:: { ItemDoc , PyMethodFlags } ;
12- use rustpython_vm:: types:: { AtomicPyTypeFlags , PyTypeFlags , PyTypeSlots , SlotAccessor } ;
12+ use rustpython_vm:: types:: {
13+ AtomicPyTypeFlags , PyTypeFlags , PyTypeSlots ,
14+ SlotAccessor :: { TpBase , TpDealloc , TpDoc , TpGetset , TpMembers , TpMethods , TpNew , TpTraverse } ,
15+ } ;
1316use rustpython_vm:: { AsObject , Py , PyObject } ;
1417
1518pub type PyTypeObject = Py < PyType > ;
@@ -32,25 +35,6 @@ pub struct PyType_Spec {
3235 pub slots : * mut PyType_Slot ,
3336}
3437
35- impl PyType_Slot {
36- pub ( crate ) fn iter < ' a > ( mut slots : * const Self ) -> impl Iterator < Item = & ' a Self > {
37- core:: iter:: from_fn ( move || {
38- let slot = unsafe { & * slots } ;
39- if slot. slot == 0 {
40- None
41- } else {
42- slots = unsafe { slots. add ( 1 ) } ;
43- Some ( slot)
44- }
45- } )
46- }
47-
48- fn as_slot_accessor ( & self ) -> Option < SlotAccessor > {
49- let slot_id: u8 = self . slot . try_into ( ) . ok ( ) ?;
50- slot_id. try_into ( ) . ok ( )
51- }
52- }
53-
5438#[ unsafe( no_mangle) ]
5539pub unsafe extern "C" fn Py_TYPE ( op : * mut PyObject ) -> * const PyTypeObject {
5640 unsafe { op. assume_borrowed ( ) } . class ( )
@@ -148,64 +132,38 @@ pub unsafe extern "C" fn PyType_FromSlots(slots: *const PySlot) -> *mut PyObject
148132 ) ) ;
149133 }
150134 }
151- PySlotType :: Slots { value, .. } => {
152- for slot in PyType_Slot :: iter ( value) {
153- let accessor = slot. as_slot_accessor ( ) . ok_or_else ( || {
154- vm. new_value_error ( format ! (
155- "Invalid slot id: {} for PyType_FromSlots" ,
156- slot. slot
157- ) )
158- } ) ?;
159- match accessor {
160- SlotAccessor :: TpDoc => {
161- let doc = unsafe {
162- slot. pfunc . cast :: < c_char > ( ) . try_as_str_opt ( vm) ?
163- }
164- . map_or (
165- ItemDoc :: NONE ,
166- |doc| {
167- let text: & ' static str =
168- Box :: leak ( doc. to_owned ( ) . into_boxed_str ( ) ) ;
169- ItemDoc :: static_text ( text)
170- } ,
171- ) ;
172- type_slots. doc = doc;
173- }
174- SlotAccessor :: TpNew => {
175- type_slots. new . store ( Some ( |ty, _args, vm| {
176- Err ( vm. new_not_implemented_error ( format ! ( "tp_new is not yet implemented in PyType_FromSlots for {ty:?}" ) ) )
177- } ) ) ;
178- }
179- SlotAccessor :: TpBase => {
180- base = unsafe { Some ( & * slot. pfunc . cast :: < PyTypeObject > ( ) ) }
181- }
182- SlotAccessor :: TpDealloc => {
183- //TODO
184- }
185- SlotAccessor :: TpMethods => {
186- for def in PyMethodDef :: iter ( slot. pfunc . cast ( ) ) {
187- let name = unsafe { def. ml_name . try_as_str ( vm) ? } ;
188- let is_static =
189- PyMethodFlags :: from_bits_retain ( def. ml_flags as _ )
190- . contains ( PyMethodFlags :: STATIC ) ;
191- let method = build_method_def ( vm, def, !is_static) ?;
192- methods. push ( ( name, method) ) ;
193- }
194- }
195- SlotAccessor :: TpGetset => {
196- getsets. extend ( PyGetSetDef :: iter ( slot. pfunc . cast ( ) ) ) ;
197- }
198- SlotAccessor :: TpMembers => {
199- members. extend ( PyMemberDef :: iter ( slot. pfunc . cast ( ) ) ) ;
200- }
201- slot => {
202- return Err ( vm. new_not_implemented_error ( format ! (
203- "PyType_FromSlots with PyType_Slot {slot:?} not implemented yet"
204- ) ) ) ;
205- }
206- }
135+ PySlotType :: TypeSlot ( TpDoc , pfunc) => {
136+ let doc = unsafe { pfunc. cast :: < c_char > ( ) . try_as_str_opt ( vm) ? } . map_or (
137+ ItemDoc :: NONE ,
138+ |doc| {
139+ let text: & ' static str =
140+ Box :: leak ( doc. to_owned ( ) . into_boxed_str ( ) ) ;
141+ ItemDoc :: static_text ( text)
142+ } ,
143+ ) ;
144+ type_slots. doc = doc;
145+ }
146+ PySlotType :: TypeSlot ( TpBase , pfunc) => {
147+ base = unsafe { Some ( & * pfunc. cast :: < PyTypeObject > ( ) ) }
148+ }
149+ PySlotType :: TypeSlot ( TpMembers , pfunc) => {
150+ members. extend ( PyMemberDef :: iter ( pfunc. cast ( ) ) ) ;
151+ }
152+ PySlotType :: TypeSlot ( TpGetset , pfunc) => {
153+ getsets. extend ( PyGetSetDef :: iter ( pfunc. cast ( ) ) ) ;
154+ }
155+ PySlotType :: TypeSlot ( TpMethods , pfunc) => {
156+ for def in PyMethodDef :: iter ( pfunc. cast ( ) ) {
157+ let name = unsafe { def. ml_name . try_as_str ( vm) ? } ;
158+ let is_static = PyMethodFlags :: from_bits_retain ( def. ml_flags as _ )
159+ . contains ( PyMethodFlags :: STATIC ) ;
160+ let method = build_method_def ( vm, def, !is_static) ?;
161+ methods. push ( ( name, method) ) ;
207162 }
208163 }
164+ PySlotType :: TypeSlot ( TpNew | TpDealloc | TpTraverse , _) => {
165+ // TODO
166+ }
209167 _ => {
210168 return Err ( vm. new_not_implemented_error ( format ! (
211169 "PyType_FromSlots with slot {kind:?} not implemented yet"
0 commit comments