Skip to content

Commit 460d3f3

Browse files
fangerertimfel
authored andcommitted
Support indirect native float subclasses in float constructor
1 parent ce76a4d commit 460d3f3

File tree

3 files changed

+56
-33
lines changed

3 files changed

+56
-33
lines changed

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

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -968,59 +968,54 @@ abstract static class FloatNode extends PythonBinaryBuiltinNode {
968968
// Used for the recursive call
969969
protected abstract double executeDouble(VirtualFrame frame, PythonBuiltinClassType cls, Object arg) throws UnexpectedResultException;
970970

971-
protected final boolean isPrimitiveFloat(Node inliningTarget, Object cls, InlineIsBuiltinClassProfile isPrimitiveProfile) {
972-
return isPrimitiveProfile.profileIsBuiltinClass(inliningTarget, cls, PythonBuiltinClassType.PFloat);
973-
}
974-
975971
@Specialization(guards = "isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", limit = "1")
976-
double floatFromDouble(@SuppressWarnings("unused") Object cls, double arg,
977-
@Bind("this") Node inliningTarget,
978-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
972+
static double floatFromDouble(@SuppressWarnings("unused") Object cls, double arg,
973+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
974+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
979975
return arg;
980976
}
981977

982978
@Specialization(guards = "isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", limit = "1")
983-
double floatFromInt(@SuppressWarnings("unused") Object cls, int arg,
984-
@Bind("this") Node inliningTarget,
985-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
979+
static double floatFromInt(@SuppressWarnings("unused") Object cls, int arg,
980+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
981+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
986982
return arg;
987983
}
988984

989985
@Specialization(guards = "isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", limit = "1")
990-
double floatFromLong(@SuppressWarnings("unused") Object cls, long arg,
991-
@Bind("this") Node inliningTarget,
992-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
986+
static double floatFromLong(@SuppressWarnings("unused") Object cls, long arg,
987+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
988+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
993989
return arg;
994990
}
995991

996992
@Specialization(guards = "isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", limit = "1")
997-
double floatFromBoolean(@SuppressWarnings("unused") Object cls, boolean arg,
998-
@Bind("this") Node inliningTarget,
999-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
993+
static double floatFromBoolean(@SuppressWarnings("unused") Object cls, boolean arg,
994+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
995+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
1000996
return arg ? 1d : 0d;
1001997
}
1002998

1003999
@Specialization(guards = "isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", limit = "1")
1004-
double floatFromString(VirtualFrame frame, @SuppressWarnings("unused") Object cls, TruffleString obj,
1005-
@Bind("this") Node inliningTarget,
1006-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile,
1000+
static double floatFromString(VirtualFrame frame, @SuppressWarnings("unused") Object cls, TruffleString obj,
1001+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
1002+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile,
10071003
@Shared("fromString") @Cached PyFloatFromString fromString) {
10081004
return fromString.execute(frame, obj);
10091005
}
10101006

10111007
@Specialization(guards = {"isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", "isNoValue(obj)"}, limit = "1")
1012-
double floatFromNoValue(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") PNone obj,
1013-
@Bind("this") Node inliningTarget,
1014-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
1008+
static double floatFromNoValue(@SuppressWarnings("unused") Object cls, @SuppressWarnings("unused") PNone obj,
1009+
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
1010+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
10151011
return 0.0;
10161012
}
10171013

10181014
@Specialization(guards = {"isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", "!isNoValue(obj)"}, //
10191015
replaces = "floatFromString", limit = "1")
1020-
@SuppressWarnings("truffle-static-method")
1021-
double floatFromObject(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj,
1016+
static double floatFromObject(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object obj,
10221017
@Bind("this") Node inliningTarget,
1023-
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile,
1018+
@SuppressWarnings("unused") @Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile,
10241019
@Cached IsBuiltinObjectProfile stringProfile,
10251020
@Shared("fromString") @Cached PyFloatFromString fromString,
10261021
@Cached PyNumberFloatNode pyNumberFloat) {
@@ -1030,7 +1025,15 @@ protected final boolean isPrimitiveFloat(Node inliningTarget, Object cls, Inline
10301025
return pyNumberFloat.execute(frame, obj);
10311026
}
10321027

1033-
@Specialization(guards = {"!isNativeClass(cls)", "!isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)"}, //
1028+
@Specialization(guards = {"!needsNativeAllocation(cls)", "!isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", "isNoValue(obj)"}, //
1029+
limit = "1")
1030+
Object floatFromNoneManagedSubclass(Object cls, PNone obj,
1031+
@Bind("this") Node inliningTarget,
1032+
@Shared("isFloat") @Cached InlineIsBuiltinClassProfile isPrimitiveFloatProfile) {
1033+
return factory().createFloat(cls, floatFromNoValue(cls, obj, inliningTarget, isPrimitiveFloatProfile));
1034+
}
1035+
1036+
@Specialization(guards = {"!needsNativeAllocation(cls)", "!isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)"}, //
10341037
limit = "1")
10351038
Object floatFromObjectManagedSubclass(VirtualFrame frame, Object cls, Object obj,
10361039
@SuppressWarnings("unused") @Bind("this") Node inliningTarget,
@@ -1046,8 +1049,13 @@ Object floatFromObjectManagedSubclass(VirtualFrame frame, Object cls, Object obj
10461049
// logic similar to float_subtype_new(PyTypeObject *type, PyObject *x) from CPython
10471050
// floatobject.c we have to first create a temporary float, then fill it into
10481051
// a natively allocated subtype structure
1049-
@Specialization(guards = "isSubtypeOfFloat(frame, isSubtype, cls)", limit = "1")
1050-
static Object floatFromObjectNativeSubclass(VirtualFrame frame, PythonNativeClass cls, Object obj,
1052+
@Specialization(guards = { //
1053+
"needsNativeAllocation(cls)", //
1054+
"!isPrimitiveFloat(this, cls, isPrimitiveFloatProfile)", //
1055+
"isSubtypeOfFloat(frame, isSubtype, cls)"}, limit = "1")
1056+
static Object floatFromObjectNativeSubclass(VirtualFrame frame, Object cls, Object obj,
1057+
@Bind("this") @SuppressWarnings("unused") Node inliningTarget,
1058+
@Shared("isFloat") @Cached @SuppressWarnings("unused") InlineIsBuiltinClassProfile isPrimitiveFloatProfile,
10511059
@Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype,
10521060
@Cached CExtNodes.FloatSubtypeNew subtypeNew,
10531061
@Shared @Cached FloatNode recursiveCallNode) {
@@ -1058,7 +1066,11 @@ static Object floatFromObjectNativeSubclass(VirtualFrame frame, PythonNativeClas
10581066
}
10591067
}
10601068

1061-
protected static boolean isSubtypeOfFloat(VirtualFrame frame, IsSubtypeNode isSubtypeNode, PythonNativeClass cls) {
1069+
protected final boolean isPrimitiveFloat(Node inliningTarget, Object cls, InlineIsBuiltinClassProfile isPrimitiveProfile) {
1070+
return isPrimitiveProfile.profileIsBuiltinClass(inliningTarget, cls, PythonBuiltinClassType.PFloat);
1071+
}
1072+
1073+
protected static boolean isSubtypeOfFloat(VirtualFrame frame, IsSubtypeNode isSubtypeNode, Object cls) {
10621074
return isSubtypeNode.execute(frame, cls, PythonBuiltinClassType.PFloat);
10631075
}
10641076
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ protected static NativeCAPISymbol getFunction(String typenamePrefix) {
260260
return result;
261261
}
262262

263-
@Specialization(guards = "isNativeClass(object)")
264-
protected Object callNativeConstructor(Object object, Object arg,
263+
@Specialization(guards = "needsNativeAllocation(object)")
264+
Object callNativeConstructor(Object object, Object arg,
265265
@Cached ToSulongNode toSulongNode,
266266
@Cached NativeToPythonNode toJavaNode,
267267
@CachedLibrary(limit = "1") InteropLibrary interopLibrary,
@@ -270,8 +270,7 @@ protected Object callNativeConstructor(Object object, Object arg,
270270
Object result = interopLibrary.execute(importCAPISymbolNode.execute(getFunction()), toSulongNode.execute(object), arg);
271271
return toJavaNode.execute(result);
272272
} catch (UnsupportedMessageException | UnsupportedTypeException | ArityException e) {
273-
CompilerDirectives.transferToInterpreterAndInvalidate();
274-
throw new IllegalStateException("C subtype_new function failed", e);
273+
throw CompilerDirectives.shouldNotReachHere("C subtype_new function failed", e);
275274
}
276275
}
277276
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/PGuards.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ public static boolean isNativeClass(Object klass) {
377377
return PythonNativeClass.isInstance(klass);
378378
}
379379

380+
/**
381+
* Tests if the given {@code klass} is a Python class that needs a native allocation. This is
382+
* the case if {@code klass} either is a native class or it is a managed class that (indirectly)
383+
* inherits from a native class.
384+
*/
385+
public static boolean needsNativeAllocation(Object klass) {
386+
if (klass instanceof PythonManagedClass managedClass) {
387+
return managedClass.needsNativeAllocation();
388+
}
389+
return PythonNativeClass.isInstance(klass);
390+
}
391+
380392
public static boolean isPythonClass(Object klass) {
381393
return PythonAbstractClass.isInstance(klass) || klass instanceof PythonBuiltinClassType;
382394
}

0 commit comments

Comments
 (0)