40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .cext .common ;
42
42
43
+ import static com .oracle .graal .python .builtins .PythonBuiltinClassType .OverflowError ;
43
44
import static com .oracle .graal .python .runtime .exception .PythonErrorType .LookupError ;
44
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .SystemError ;
45
46
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
74
75
import com .oracle .graal .python .nodes .util .CastToJavaLongLossyNode ;
75
76
import com .oracle .graal .python .nodes .util .CastToJavaStringNode ;
76
77
import com .oracle .graal .python .runtime .PythonOptions ;
77
- import com .oracle .graal .python .runtime .exception .PythonErrorType ;
78
78
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
79
79
import com .oracle .graal .python .util .OverflowException ;
80
80
import com .oracle .truffle .api .CompilerAsserts ;
101
101
import com .oracle .truffle .api .nodes .Node ;
102
102
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
103
103
import com .oracle .truffle .api .profiles .BranchProfile ;
104
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
104
105
105
106
public abstract class CExtCommonNodes {
106
107
@@ -398,27 +399,93 @@ public final int executeInt(Frame frame, Object o, int signed, long targetTypeSi
398
399
}
399
400
400
401
@ Specialization (guards = {"targetTypeSize == 4" , "signed != 0" , "fitsInInt32(nativeWrapper)" })
401
- static long doPrimitiveNativeWrapperToInt32 (PrimitiveNativeWrapper nativeWrapper , @ SuppressWarnings ("unused" ) int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ) {
402
+ @ SuppressWarnings ("unused" )
403
+ static int doWrapperToInt32 (PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ) {
402
404
return nativeWrapper .getInt ();
403
405
}
404
406
405
- @ Specialization (guards = {"targetTypeSize == 8" , "fitsInInt64(nativeWrapper)" })
406
- static long doPrimitiveNativeWrapperToInt64 (PrimitiveNativeWrapper nativeWrapper , @ SuppressWarnings ("unused" ) int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ) {
407
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed != 0" , "fitsInInt64(nativeWrapper)" })
408
+ @ SuppressWarnings ("unused" )
409
+ static long doWrapperToInt64 (PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ) {
407
410
return nativeWrapper .getLong ();
408
411
}
409
412
410
- @ Specialization (guards = "targetTypeSize == 4" )
411
- static long doInt4 (int obj , @ SuppressWarnings ("unused" ) int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ) {
412
- return obj ;
413
+ @ Specialization (guards = {"targetTypeSize == 4" , "signed == 0" , "fitsInUInt32(nativeWrapper)" })
414
+ @ SuppressWarnings ("unused" )
415
+ static int doWrapperToUInt32Pos (PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ) {
416
+ return nativeWrapper .getInt ();
413
417
}
414
418
415
- @ Specialization (guards = "targetTypeSize == 8" )
416
- static long doInt8 (int obj , int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ) {
417
- if (signed != 0 ) {
418
- return obj ;
419
- } else {
420
- return obj & 0xFFFFFFFFL ;
419
+ @ Specialization (guards = {"targetTypeSize == 4" , "signed == 0" , "fitsInInt32(nativeWrapper)" }, replaces = "doWrapperToUInt32Pos" )
420
+ @ SuppressWarnings ("unused" )
421
+ static int doWrapperToUInt32 (Frame frame , PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ,
422
+ @ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ,
423
+ @ Cached ConditionProfile negativeProfile ) {
424
+ return doIntToUInt32 (frame , nativeWrapper .getInt (), signed , targetTypeSize , raiseNativeNode , negativeProfile );
425
+ }
426
+
427
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" , "fitsInUInt64(nativeWrapper)" })
428
+ @ SuppressWarnings ("unused" )
429
+ static long doWrapperToUInt64Pos (PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ) {
430
+ return nativeWrapper .getLong ();
431
+ }
432
+
433
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" , "fitsInInt64(nativeWrapper)" }, replaces = "doWrapperToUInt64Pos" )
434
+ @ SuppressWarnings ("unused" )
435
+ static long doWrapperToUInt64 (Frame frame , PrimitiveNativeWrapper nativeWrapper , int signed , long targetTypeSize ,
436
+ @ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ,
437
+ @ Cached ConditionProfile negativeProfile ) {
438
+ long value = nativeWrapper .getLong ();
439
+ if (negativeProfile .profile (value < 0 )) {
440
+ return raiseNegativeValue (frame , raiseNativeNode );
441
+ }
442
+ return value ;
443
+ }
444
+
445
+ @ Specialization (guards = {"targetTypeSize == 4" , "signed != 0" })
446
+ @ SuppressWarnings ("unused" )
447
+ static long doIntToInt32 (int value , int signed , long targetTypeSize ) {
448
+ return value ;
449
+ }
450
+
451
+ @ Specialization (guards = {"targetTypeSize == 4" , "signed == 0" , "value >= 0" })
452
+ @ SuppressWarnings ("unused" )
453
+ static long doIntToUInt32Pos (int value , int signed , long targetTypeSize ) {
454
+ return value ;
455
+ }
456
+
457
+ @ Specialization (guards = {"targetTypeSize == 4" , "signed == 0" }, replaces = "doIntToUInt32Pos" )
458
+ @ SuppressWarnings ("unused" )
459
+ static int doIntToUInt32 (Frame frame , int value , int signed , long targetTypeSize ,
460
+ @ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ,
461
+ @ Cached ConditionProfile negativeProfile ) {
462
+ if (negativeProfile .profile (value < 0 )) {
463
+ return raiseNegativeValue (frame , raiseNativeNode );
464
+ }
465
+ return value ;
466
+ }
467
+
468
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed != 0" })
469
+ @ SuppressWarnings ("unused" )
470
+ static long doIntToInt64 (int value , int signed , long targetTypeSize ) {
471
+ return value ;
472
+ }
473
+
474
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" , "value >= 0" })
475
+ @ SuppressWarnings ("unused" )
476
+ static long doIntToUInt64Pos (int value , int signed , long targetTypeSize ) {
477
+ return value ;
478
+ }
479
+
480
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" }, replaces = "doIntToUInt64Pos" )
481
+ @ SuppressWarnings ("unused" )
482
+ static int doIntToUInt64 (Frame frame , int value , int signed , long targetTypeSize ,
483
+ @ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ,
484
+ @ Cached ConditionProfile negativeProfile ) {
485
+ if (negativeProfile .profile (value < 0 )) {
486
+ return raiseNegativeValue (frame , raiseNativeNode );
421
487
}
488
+ return value ;
422
489
}
423
490
424
491
@ Specialization (guards = {"targetTypeSize != 4" , "targetTypeSize != 8" })
@@ -433,9 +500,27 @@ static long doLong4(Frame frame, @SuppressWarnings("unused") long obj, @Suppress
433
500
return raiseTooLarge (frame , raiseNativeNode , targetTypeSize );
434
501
}
435
502
436
- @ Specialization (guards = "targetTypeSize == 8" )
437
- static long doLong8 (long obj , @ SuppressWarnings ("unused" ) int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ) {
438
- return obj ;
503
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed != 0" })
504
+ @ SuppressWarnings ("unused" )
505
+ static long doLongToInt64 (int value , int signed , long targetTypeSize ) {
506
+ return value ;
507
+ }
508
+
509
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" , "value >= 0" })
510
+ @ SuppressWarnings ("unused" )
511
+ static long doLongToUInt64Pos (int value , int signed , long targetTypeSize ) {
512
+ return value ;
513
+ }
514
+
515
+ @ Specialization (guards = {"targetTypeSize == 8" , "signed == 0" }, replaces = "doLongToUInt64Pos" )
516
+ @ SuppressWarnings ("unused" )
517
+ static int doLongToUInt64 (Frame frame , int value , int signed , long targetTypeSize ,
518
+ @ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ,
519
+ @ Cached ConditionProfile negativeProfile ) {
520
+ if (negativeProfile .profile (value < 0 )) {
521
+ return raiseNegativeValue (frame , raiseNativeNode );
522
+ }
523
+ return value ;
439
524
}
440
525
441
526
@ Specialization (guards = "targetTypeSize == 8" )
@@ -450,33 +535,41 @@ static long doPInt(Frame frame, @SuppressWarnings("unused") long obj, @SuppressW
450
535
}
451
536
452
537
@ Specialization (guards = "targetTypeSize == 4" )
453
- static long doPInt4 (Frame frame , PInt obj , int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ,
538
+ @ TruffleBoundary
539
+ static int doPIntTo32Bit (PInt obj , int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ,
454
540
@ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ) {
455
541
try {
456
542
if (signed != 0 ) {
457
543
return obj .intValueExact ();
458
544
} else if (obj .bitCount () <= 32 ) {
545
+ if (obj .isNegative ()) {
546
+ return raiseNegativeValue (raiseNativeNode );
547
+ }
459
548
return obj .intValue ();
460
549
}
461
550
} catch (ArithmeticException e ) {
462
551
// fall through
463
552
}
464
- return raiseTooLarge (frame , raiseNativeNode , targetTypeSize );
553
+ return raiseTooLarge (raiseNativeNode , targetTypeSize );
465
554
}
466
555
467
556
@ Specialization (guards = "targetTypeSize == 8" )
468
- static long doPInt8 (Frame frame , PInt obj , int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ,
557
+ @ TruffleBoundary
558
+ static long doPIntTo64Bit (PInt obj , int signed , @ SuppressWarnings ("unused" ) long targetTypeSize ,
469
559
@ Shared ("raiseNativeNode" ) @ Cached PRaiseNativeNode raiseNativeNode ) {
470
560
try {
471
561
if (signed != 0 ) {
472
562
return obj .longValueExact ();
473
563
} else if (obj .bitCount () <= 64 ) {
564
+ if (obj .isNegative ()) {
565
+ return raiseNegativeValue (raiseNativeNode );
566
+ }
474
567
return obj .longValue ();
475
568
}
476
569
} catch (ArithmeticException e ) {
477
570
// fall through
478
571
}
479
- return raiseTooLarge (frame , raiseNativeNode , targetTypeSize );
572
+ return raiseTooLarge (raiseNativeNode , targetTypeSize );
480
573
}
481
574
482
575
@ Specialization (guards = {"targetTypeSize != 4" , "targetTypeSize != 8" })
@@ -491,20 +584,40 @@ static Object doGeneric(Object obj, int signed, long targetTypeSize,
491
584
return asNativePrimitiveNode .execute (obj , signed , (int ) targetTypeSize , true );
492
585
}
493
586
587
+ private static int raiseTooLarge (PRaiseNativeNode raiseNativeNode , long targetTypeSize ) {
588
+ return raiseNativeNode .raiseIntWithoutFrame (-1 , OverflowError , ErrorMessages .PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE , targetTypeSize );
589
+ }
590
+
494
591
private static int raiseTooLarge (Frame frame , PRaiseNativeNode raiseNativeNode , long targetTypeSize ) {
495
- return raiseNativeNode .raiseInt (frame , -1 , PythonErrorType . OverflowError , ErrorMessages .PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE , targetTypeSize );
592
+ return raiseNativeNode .raiseInt (frame , -1 , OverflowError , ErrorMessages .PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE , targetTypeSize );
496
593
}
497
594
498
595
private static Integer raiseUnsupportedSize (Frame frame , PRaiseNativeNode raiseNativeNode , long targetTypeSize ) {
499
596
return raiseNativeNode .raiseInt (frame , -1 , SystemError , ErrorMessages .UNSUPPORTED_TARGET_SIZE , targetTypeSize );
500
597
}
501
598
599
+ private static int raiseNegativeValue (PRaiseNativeNode raiseNativeNode ) {
600
+ return raiseNativeNode .raiseIntWithoutFrame (-1 , OverflowError , ErrorMessages .CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT );
601
+ }
602
+
603
+ private static int raiseNegativeValue (Frame frame , PRaiseNativeNode raiseNativeNode ) {
604
+ return raiseNativeNode .raiseInt (frame , -1 , OverflowError , ErrorMessages .CANNOT_CONVERT_NEGATIVE_VALUE_TO_UNSIGNED_INT );
605
+ }
606
+
502
607
static boolean fitsInInt32 (PrimitiveNativeWrapper nativeWrapper ) {
503
608
return nativeWrapper .isBool () || nativeWrapper .isByte () || nativeWrapper .isInt ();
504
609
}
505
610
506
611
static boolean fitsInInt64 (PrimitiveNativeWrapper nativeWrapper ) {
507
612
return nativeWrapper .isIntLike () || nativeWrapper .isBool ();
508
613
}
614
+
615
+ static boolean fitsInUInt32 (PrimitiveNativeWrapper nativeWrapper ) {
616
+ return (nativeWrapper .isBool () || nativeWrapper .isByte () || nativeWrapper .isInt ()) && nativeWrapper .getInt () >= 0 ;
617
+ }
618
+
619
+ static boolean fitsInUInt64 (PrimitiveNativeWrapper nativeWrapper ) {
620
+ return (nativeWrapper .isIntLike () || nativeWrapper .isBool ()) && nativeWrapper .getLong () >= 0 ;
621
+ }
509
622
}
510
623
}
0 commit comments