|
74 | 74 | import static com.oracle.graal.python.nodes.SpecialMethodNames.DECODE;
|
75 | 75 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__COMPLEX__;
|
76 | 76 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__EQ__;
|
| 77 | +import static com.oracle.graal.python.nodes.SpecialMethodNames.__FLOAT__; |
77 | 78 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__HASH__;
|
78 | 79 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__INDEX__;
|
79 | 80 | import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
|
@@ -916,6 +917,7 @@ public Object reversed(VirtualFrame frame, Object cls, Object sequence,
|
916 | 917 | @ReportPolymorphism
|
917 | 918 | public abstract static class FloatNode extends PythonBuiltinNode {
|
918 | 919 | @Child private BytesNodes.ToBytesNode toByteArrayNode;
|
| 920 | + @Child private LookupAndCallUnaryNode callFloatNode; |
919 | 921 |
|
920 | 922 | @Child private IsBuiltinClassProfile isPrimitiveProfile = IsBuiltinClassProfile.create();
|
921 | 923 | private ConditionProfile isNanProfile;
|
@@ -1051,20 +1053,51 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
|
1051 | 1053 | @Specialization(guards = "isPrimitiveFloat(cls)")
|
1052 | 1054 | double doubleFromObject(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj,
|
1053 | 1055 | @CachedLibrary(limit = "1") PythonObjectLibrary lib) {
|
| 1056 | + |
| 1057 | + if (obj instanceof PNone) { |
| 1058 | + return 0.0; |
| 1059 | + } |
1054 | 1060 | if (obj instanceof String) {
|
1055 | 1061 | return convertStringToDouble((String) obj);
|
1056 |
| - } else if (obj instanceof PString) { |
| 1062 | + } |
| 1063 | + // Follows logic from PyNumber_Float: |
| 1064 | + // lib.asJavaDouble cannot be used here because it models PyFloat_AsDouble, |
| 1065 | + // which ignores __float__ defined by float subclasses, whereas PyNumber_Float |
| 1066 | + // uses the __float__ even for subclasses |
| 1067 | + if (callFloatNode == null) { |
| 1068 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 1069 | + callFloatNode = insert(LookupAndCallUnaryNode.create(__FLOAT__)); |
| 1070 | + } |
| 1071 | + Object result = callFloatNode.executeObject(frame, obj); |
| 1072 | + if (result != PNone.NO_VALUE) { |
| 1073 | + if (PGuards.isDouble(result)) { |
| 1074 | + return (double) result; |
| 1075 | + } |
| 1076 | + if (PGuards.isPFloat(result)) { |
| 1077 | + if (!isPrimitiveProfile.profileObject(result, PythonBuiltinClassType.PFloat)) { |
| 1078 | + // TODO deprecation warning |
| 1079 | + } |
| 1080 | + return ((PFloat) result).getValue(); |
| 1081 | + } |
| 1082 | + throw raise(TypeError, ErrorMessages.RETURNED_NON_FLOAT, "__float__", result); |
| 1083 | + } |
| 1084 | + if (lib.canBeIndex(obj)) { |
| 1085 | + return lib.asJavaDouble(lib.asIndex(obj)); |
| 1086 | + } |
| 1087 | + // Follows logic from PyFloat_FromString: |
| 1088 | + if (obj instanceof PString) { |
1057 | 1089 | return convertStringToDouble(((PString) obj).getValue());
|
1058 |
| - } else if (obj instanceof PNone) { |
1059 |
| - return 0.0; |
1060 | 1090 | } else if (obj instanceof PIBytesLike) {
|
1061 | 1091 | return convertBytesToDouble(frame, (PIBytesLike) obj);
|
| 1092 | + } else if (lib.isBuffer(obj)) { |
| 1093 | + try { |
| 1094 | + return convertStringToDouble(createString(lib.getBufferBytes(obj))); |
| 1095 | + } catch (UnsupportedMessageException e) { |
| 1096 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 1097 | + throw new IllegalStateException("Object claims to be a buffer but does not support getBufferBytes()"); |
| 1098 | + } |
1062 | 1099 | }
|
1063 |
| - if (lib.canBeJavaDouble(obj)) { |
1064 |
| - return lib.asJavaDouble(obj); |
1065 |
| - } else { |
1066 |
| - throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "float()", obj); |
1067 |
| - } |
| 1100 | + throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "float()", obj); |
1068 | 1101 | }
|
1069 | 1102 |
|
1070 | 1103 | @Specialization(guards = "!isNativeClass(cls)")
|
|
0 commit comments