11use crate :: common:: { hash:: PyHash , lock:: PyRwLock } ;
22use crate :: {
3- builtins:: { PyInt , PyStrInterned , PyStrRef , PyType , PyTypeRef } ,
3+ builtins:: { PyFloat , PyInt , PyStrInterned , PyStrRef , PyType , PyTypeRef } ,
44 bytecode:: ComparisonOperator ,
55 convert:: ToPyResult ,
66 function:: Either ,
@@ -205,6 +205,30 @@ fn slot_as_sequence(zelf: &PyObject, vm: &VirtualMachine) -> &'static PySequence
205205 PySequenceMethods :: generic ( has_length, has_ass_item)
206206}
207207
208+ fn int_wrapper ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyInt > > {
209+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __int__) , ( ) ) ?;
210+ ret. downcast :: < PyInt > ( ) . map_err ( |obj| {
211+ vm. new_type_error ( format ! ( "__int__ returned non-int (type {})" , obj. class( ) ) )
212+ } )
213+ }
214+
215+ fn index_wrapper ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyInt > > {
216+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __index__) , ( ) ) ?;
217+ ret. downcast :: < PyInt > ( ) . map_err ( |obj| {
218+ vm. new_type_error ( format ! ( "__index__ returned non-int (type {})" , obj. class( ) ) )
219+ } )
220+ }
221+
222+ fn float_wrapper ( num : & PyNumber , vm : & VirtualMachine ) -> PyResult < PyRef < PyFloat > > {
223+ let ret = vm. call_special_method ( num. obj . to_owned ( ) , identifier ! ( vm, __float__) , ( ) ) ?;
224+ ret. downcast :: < PyFloat > ( ) . map_err ( |obj| {
225+ vm. new_type_error ( format ! (
226+ "__float__ returned non-float (type {})" ,
227+ obj. class( )
228+ ) )
229+ } )
230+ }
231+
208232fn hash_wrapper ( zelf : & PyObject , vm : & VirtualMachine ) -> PyResult < PyHash > {
209233 let hash_obj = vm. call_special_method ( zelf. to_owned ( ) , identifier ! ( vm, __hash__) , ( ) ) ?;
210234 match hash_obj. payload_if_subclass :: < PyInt > ( vm) {
@@ -318,21 +342,37 @@ impl PyType {
318342 debug_assert ! ( name. as_str( ) . starts_with( "__" ) ) ;
319343 debug_assert ! ( name. as_str( ) . ends_with( "__" ) ) ;
320344
321- macro_rules! update_slot {
345+ macro_rules! toggle_slot {
322346 ( $name: ident, $func: expr) => { {
323347 self . slots. $name. store( if add { Some ( $func) } else { None } ) ;
324348 } } ;
325349 }
350+
351+ macro_rules! update_slot {
352+ ( $name: ident, $func: expr) => { {
353+ self . slots. $name. store( Some ( $func) ) ;
354+ } } ;
355+ }
356+
357+ macro_rules! update_pointer_slot {
358+ ( $name: ident, $pointed: ident) => { {
359+ self . slots. $name. store(
360+ self . heaptype_ext
361+ . as_ref( )
362+ . map( |ext| NonNull :: from( & ext. $pointed) ) ,
363+ ) ;
364+ } } ;
365+ }
326366 match name. as_str ( ) {
327367 "__len__" | "__getitem__" | "__setitem__" | "__delitem__" => {
328368 update_slot ! ( as_mapping, slot_as_mapping) ;
329369 update_slot ! ( as_sequence, slot_as_sequence) ;
330370 }
331371 "__hash__" => {
332- update_slot ! ( hash, hash_wrapper) ;
372+ toggle_slot ! ( hash, hash_wrapper) ;
333373 }
334374 "__call__" => {
335- update_slot ! ( call, call_wrapper) ;
375+ toggle_slot ! ( call, call_wrapper) ;
336376 }
337377 "__getattr__" | "__getattribute__" => {
338378 update_slot ! ( getattro, getattro_wrapper) ;
@@ -344,28 +384,52 @@ impl PyType {
344384 update_slot ! ( richcompare, richcompare_wrapper) ;
345385 }
346386 "__iter__" => {
347- update_slot ! ( iter, iter_wrapper) ;
387+ toggle_slot ! ( iter, iter_wrapper) ;
348388 }
349389 "__next__" => {
350- update_slot ! ( iternext, iternext_wrapper) ;
390+ toggle_slot ! ( iternext, iternext_wrapper) ;
351391 }
352392 "__get__" => {
353- update_slot ! ( descr_get, descr_get_wrapper) ;
393+ toggle_slot ! ( descr_get, descr_get_wrapper) ;
354394 }
355395 "__set__" | "__delete__" => {
356396 update_slot ! ( descr_set, descr_set_wrapper) ;
357397 }
358398 "__init__" => {
359- update_slot ! ( init, init_wrapper) ;
399+ toggle_slot ! ( init, init_wrapper) ;
360400 }
361401 "__new__" => {
362- update_slot ! ( new, new_wrapper) ;
402+ toggle_slot ! ( new, new_wrapper) ;
363403 }
364404 "__del__" => {
365- update_slot ! ( del, del_wrapper) ;
405+ toggle_slot ! ( del, del_wrapper) ;
406+ }
407+ "__int__" => {
408+ self . heaptype_ext
409+ . as_ref ( )
410+ . unwrap ( )
411+ . number_methods
412+ . int
413+ . store ( Some ( int_wrapper) ) ;
414+ update_pointer_slot ! ( as_number, number_methods) ;
366415 }
367- "__int__" | "__index__" | "__float__" => {
368- // update_slot!(as_number, slot_as_number);
416+ "__index__" => {
417+ self . heaptype_ext
418+ . as_ref ( )
419+ . unwrap ( )
420+ . number_methods
421+ . index
422+ . store ( Some ( index_wrapper) ) ;
423+ update_pointer_slot ! ( as_number, number_methods) ;
424+ }
425+ "__float__" => {
426+ self . heaptype_ext
427+ . as_ref ( )
428+ . unwrap ( )
429+ . number_methods
430+ . float
431+ . store ( Some ( float_wrapper) ) ;
432+ update_pointer_slot ! ( as_number, number_methods) ;
369433 }
370434 _ => { }
371435 }
@@ -871,15 +935,8 @@ pub trait AsSequence: PyPayload {
871935
872936#[ pyimpl]
873937pub trait AsNumber : PyPayload {
874- // const AS_NUMBER: PyNumberMethods;
875-
876938 #[ pyslot]
877939 fn as_number ( ) -> & ' static PyNumberMethods ;
878- // #[inline]
879- // #[pyslot]
880- // fn as_number() -> &'static PyNumberMethods {
881- // &Self::AS_NUMBER
882- // }
883940
884941 fn number_downcast < ' a > ( number : & ' a PyNumber ) -> & ' a Py < Self > {
885942 unsafe { number. obj . downcast_unchecked_ref ( ) }
0 commit comments