Skip to content

Commit feba538

Browse files
committed
Avoid using generic float() specialization when a more suitable one exists
1 parent d35fbc1 commit feba538

File tree

2 files changed

+21
-25
lines changed

2 files changed

+21
-25
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinConstructors.java

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -915,7 +915,7 @@ public Object reversed(VirtualFrame frame, Object cls, Object sequence,
915915
@Builtin(name = FLOAT, minNumOfPositionalArgs = 1, maxNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PFloat)
916916
@GenerateNodeFactory
917917
@ReportPolymorphism
918-
public abstract static class FloatNode extends PythonBuiltinNode {
918+
public abstract static class FloatNode extends PythonBinaryBuiltinNode {
919919
@Child private BytesNodes.ToBytesNode toByteArrayNode;
920920
@Child private LookupAndCallUnaryNode callFloatNode;
921921
@Child private LookupAndCallUnaryNode callReprNode;
@@ -982,15 +982,6 @@ Object floatFromString(VirtualFrame frame, Object cls, String arg) {
982982
return factoryCreateFloat(cls, value);
983983
}
984984

985-
@Specialization(guards = "!isNativeClass(cls)")
986-
Object floatFromBytes(VirtualFrame frame, Object cls, PIBytesLike arg) {
987-
double value = convertBytesToDouble(frame, arg);
988-
if (isPrimitiveFloat(cls)) {
989-
return value;
990-
}
991-
return factoryCreateFloat(cls, value);
992-
}
993-
994985
private double convertBytesToDouble(VirtualFrame frame, PIBytesLike arg) {
995986
return convertStringToDouble(frame, createString(getByteArray(frame, arg)), arg);
996987
}
@@ -1101,16 +1092,13 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
11011092
return factory().createFloat(cls, 0.0);
11021093
}
11031094

1104-
@Specialization(guards = "isPrimitiveFloat(cls)")
1095+
static boolean isHandledType(Object o) {
1096+
return PGuards.canBeInteger(o) || PGuards.isDouble(o) || o instanceof String || PGuards.isPNone(o);
1097+
}
1098+
1099+
@Specialization(guards = {"isPrimitiveFloat(cls)", "!isHandledType(obj)"})
11051100
double doubleFromObject(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj,
11061101
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
1107-
1108-
if (obj instanceof PNone) {
1109-
return 0.0;
1110-
}
1111-
if (obj instanceof String) {
1112-
return convertStringToDouble(frame, (String) obj, obj);
1113-
}
11141102
// Follows logic from PyNumber_Float:
11151103
// lib.asJavaDouble cannot be used here because it models PyFloat_AsDouble,
11161104
// which ignores __float__ defined by float subclasses, whereas PyNumber_Float
@@ -1136,6 +1124,7 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
11361124
return lib.asJavaDouble(lib.asIndex(obj));
11371125
}
11381126
// Follows logic from PyFloat_FromString:
1127+
// These types are handled only if the object doesn't implement __float__/__index__
11391128
if (obj instanceof PString) {
11401129
return convertStringToDouble(frame, ((PString) obj).getValue(), obj);
11411130
} else if (obj instanceof PIBytesLike) {
@@ -1151,10 +1140,14 @@ Object floatFromNone(Object cls, @SuppressWarnings("unused") PNone arg) {
11511140
throw raise(PythonBuiltinClassType.TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_NUMBER, "float()", obj);
11521141
}
11531142

1154-
@Specialization(guards = "!isNativeClass(cls)")
1143+
@Specialization(guards = {"!isNativeClass(cls)", "!isPrimitiveFloat(cls)"})
11551144
Object doPythonObject(VirtualFrame frame, Object cls, Object obj,
1156-
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
1157-
return floatFromDouble(cls, doubleFromObject(frame, cls, obj, lib));
1145+
@Cached FloatNode recursiveCallNode) {
1146+
Object doubleValue = recursiveCallNode.executeWith(frame, PythonBuiltinClassType.PFloat, obj);
1147+
if (!(doubleValue instanceof Double)) {
1148+
throw CompilerDirectives.shouldNotReachHere("float() returned non-primitive value");
1149+
}
1150+
return floatFromDouble(cls, (double) doubleValue);
11581151
}
11591152

11601153
// logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython
@@ -1164,9 +1157,12 @@ Object doPythonObject(VirtualFrame frame, Object cls, Object obj,
11641157
Object doPythonObject(VirtualFrame frame, PythonNativeClass cls, Object obj,
11651158
@Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype,
11661159
@Cached CExtNodes.FloatSubtypeNew subtypeNew,
1167-
@CachedLibrary(limit = "1") PythonObjectLibrary lib) {
1168-
double realFloat = doubleFromObject(frame, PythonBuiltinClassType.PFloat, obj, lib);
1169-
return subtypeNew.call(cls, realFloat);
1160+
@Cached FloatNode recursiveCallNode) {
1161+
Object doubleValue = recursiveCallNode.executeWith(frame, PythonBuiltinClassType.PFloat, obj);
1162+
if (!(doubleValue instanceof Double)) {
1163+
throw CompilerDirectives.shouldNotReachHere("float() returned non-primitive value");
1164+
}
1165+
return subtypeNew.call(cls, (double) doubleValue);
11701166
}
11711167

11721168
@Fallback

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2654,7 +2654,7 @@ Object doGeneric(VirtualFrame frame, @SuppressWarnings("unused") Object module,
26542654
@Shared("asPythonObjectNode") @Cached AsPythonObjectNode asPythonObjectNode) {
26552655
if (floatNode == null) {
26562656
CompilerDirectives.transferToInterpreterAndInvalidate();
2657-
floatNode = insert(BuiltinConstructorsFactory.FloatNodeFactory.create(null));
2657+
floatNode = insert(BuiltinConstructorsFactory.FloatNodeFactory.create());
26582658
}
26592659
return toNewRefNode.execute(floatNode.executeWith(frame, PythonBuiltinClassType.PFloat, asPythonObjectNode.execute(object)));
26602660
}

0 commit comments

Comments
 (0)