2121
2222namespace IronPython . Modules {
2323 /// <summary>
24- /// Provides helper functions which need to be called from generated code to implement various
24+ /// Provides helper functions which need to be called from generated code to implement various
2525 /// portions of modules.
2626 /// </summary>
2727 public static partial class ModuleOps {
@@ -110,7 +110,7 @@ public static CTypes.CData CheckSimpleCDataType(object o, object type) {
110110 if ( res == null && PythonOps . TryGetBoundAttr ( o , "_as_parameter_" , out object asParam ) ) {
111111 res = asParam as CTypes . _CFuncPtr ;
112112 }
113-
113+
114114 if ( res == null || res . NativeType != type ) {
115115 throw ArgumentError ( type , ( ( PythonType ) type ) . Name , o ) ;
116116 }
@@ -298,9 +298,6 @@ public static IntPtr GetPointer(object value) {
298298 }
299299
300300 if ( value is int iVal ) {
301- if ( iVal > int . MaxValue ) {
302- iVal = - 1 ;
303- }
304301 return new IntPtr ( iVal ) ;
305302 }
306303
@@ -357,13 +354,8 @@ public static IntPtr GetObject(object value) {
357354 }
358355
359356 public static long GetSignedLongLong ( object value , object type ) {
360- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
361- if ( res != null ) {
362- return res . Value ;
363- }
364-
365- if ( value is BigInteger ) {
366- return ( long ) ( BigInteger ) value ;
357+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
358+ return unchecked ( ( long ) ( ulong ) ( bi & ulong . MaxValue ) ) ;
367359 }
368360
369361 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -373,14 +365,9 @@ public static long GetSignedLongLong(object value, object type) {
373365 throw PythonOps . TypeErrorForTypeMismatch ( "signed long long " , value ) ;
374366 }
375367
376- public static long GetUnsignedLongLong ( object value , object type ) {
377- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
378- if ( res != null && res . Value >= 0 ) {
379- return res . Value ;
380- }
381-
382- if ( value is BigInteger ) {
383- return ( long ) ( ulong ) ( BigInteger ) value ;
368+ public static ulong GetUnsignedLongLong ( object value , object type ) {
369+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
370+ return ( ulong ) ( bi & ulong . MaxValue ) ;
384371 }
385372
386373 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -463,17 +450,8 @@ public static int GetSingleBits(object value) {
463450 }
464451
465452 public static int GetSignedLong ( object value , object type ) {
466- if ( value is int ) {
467- return ( int ) value ;
468- }
469-
470- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
471- if ( res != null ) {
472- return res . Value ;
473- }
474-
475- if ( value is BigInteger && ( ( BigInteger ) value ) . AsUInt32 ( out uint unsigned ) ) {
476- return ( int ) unsigned ;
453+ if ( TryToIntStrict ( value , out BigInteger bi ) ) {
454+ return unchecked ( ( int ) ( uint ) ( bi & uint . MaxValue ) ) ;
477455 }
478456
479457 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -483,16 +461,9 @@ public static int GetSignedLong(object value, object type) {
483461 throw PythonOps . TypeErrorForTypeMismatch ( "signed long" , value ) ;
484462 }
485463
486- public static int GetUnsignedLong ( object value , object type ) {
487- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
488- if ( res != null ) {
489- return res . Value ;
490- }
491-
492- if ( value is BigInteger ) {
493- if ( ( ( BigInteger ) value ) . AsUInt32 ( out uint ures ) ) {
494- return ( int ) ures ;
495- }
464+ public static uint GetUnsignedLong ( object value , object type ) {
465+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
466+ return ( uint ) ( bi & uint . MaxValue ) ;
496467 }
497468
498469 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -502,24 +473,23 @@ public static int GetUnsignedLong(object value, object type) {
502473 throw PythonOps . TypeErrorForTypeMismatch ( "unsigned long" , value ) ;
503474 }
504475
505- public static int GetUnsignedInt ( object value , object type ) {
506- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
507- if ( res != null && res . Value >= 0 ) {
508- return res . Value ;
476+ public static uint GetUnsignedInt ( object value , object type ) {
477+ if ( TryToIntStrict ( value , out BigInteger bi ) ) {
478+ return ( uint ) ( bi & uint . MaxValue ) ;
509479 }
510480
511481 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
512- return GetUnsignedInt ( type , asParam ) ;
482+ return GetUnsignedInt ( asParam , type ) ;
513483 }
514484
515485 throw PythonOps . TypeErrorForTypeMismatch ( "unsigned int" , value ) ;
516486 }
517487
518488 public static int GetSignedInt ( object value , object type ) {
519- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
520- if ( res != null ) {
521- return res . Value ;
489+ if ( TryToIntStrict ( value , out BigInteger bi ) ) {
490+ return unchecked ( ( int ) ( bi & uint . MaxValue ) ) ;
522491 }
492+
523493 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
524494 return GetSignedInt ( asParam , type ) ;
525495 }
@@ -528,13 +498,10 @@ public static int GetSignedInt(object value, object type) {
528498 }
529499
530500 public static ushort GetUnsignedShort ( object value , object type ) {
531- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
532- if ( res != null ) {
533- int iVal = res . Value ;
534- if ( iVal >= ushort . MinValue && iVal <= ushort . MaxValue ) {
535- return ( ushort ) iVal ;
536- }
501+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
502+ return ( ushort ) ( bi & ushort . MaxValue ) ;
537503 }
504+
538505 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
539506 return GetUnsignedShort ( asParam , type ) ;
540507 }
@@ -543,12 +510,8 @@ public static ushort GetUnsignedShort(object value, object type) {
543510 }
544511
545512 public static short GetSignedShort ( object value , object type ) {
546- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
547- if ( res != null ) {
548- int iVal = res . Value ;
549- return ( short ) iVal ;
550- } else if ( value is BigInteger bigInt ) {
551- return ( short ) ( int ) ( bigInt & 0xffff ) ;
513+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
514+ return unchecked ( ( short ) ( ushort ) ( bi & ushort . MaxValue ) ) ;
552515 }
553516
554517 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -563,9 +526,8 @@ public static int GetVariantBool(object value, object type) {
563526 }
564527
565528 public static byte GetUnsignedByte ( object value , object type ) {
566- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
567- if ( res != null ) {
568- return ( byte ) res . Value ;
529+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
530+ return ( byte ) ( bi & byte . MaxValue ) ;
569531 }
570532
571533 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -576,12 +538,8 @@ public static byte GetUnsignedByte(object value, object type) {
576538 }
577539
578540 public static sbyte GetSignedByte ( object value , object type ) {
579- int ? res = Converter . ImplicitConvertToInt32 ( value ) ;
580- if ( res != null ) {
581- int iVal = res . Value ;
582- if ( iVal >= sbyte . MinValue && iVal <= sbyte . MaxValue ) {
583- return ( sbyte ) iVal ;
584- }
541+ if ( PythonOps . TryToInt ( value , out BigInteger bi ) ) {
542+ return unchecked ( ( sbyte ) ( byte ) ( bi & byte . MaxValue ) ) ;
585543 }
586544
587545 if ( PythonOps . TryGetBoundAttr ( value , "_as_parameter_" , out object asParam ) ) {
@@ -639,7 +597,7 @@ public static char GetWChar(object value, object type) {
639597 return GetWChar ( asParam , type ) ;
640598 }
641599
642- throw PythonOps . TypeError ( "unicode string expected instead of {0} instance" , PythonOps . GetPythonTypeName ( value ) ) ;
600+ throw PythonOps . TypeErrorForBadInstance ( "unicode string expected instead of {0} instance" , value ) ;
643601 }
644602
645603 public static object IntPtrToObject ( IntPtr address ) {
@@ -650,6 +608,22 @@ public static object IntPtrToObject(IntPtr address) {
650608 return res ;
651609 }
652610
611+ internal static bool TryToIntStrict ( object value , out BigInteger bi ) {
612+ // When IronPython upgrades to Python 3.10, this method becomes obsolete
613+ // and can be replaced with PythonOps.TryToIndex(value, out bi)
614+ if ( IsFloatingPoint ( value ) ) {
615+ throw PythonOps . TypeErrorForBadInstance ( "int expected instead of {0}" , value ) ;
616+ }
617+
618+ return PythonOps . TryToInt ( value , out bi ) ;
619+ }
620+
621+ internal static bool IsFloatingPoint ( object value )
622+ => value is double or float
623+ #if NETCOREAPP
624+ or Half
625+ #endif
626+ ;
653627 }
654628}
655629#endif
0 commit comments