66
66
import com .oracle .graal .python .builtins .objects .bytes .PBytes ;
67
67
import com .oracle .graal .python .builtins .objects .bytes .PIBytesLike ;
68
68
import com .oracle .graal .python .builtins .objects .cell .PCell ;
69
+ import com .oracle .graal .python .builtins .objects .cext .CExtNodes ;
70
+ import com .oracle .graal .python .builtins .objects .cext .PythonNativeClass ;
69
71
import com .oracle .graal .python .builtins .objects .code .PCode ;
70
72
import com .oracle .graal .python .builtins .objects .common .HashingStorage .DictEntry ;
71
73
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes ;
128
130
import com .oracle .graal .python .nodes .call .special .CallUnaryMethodNode ;
129
131
import com .oracle .graal .python .nodes .call .special .LookupAndCallTernaryNode ;
130
132
import com .oracle .graal .python .nodes .call .special .LookupAndCallUnaryNode ;
133
+ import com .oracle .graal .python .nodes .classes .IsSubtypeNode ;
131
134
import com .oracle .graal .python .nodes .control .GetIteratorNode ;
132
135
import com .oracle .graal .python .nodes .control .GetNextNode ;
133
136
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
@@ -426,51 +429,55 @@ public Object reversed(PythonClass cls, Object sequence,
426
429
public abstract static class FloatNode extends PythonBuiltinNode {
427
430
private final ConditionProfile isPrimitiveProfile = ConditionProfile .createBinaryProfile ();
428
431
429
- private boolean isPrimitiveFloat (Object cls ) {
430
- return isPrimitiveProfile .profile (cls == getCore (). lookupType ( PythonBuiltinClassType . PFloat ));
432
+ protected boolean isPrimitiveFloat (Object cls ) {
433
+ return isPrimitiveProfile .profile (cls == getBuiltinFloatClass ( ));
431
434
}
432
435
433
- @ Specialization
436
+ protected PythonBuiltinClass getBuiltinFloatClass () {
437
+ return getCore ().lookupType (PythonBuiltinClassType .PFloat );
438
+ }
439
+
440
+ @ Specialization (guards = "!isNativeClass(cls)" )
434
441
public Object floatFromInt (PythonClass cls , int arg ) {
435
442
if (isPrimitiveFloat (cls )) {
436
443
return (double ) arg ;
437
444
}
438
445
return factory ().createFloat (cls , arg );
439
446
}
440
447
441
- @ Specialization
448
+ @ Specialization ( guards = "!isNativeClass(cls)" )
442
449
public Object floatFromBoolean (PythonClass cls , boolean arg ) {
443
450
if (isPrimitiveFloat (cls )) {
444
451
return arg ? 1d : 0d ;
445
452
}
446
453
return factory ().createFloat (cls , arg ? 1d : 0d );
447
454
}
448
455
449
- @ Specialization
456
+ @ Specialization ( guards = "!isNativeClass(cls)" )
450
457
public Object floatFromLong (PythonClass cls , long arg ) {
451
458
if (isPrimitiveFloat (cls )) {
452
459
return (double ) arg ;
453
460
}
454
461
return factory ().createFloat (cls , arg );
455
462
}
456
463
457
- @ Specialization
464
+ @ Specialization ( guards = "!isNativeClass(cls)" )
458
465
public Object floatFromPInt (PythonClass cls , PInt arg ) {
459
466
if (isPrimitiveFloat (cls )) {
460
467
return arg .doubleValue ();
461
468
}
462
469
return factory ().createFloat (cls , arg .doubleValue ());
463
470
}
464
471
465
- @ Specialization
472
+ @ Specialization ( guards = "!isNativeClass(cls)" )
466
473
public Object floatFromFloat (PythonClass cls , double arg ) {
467
474
if (isPrimitiveFloat (cls )) {
468
475
return arg ;
469
476
}
470
477
return factory ().createFloat (cls , arg );
471
478
}
472
479
473
- @ Specialization
480
+ @ Specialization ( guards = "!isNativeClass(cls)" )
474
481
public Object floatFromString (PythonClass cls , String arg ) {
475
482
double value = JavaTypeConversions .convertStringToDouble (arg );
476
483
if (isPrimitiveFloat (cls )) {
@@ -479,34 +486,59 @@ public Object floatFromString(PythonClass cls, String arg) {
479
486
return factory ().createFloat (cls , value );
480
487
}
481
488
482
- @ Specialization
489
+ @ Specialization ( guards = "!isNativeClass(cls)" )
483
490
public Object floatFromNone (PythonClass cls , @ SuppressWarnings ("unused" ) PNone arg ) {
484
491
if (isPrimitiveFloat (cls )) {
485
492
return 0.0 ;
486
493
}
487
494
return factory ().createFloat (cls , 0.0 );
488
495
}
489
496
490
- @ Specialization
491
- Object doPythonObject ( PythonClass cls , Object obj ,
497
+ @ Specialization ( guards = "isPrimitiveFloat(cls)" )
498
+ double doubleFromObject ( @ SuppressWarnings ( "unused" ) PythonClass cls , Object obj ,
492
499
@ Cached ("create(__FLOAT__)" ) LookupAndCallUnaryNode callFloatNode ,
493
500
@ Cached ("create()" ) BranchProfile gotException ) {
494
501
try {
495
- return floatFromFloat ( cls , callFloatNode .executeDouble (obj ) );
502
+ return callFloatNode .executeDouble (obj );
496
503
} catch (UnexpectedResultException e ) {
497
504
gotException .enter ();
498
505
Object result = e .getResult ();
499
506
if (result == PNone .NO_VALUE ) {
500
507
throw raise (TypeError , "must be real number, not %p" , obj );
501
- } else if (PGuards . isPFloat ( result ) ) {
508
+ } else if (result instanceof PFloat ) {
502
509
// TODO Issue warning if 'result' is a subclass of Python type 'float'
503
- return result ;
510
+ return (( PFloat ) result ). getValue () ;
504
511
} else {
505
512
throw raise (TypeError , "%p.__float__ returned non-float (type %p)" , obj , result );
506
513
}
507
514
}
508
515
}
509
516
517
+ @ Specialization (guards = "!isNativeClass(cls)" )
518
+ Object doPythonObject (PythonClass cls , Object obj ,
519
+ @ Cached ("create(__FLOAT__)" ) LookupAndCallUnaryNode callFloatNode ,
520
+ @ Cached ("create()" ) BranchProfile gotException ) {
521
+ return floatFromFloat (cls , doubleFromObject (cls , obj , callFloatNode , gotException ));
522
+ }
523
+
524
+ protected CExtNodes .SubtypeNew createSubtypeNew () {
525
+ return new CExtNodes .SubtypeNew ("float" );
526
+ }
527
+
528
+ // logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython
529
+ // floatobject.c we have to first create a temporary float, then fill it into
530
+ // a natively allocated subtype structure
531
+ @ Specialization (guards = "isSubtype.execute(cls, floatCls)" , limit = "1" )
532
+ Object doPythonObject (PythonNativeClass cls , Object obj ,
533
+ @ Cached ("getBuiltinFloatClass()" ) PythonBuiltinClass floatCls ,
534
+ @ SuppressWarnings ("unused" ) @ Cached ("create()" ) IsSubtypeNode isSubtype ,
535
+ @ Cached ("create(__FLOAT__)" ) LookupAndCallUnaryNode callFloatNode ,
536
+ @ Cached ("create()" ) BranchProfile gotException ,
537
+ @ Cached ("createSubtypeNew()" ) CExtNodes .SubtypeNew subtypeNew ) {
538
+ double realFloat = doubleFromObject (floatCls , obj , callFloatNode , gotException );
539
+ return subtypeNew .execute (cls , realFloat );
540
+ }
541
+
510
542
@ Fallback
511
543
@ TruffleBoundary
512
544
public Object floatFromObject (@ SuppressWarnings ("unused" ) Object cls , Object arg ) {
0 commit comments