|
26 | 26 | package com.oracle.graal.python.builtins.objects.floats; |
27 | 27 |
|
28 | 28 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError; |
| 29 | +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; |
29 | 30 | import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; |
30 | 31 | import static com.oracle.graal.python.nodes.BuiltinNames.J_FLOAT; |
31 | 32 | import static com.oracle.graal.python.nodes.SpecialMethodNames.J___ABS__; |
|
91 | 92 | import com.oracle.graal.python.builtins.objects.floats.FloatBuiltinsClinicProviders.FormatNodeClinicProviderGen; |
92 | 93 | import com.oracle.graal.python.builtins.objects.ints.PInt; |
93 | 94 | import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
94 | | -import com.oracle.graal.python.lib.PyFloatAsDoubleNode; |
95 | 95 | import com.oracle.graal.python.lib.PyFloatCheckNode; |
96 | | -import com.oracle.graal.python.lib.PyLongAsDoubleNode; |
97 | 96 | import com.oracle.graal.python.lib.PyLongCheckNode; |
98 | 97 | import com.oracle.graal.python.lib.PyObjectHashNode; |
99 | 98 | import com.oracle.graal.python.nodes.ErrorMessages; |
| 99 | +import com.oracle.graal.python.nodes.PRaiseNode; |
100 | 100 | import com.oracle.graal.python.nodes.call.special.LookupAndCallTernaryNode; |
101 | 101 | import com.oracle.graal.python.nodes.call.special.LookupAndCallVarargsNode; |
102 | 102 | import com.oracle.graal.python.nodes.classes.IsSubtypeNode; |
|
111 | 111 | import com.oracle.graal.python.nodes.object.InlinedGetClassNode; |
112 | 112 | import com.oracle.graal.python.nodes.object.InlinedGetClassNode.GetPythonObjectClassNode; |
113 | 113 | import com.oracle.graal.python.nodes.truffle.PythonArithmeticTypes; |
| 114 | +import com.oracle.graal.python.nodes.util.CannotCastException; |
| 115 | +import com.oracle.graal.python.nodes.util.CastToJavaDoubleNode; |
114 | 116 | import com.oracle.graal.python.runtime.exception.PythonErrorType; |
115 | 117 | import com.oracle.graal.python.runtime.formatting.FloatFormatter; |
116 | 118 | import com.oracle.graal.python.runtime.formatting.InternalFormat; |
|
130 | 132 | import com.oracle.truffle.api.dsl.TypeSystemReference; |
131 | 133 | import com.oracle.truffle.api.frame.VirtualFrame; |
132 | 134 | import com.oracle.truffle.api.interop.InteropLibrary; |
133 | | -import com.oracle.truffle.api.interop.UnsupportedMessageException; |
134 | 135 | import com.oracle.truffle.api.library.CachedLibrary; |
135 | 136 | import com.oracle.truffle.api.nodes.Node; |
136 | 137 | import com.oracle.truffle.api.nodes.UnexpectedResultException; |
@@ -297,107 +298,68 @@ static boolean isFloatSubtype(Node inliningTarget, PythonAbstractNativeObject ob |
297 | 298 | } |
298 | 299 | } |
299 | 300 |
|
300 | | - protected static final int DOUBLE_TYPE = 1; |
301 | | - protected static final int LONG_TYPE = 2; |
302 | | - protected static final int FOREIGN_TYPE = 3; |
303 | | - protected static final int NOT_IMPLEMENTED = 4; |
304 | | - |
305 | 301 | @GenerateUncached |
306 | 302 | abstract static class ConvertToDoubleCheckNode extends Node { |
307 | | - abstract int execute(Object obj); |
| 303 | + abstract boolean execute(Object obj); |
308 | 304 |
|
309 | 305 | @Specialization |
310 | | - static int doDouble(@SuppressWarnings("unused") Double object) { |
311 | | - return DOUBLE_TYPE; |
| 306 | + static boolean doDouble(@SuppressWarnings("unused") Double object) { |
| 307 | + return true; |
312 | 308 | } |
313 | 309 |
|
314 | 310 | @Specialization |
315 | | - static int doInt(@SuppressWarnings("unused") Integer object) { |
316 | | - return LONG_TYPE; |
| 311 | + static boolean doInt(@SuppressWarnings("unused") Integer object) { |
| 312 | + return true; |
317 | 313 | } |
318 | 314 |
|
319 | 315 | @Specialization |
320 | | - static int doLong(@SuppressWarnings("unused") Long object) { |
321 | | - return LONG_TYPE; |
| 316 | + static boolean doLong(@SuppressWarnings("unused") Long object) { |
| 317 | + return true; |
322 | 318 | } |
323 | 319 |
|
324 | 320 | @Specialization |
325 | | - static int doBoolean(@SuppressWarnings("unused") Boolean object) { |
326 | | - return LONG_TYPE; |
| 321 | + static boolean doBoolean(@SuppressWarnings("unused") Boolean object) { |
| 322 | + return true; |
327 | 323 | } |
328 | 324 |
|
329 | 325 | @Specialization |
330 | | - static int doString(@SuppressWarnings("unused") TruffleString object) { |
331 | | - return NOT_IMPLEMENTED; |
| 326 | + static boolean doString(@SuppressWarnings("unused") TruffleString object) { |
| 327 | + return false; |
332 | 328 | } |
333 | 329 |
|
334 | 330 | @Specialization |
335 | | - static int doPBCT(@SuppressWarnings("unused") PythonBuiltinClassType object) { |
336 | | - return NOT_IMPLEMENTED; |
| 331 | + static boolean doPBCT(@SuppressWarnings("unused") PythonBuiltinClassType object) { |
| 332 | + return false; |
337 | 333 | } |
338 | 334 |
|
339 | 335 | @Specialization |
340 | | - static int typeCheck(Object obj, |
| 336 | + static boolean typeCheck(Object obj, |
341 | 337 | @Cached PyFloatCheckNode floatCheckNode, |
342 | 338 | @Cached PyLongCheckNode longCheckNode, |
343 | 339 | @Bind("this") Node inliningTarget, |
344 | 340 | @Cached InlinedGetClassNode getClassNode, |
345 | 341 | @CachedLibrary(limit = "3") InteropLibrary interopLibrary) { |
346 | | - if (floatCheckNode.execute(inliningTarget, obj)) { |
347 | | - return DOUBLE_TYPE; |
348 | | - } |
349 | | - if (longCheckNode.execute(obj)) { |
350 | | - return LONG_TYPE; |
| 342 | + if (floatCheckNode.execute(inliningTarget, obj) || longCheckNode.execute(obj)) { |
| 343 | + return true; |
351 | 344 | } |
352 | 345 | Object type = getClassNode.execute(inliningTarget, obj); |
353 | 346 | if (type == PythonBuiltinClassType.ForeignObject) { |
354 | 347 | if (interopLibrary.fitsInDouble(obj) || interopLibrary.fitsInLong(obj) || interopLibrary.isBoolean(obj)) { |
355 | | - return FOREIGN_TYPE; |
| 348 | + return true; |
356 | 349 | } |
357 | 350 | } |
358 | | - return NOT_IMPLEMENTED; |
| 351 | + return false; |
359 | 352 | } |
360 | 353 | } |
361 | 354 |
|
362 | | - @ImportStatic(FloatBuiltins.class) |
363 | | - @GenerateUncached |
364 | | - abstract static class ConvertToDoubleNode extends Node { |
365 | | - |
366 | | - abstract double execute(VirtualFrame frame, int type, Object obj); |
367 | | - |
368 | | - @Specialization(guards = "type == DOUBLE_TYPE") |
369 | | - static double doDouble(VirtualFrame frame, @SuppressWarnings("unused") int type, Object obj, |
370 | | - @Cached PyFloatAsDoubleNode asDoubleNode) { |
371 | | - return asDoubleNode.execute(frame, obj); |
372 | | - } |
373 | | - |
374 | | - @Specialization(guards = "type == LONG_TYPE") |
375 | | - static double doLong(@SuppressWarnings("unused") int type, Object obj, |
376 | | - @Cached PyLongAsDoubleNode asDoubleNode) { |
377 | | - Object r = asDoubleNode.execute(obj); |
378 | | - assert r != PNotImplemented.NOT_IMPLEMENTED : "Already been checked in ConvertToDoubleCheckNode"; |
379 | | - return (double) r; |
380 | | - } |
381 | | - |
382 | | - @Specialization(guards = "type == FOREIGN_TYPE") |
383 | | - static double doForeign(@SuppressWarnings("unused") int type, Object obj, |
384 | | - @CachedLibrary(limit = "3") InteropLibrary interopLibrary) { |
385 | | - try { |
386 | | - if (interopLibrary.fitsInDouble(obj)) { |
387 | | - |
388 | | - return interopLibrary.asDouble(obj); |
389 | | - } |
390 | | - if (interopLibrary.fitsInLong(obj)) { |
391 | | - return (double) interopLibrary.asLong(obj); |
392 | | - } |
393 | | - if (interopLibrary.isBoolean(obj)) { |
394 | | - return interopLibrary.asBoolean(obj) ? 1.0 : 0.0; |
395 | | - } |
396 | | - } catch (UnsupportedMessageException e) { |
397 | | - throw CompilerDirectives.shouldNotReachHere(e); |
398 | | - } |
399 | | - |
400 | | - throw CompilerDirectives.shouldNotReachHere("Should have been checked in ConvertToDoubleCheckNode"); |
| 355 | + static double convertToDouble(Object obj, |
| 356 | + CastToJavaDoubleNode asDoubleNode, |
| 357 | + PRaiseNode raiseNode) { |
| 358 | + try { |
| 359 | + return asDoubleNode.execute(obj); |
| 360 | + } catch (CannotCastException e) { |
| 361 | + // This can only happen to values that are expected to be long. |
| 362 | + throw raiseNode.raise(TypeError, ErrorMessages.INTEGER_REQUIRED); |
401 | 363 | } |
402 | 364 | } |
403 | 365 |
|
@@ -449,20 +411,20 @@ static Object doDP(VirtualFrame frame, PythonAbstractNativeObject left, double r |
449 | 411 | } |
450 | 412 |
|
451 | 413 | @Fallback |
452 | | - static Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 414 | + Object doGeneric(Object left, Object right, |
453 | 415 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
454 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 416 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
455 | 417 | double leftDouble; |
456 | 418 | double rightDouble; |
457 | | - int leftType = convertToDoubleCheckNode.execute(left); |
458 | | - if (leftType != NOT_IMPLEMENTED) { |
459 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 419 | + |
| 420 | + if (convertToDoubleCheckNode.execute(left)) { |
| 421 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
460 | 422 | } else { |
461 | 423 | return PNotImplemented.NOT_IMPLEMENTED; |
462 | 424 | } |
463 | | - int rightType = convertToDoubleCheckNode.execute(right); |
464 | | - if (rightType != NOT_IMPLEMENTED) { |
465 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 425 | + |
| 426 | + if (convertToDoubleCheckNode.execute(right)) { |
| 427 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
466 | 428 | } else { |
467 | 429 | return PNotImplemented.NOT_IMPLEMENTED; |
468 | 430 | } |
@@ -501,20 +463,20 @@ static double doLD(long left, double right) { |
501 | 463 | } |
502 | 464 |
|
503 | 465 | @Fallback |
504 | | - static Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 466 | + Object doGeneric(Object left, Object right, |
505 | 467 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
506 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 468 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
507 | 469 | double leftDouble; |
508 | 470 | double rightDouble; |
509 | | - int leftType = convertToDoubleCheckNode.execute(left); |
510 | | - if (leftType != NOT_IMPLEMENTED) { |
511 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 471 | + |
| 472 | + if (convertToDoubleCheckNode.execute(left)) { |
| 473 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
512 | 474 | } else { |
513 | 475 | return PNotImplemented.NOT_IMPLEMENTED; |
514 | 476 | } |
515 | | - int rightType = convertToDoubleCheckNode.execute(right); |
516 | | - if (rightType != NOT_IMPLEMENTED) { |
517 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 477 | + |
| 478 | + if (convertToDoubleCheckNode.execute(right)) { |
| 479 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
518 | 480 | } else { |
519 | 481 | return PNotImplemented.NOT_IMPLEMENTED; |
520 | 482 | } |
@@ -581,20 +543,20 @@ Object doDP(VirtualFrame frame, PythonAbstractNativeObject left, PInt right, |
581 | 543 | } |
582 | 544 |
|
583 | 545 | @Fallback |
584 | | - static Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 546 | + Object doGeneric(Object left, Object right, |
585 | 547 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
586 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 548 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
587 | 549 | double leftDouble; |
588 | 550 | double rightDouble; |
589 | | - int leftType = convertToDoubleCheckNode.execute(left); |
590 | | - if (leftType != NOT_IMPLEMENTED) { |
591 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 551 | + |
| 552 | + if (convertToDoubleCheckNode.execute(left)) { |
| 553 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
592 | 554 | } else { |
593 | 555 | return PNotImplemented.NOT_IMPLEMENTED; |
594 | 556 | } |
595 | | - int rightType = convertToDoubleCheckNode.execute(right); |
596 | | - if (rightType != NOT_IMPLEMENTED) { |
597 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 557 | + |
| 558 | + if (convertToDoubleCheckNode.execute(right)) { |
| 559 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
598 | 560 | } else { |
599 | 561 | return PNotImplemented.NOT_IMPLEMENTED; |
600 | 562 | } |
@@ -712,22 +674,22 @@ Object doDPiToComplex(VirtualFrame frame, PInt left, double right, @SuppressWarn |
712 | 674 | @Specialization |
713 | 675 | Object doGeneric(VirtualFrame frame, Object left, Object right, Object mod, |
714 | 676 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
715 | | - @Cached ConvertToDoubleNode convertToDoubleNode, |
| 677 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode, |
716 | 678 | @Shared("powCall") @Cached("create(Pow)") LookupAndCallTernaryNode callPow) { |
717 | 679 | if (!(mod instanceof PNone)) { |
718 | 680 | throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.POW_3RD_ARG_NOT_ALLOWED_UNLESS_INTEGERS); |
719 | 681 | } |
720 | 682 | double leftDouble; |
721 | 683 | double rightDouble; |
722 | | - int leftType = convertToDoubleCheckNode.execute(left); |
723 | | - if (leftType != NOT_IMPLEMENTED) { |
724 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 684 | + |
| 685 | + if (convertToDoubleCheckNode.execute(left)) { |
| 686 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
725 | 687 | } else { |
726 | 688 | return PNotImplemented.NOT_IMPLEMENTED; |
727 | 689 | } |
728 | | - int rightType = convertToDoubleCheckNode.execute(right); |
729 | | - if (rightType != NOT_IMPLEMENTED) { |
730 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 690 | + |
| 691 | + if (convertToDoubleCheckNode.execute(right)) { |
| 692 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
731 | 693 | } else { |
732 | 694 | return PNotImplemented.NOT_IMPLEMENTED; |
733 | 695 | } |
@@ -812,20 +774,20 @@ PTuple doGenericFloat(VirtualFrame frame, Object left, Object right, |
812 | 774 | } |
813 | 775 |
|
814 | 776 | @Fallback |
815 | | - Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 777 | + Object doGeneric(Object left, Object right, |
816 | 778 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
817 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 779 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
818 | 780 | double leftDouble; |
819 | 781 | double rightDouble; |
820 | | - int leftType = convertToDoubleCheckNode.execute(left); |
821 | | - if (leftType != NOT_IMPLEMENTED) { |
822 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 782 | + |
| 783 | + if (convertToDoubleCheckNode.execute(left)) { |
| 784 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
823 | 785 | } else { |
824 | 786 | return PNotImplemented.NOT_IMPLEMENTED; |
825 | 787 | } |
826 | | - int rightType = convertToDoubleCheckNode.execute(right); |
827 | | - if (rightType != NOT_IMPLEMENTED) { |
828 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 788 | + |
| 789 | + if (convertToDoubleCheckNode.execute(right)) { |
| 790 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
829 | 791 | } else { |
830 | 792 | return PNotImplemented.NOT_IMPLEMENTED; |
831 | 793 | } |
@@ -1016,20 +978,20 @@ public abstract static class ModNode extends FloatBinaryBuiltinNode { |
1016 | 978 | } |
1017 | 979 |
|
1018 | 980 | @Fallback |
1019 | | - Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 981 | + Object doGeneric(Object left, Object right, |
1020 | 982 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
1021 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 983 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
1022 | 984 | double leftDouble; |
1023 | 985 | double rightDouble; |
1024 | | - int leftType = convertToDoubleCheckNode.execute(left); |
1025 | | - if (leftType != NOT_IMPLEMENTED) { |
1026 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 986 | + |
| 987 | + if (convertToDoubleCheckNode.execute(left)) { |
| 988 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
1027 | 989 | } else { |
1028 | 990 | return PNotImplemented.NOT_IMPLEMENTED; |
1029 | 991 | } |
1030 | | - int rightType = convertToDoubleCheckNode.execute(right); |
1031 | | - if (rightType != NOT_IMPLEMENTED) { |
1032 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 992 | + |
| 993 | + if (convertToDoubleCheckNode.execute(right)) { |
| 994 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
1033 | 995 | } else { |
1034 | 996 | return PNotImplemented.NOT_IMPLEMENTED; |
1035 | 997 | } |
@@ -1097,20 +1059,20 @@ Object doDP(VirtualFrame frame, long left, PythonAbstractNativeObject right, |
1097 | 1059 | } |
1098 | 1060 |
|
1099 | 1061 | @Fallback |
1100 | | - Object doGeneric(VirtualFrame frame, Object left, Object right, |
| 1062 | + Object doGeneric(Object left, Object right, |
1101 | 1063 | @Cached ConvertToDoubleCheckNode convertToDoubleCheckNode, |
1102 | | - @Cached ConvertToDoubleNode convertToDoubleNode) { |
| 1064 | + @Cached CastToJavaDoubleNode castToJavaDoubleNode) { |
1103 | 1065 | double leftDouble; |
1104 | 1066 | double rightDouble; |
1105 | | - int leftType = convertToDoubleCheckNode.execute(left); |
1106 | | - if (leftType != NOT_IMPLEMENTED) { |
1107 | | - leftDouble = convertToDoubleNode.execute(frame, leftType, left); |
| 1067 | + |
| 1068 | + if (convertToDoubleCheckNode.execute(left)) { |
| 1069 | + leftDouble = convertToDouble(left, castToJavaDoubleNode, getRaiseNode()); |
1108 | 1070 | } else { |
1109 | 1071 | return PNotImplemented.NOT_IMPLEMENTED; |
1110 | 1072 | } |
1111 | | - int rightType = convertToDoubleCheckNode.execute(right); |
1112 | | - if (rightType != NOT_IMPLEMENTED) { |
1113 | | - rightDouble = convertToDoubleNode.execute(frame, rightType, right); |
| 1073 | + |
| 1074 | + if (convertToDoubleCheckNode.execute(right)) { |
| 1075 | + rightDouble = convertToDouble(right, castToJavaDoubleNode, getRaiseNode()); |
1114 | 1076 | } else { |
1115 | 1077 | return PNotImplemented.NOT_IMPLEMENTED; |
1116 | 1078 | } |
|
0 commit comments