Skip to content

Commit c83847b

Browse files
committed
[GR-12515] Reduce complexity of primitive native wrappers.
PullRequest: graalpython/278
2 parents fad98f0 + 6240d22 commit c83847b

File tree

8 files changed

+276
-231
lines changed

8 files changed

+276
-231
lines changed

graalpython/com.oracle.graal.python.cext/src/abstract.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ PyObject * PyNumber_Long(PyObject *o) {
197197

198198
UPCALL_ID(PyNumber_Float);
199199
PyObject * PyNumber_Float(PyObject *o) {
200-
return UPCALL_CEXT_O(_jls_PyNumber_Float, native_to_java(o));
200+
return ((PyObject* (*)(void*))_jls_PyNumber_Float)(native_to_java(o));
201201
}
202202

203203
UPCALL_ID(PyNumber_Absolute);

graalpython/com.oracle.graal.python.cext/src/floatobject.c

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,9 @@ typedef enum {
1616
static float_format_type double_format, float_format;
1717
static float_format_type detected_double_format, detected_float_format;
1818

19-
UPCALL_ID(PyFloat_FromObject);
19+
UPCALL_ID(PyFloat_AsDouble);
2020
double PyFloat_AsDouble(PyObject *op) {
21-
if (op == NULL) {
22-
PyErr_BadArgument();
23-
return -1.0;
24-
}
25-
26-
if (PyFloat_Check(op)) {
27-
return PyFloat_AS_DOUBLE(op);
28-
}
29-
30-
op = UPCALL_CEXT_O(_jls_PyFloat_FromObject, native_to_java(op));
31-
if (op == NULL) {
32-
return -1.0;
33-
} else {
34-
return PyFloat_AS_DOUBLE(op);
35-
}
21+
return ((double (*)(void*))_jls_PyFloat_AsDouble)(native_to_java(op));
3622
}
3723

3824
UPCALL_ID(PyFloat_FromDouble);

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

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -589,52 +589,54 @@ public abstract static class FloatNode extends PythonBuiltinNode {
589589

590590
private final IsBuiltinClassProfile isPrimitiveProfile = IsBuiltinClassProfile.create();
591591

592-
protected final boolean isPrimitiveFloat(PythonClass cls) {
592+
public abstract Object executeWith(Object cls, Object arg);
593+
594+
protected final boolean isPrimitiveFloat(LazyPythonClass cls) {
593595
return isPrimitiveProfile.profileClass(cls, PythonBuiltinClassType.PFloat);
594596
}
595597

596598
@Specialization(guards = "!isNativeClass(cls)")
597-
public Object floatFromInt(PythonClass cls, int arg) {
599+
public Object floatFromInt(LazyPythonClass cls, int arg) {
598600
if (isPrimitiveFloat(cls)) {
599601
return (double) arg;
600602
}
601603
return factory().createFloat(cls, arg);
602604
}
603605

604606
@Specialization(guards = "!isNativeClass(cls)")
605-
public Object floatFromBoolean(PythonClass cls, boolean arg) {
607+
public Object floatFromBoolean(LazyPythonClass cls, boolean arg) {
606608
if (isPrimitiveFloat(cls)) {
607609
return arg ? 1d : 0d;
608610
}
609611
return factory().createFloat(cls, arg ? 1d : 0d);
610612
}
611613

612614
@Specialization(guards = "!isNativeClass(cls)")
613-
public Object floatFromLong(PythonClass cls, long arg) {
615+
public Object floatFromLong(LazyPythonClass cls, long arg) {
614616
if (isPrimitiveFloat(cls)) {
615617
return (double) arg;
616618
}
617619
return factory().createFloat(cls, arg);
618620
}
619621

620622
@Specialization(guards = "!isNativeClass(cls)")
621-
public Object floatFromPInt(PythonClass cls, PInt arg) {
623+
public Object floatFromPInt(LazyPythonClass cls, PInt arg) {
622624
if (isPrimitiveFloat(cls)) {
623625
return arg.doubleValue();
624626
}
625627
return factory().createFloat(cls, arg.doubleValue());
626628
}
627629

628630
@Specialization(guards = "!isNativeClass(cls)")
629-
public Object floatFromFloat(PythonClass cls, double arg) {
631+
public Object floatFromFloat(LazyPythonClass cls, double arg) {
630632
if (isPrimitiveFloat(cls)) {
631633
return arg;
632634
}
633635
return factory().createFloat(cls, arg);
634636
}
635637

636638
@Specialization(guards = "!isNativeClass(cls)")
637-
public Object floatFromString(PythonClass cls, String arg) {
639+
public Object floatFromString(LazyPythonClass cls, String arg) {
638640
double value = convertStringToDouble(arg);
639641
if (isPrimitiveFloat(cls)) {
640642
return value;
@@ -644,7 +646,7 @@ public Object floatFromString(PythonClass cls, String arg) {
644646

645647
@Specialization(guards = "!isNativeClass(cls)")
646648
@TruffleBoundary
647-
public Object floatFromBytes(PythonClass cls, PIBytesLike arg) {
649+
public Object floatFromBytes(LazyPythonClass cls, PIBytesLike arg) {
648650
double value = convertStringToDouble(new String(getByteArray(arg)));
649651
if (isPrimitiveFloat(cls)) {
650652
return value;
@@ -694,15 +696,15 @@ private double convertStringToDouble(String str) {
694696
}
695697

696698
@Specialization(guards = "!isNativeClass(cls)")
697-
public Object floatFromNone(PythonClass cls, @SuppressWarnings("unused") PNone arg) {
699+
public Object floatFromNone(LazyPythonClass cls, @SuppressWarnings("unused") PNone arg) {
698700
if (isPrimitiveFloat(cls)) {
699701
return 0.0;
700702
}
701703
return factory().createFloat(cls, 0.0);
702704
}
703705

704706
@Specialization(guards = "isPrimitiveFloat(cls)")
705-
double doubleFromObject(@SuppressWarnings("unused") PythonClass cls, Object obj,
707+
double doubleFromObject(@SuppressWarnings("unused") LazyPythonClass cls, Object obj,
706708
@Cached("create(__FLOAT__)") LookupAndCallUnaryNode callFloatNode,
707709
@Cached("create()") BranchProfile gotException) {
708710
if (obj instanceof String) {
@@ -729,7 +731,7 @@ public Object floatFromNone(PythonClass cls, @SuppressWarnings("unused") PNone a
729731
}
730732

731733
@Specialization(guards = "!isNativeClass(cls)")
732-
Object doPythonObject(PythonClass cls, Object obj,
734+
Object doPythonObject(LazyPythonClass cls, Object obj,
733735
@Cached("create(__FLOAT__)") LookupAndCallUnaryNode callFloatNode,
734736
@Cached("create()") BranchProfile gotException) {
735737
return floatFromFloat(cls, doubleFromObject(cls, obj, callFloatNode, gotException));

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

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseTernaryNodeGen;
8383
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.MayRaiseUnaryNodeGen;
8484
import com.oracle.graal.python.builtins.objects.cext.HandleCache;
85+
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PrimitiveNativeWrapper;
8586
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PySequenceArrayWrapper;
8687
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonClassInitNativeWrapper;
8788
import com.oracle.graal.python.builtins.objects.cext.NativeWrappers.PythonClassNativeWrapper;
@@ -773,6 +774,17 @@ abstract static class NativeBuiltin extends PythonBuiltinNode {
773774
@Child private Node isBoxedNode;
774775
@Child private Node unboxNode;
775776
@Child private GetByteArrayNode getByteArrayNode;
777+
@Child private ReadAttributeFromObjectNode readNativeNull;
778+
779+
protected Object getNativeNull(Object module) {
780+
if (readNativeNull == null) {
781+
CompilerDirectives.transferToInterpreterAndInvalidate();
782+
readNativeNull = insert(ReadAttributeFromObjectNode.create());
783+
}
784+
Object wrapper = readNativeNull.execute(module, NATIVE_NULL);
785+
assert wrapper instanceof PythonNativeNull;
786+
return wrapper;
787+
}
776788

777789
protected void transformToNative(PException p) {
778790
NativeBuiltin.transformToNative(getContext(), p);
@@ -1928,8 +1940,8 @@ abstract static class AsDouble extends PythonBuiltinNode {
19281940
abstract static class PyTruffle_Register_NULL extends PythonUnaryBuiltinNode {
19291941
@Specialization
19301942
Object doIt(Object object,
1931-
@Cached("create()") ReadAttributeFromObjectNode writeAttrNode) {
1932-
Object wrapper = writeAttrNode.execute(getCore().lookupBuiltinModule("python_cext"), NATIVE_NULL);
1943+
@Cached("create()") ReadAttributeFromObjectNode readAttrNode) {
1944+
Object wrapper = readAttrNode.execute(getCore().lookupBuiltinModule("python_cext"), NATIVE_NULL);
19331945
if (wrapper instanceof PythonNativeNull) {
19341946
((PythonNativeNull) wrapper).setPtr(object);
19351947
}
@@ -2137,4 +2149,92 @@ PBytes doGeneric(PythonNativeObject object) {
21372149
throw raise(TypeError, "invalid pointer: %s", object.object);
21382150
}
21392151
}
2152+
2153+
@Builtin(name = "PyFloat_AsDouble", fixedNumOfPositionalArgs = 1)
2154+
@GenerateNodeFactory
2155+
abstract static class PyFloat_AsDouble extends NativeBuiltin {
2156+
2157+
@Child private CExtNodes.AsPythonObjectNode asPythonObjectNode;
2158+
@Child private CExtNodes.AsDouble asDoubleNode;
2159+
2160+
@Specialization(guards = "!object.isDouble()")
2161+
double doLongNativeWrapper(PrimitiveNativeWrapper object) {
2162+
return object.getLong();
2163+
}
2164+
2165+
@Specialization(guards = "object.isDouble()")
2166+
double doDoubleNativeWrapper(PrimitiveNativeWrapper object) {
2167+
return object.getDouble();
2168+
}
2169+
2170+
@Specialization(rewriteOn = PException.class)
2171+
double doGeneric(Object object) {
2172+
if (asPythonObjectNode == null) {
2173+
CompilerDirectives.transferToInterpreterAndInvalidate();
2174+
asPythonObjectNode = insert(CExtNodes.AsPythonObjectNode.create());
2175+
}
2176+
if (asDoubleNode == null) {
2177+
CompilerDirectives.transferToInterpreterAndInvalidate();
2178+
asDoubleNode = insert(CExtNodes.AsDouble.create());
2179+
}
2180+
return asDoubleNode.execute(asPythonObjectNode.execute(object));
2181+
}
2182+
2183+
@Specialization(replaces = "doGeneric")
2184+
double doGenericErr(Object object) {
2185+
try {
2186+
return doGeneric(object);
2187+
} catch (PException e) {
2188+
transformToNative(e);
2189+
return -1.0;
2190+
}
2191+
}
2192+
}
2193+
2194+
@Builtin(name = "PyNumber_Float", fixedNumOfPositionalArgs = 2, declaresExplicitSelf = true)
2195+
@GenerateNodeFactory
2196+
abstract static class PyNumber_Float extends NativeBuiltin {
2197+
2198+
@Child private CExtNodes.AsPythonObjectNode asPythonObjectNode;
2199+
@Child private CExtNodes.ToSulongNode toSulongNode;
2200+
@Child private BuiltinConstructors.FloatNode floatNode;
2201+
2202+
@Specialization(guards = "object.isDouble()")
2203+
Object doDoubleNativeWrapper(@SuppressWarnings("unused") Object module, PrimitiveNativeWrapper object) {
2204+
return object;
2205+
}
2206+
2207+
@Specialization(guards = "!object.isDouble()")
2208+
Object doLongNativeWrapper(@SuppressWarnings("unused") Object module, PrimitiveNativeWrapper object,
2209+
@Cached("create()") CExtNodes.ToSulongNode primitiveToSulongNode) {
2210+
return primitiveToSulongNode.execute((double) object.getLong());
2211+
}
2212+
2213+
@Specialization(rewriteOn = PException.class)
2214+
Object doGeneric(@SuppressWarnings("unused") Object module, Object object) {
2215+
if (asPythonObjectNode == null) {
2216+
CompilerDirectives.transferToInterpreterAndInvalidate();
2217+
asPythonObjectNode = insert(CExtNodes.AsPythonObjectNode.create());
2218+
}
2219+
if (floatNode == null) {
2220+
CompilerDirectives.transferToInterpreterAndInvalidate();
2221+
floatNode = insert(BuiltinConstructorsFactory.FloatNodeFactory.create(null));
2222+
}
2223+
if (toSulongNode == null) {
2224+
CompilerDirectives.transferToInterpreterAndInvalidate();
2225+
toSulongNode = insert(CExtNodes.ToSulongNode.create());
2226+
}
2227+
return toSulongNode.execute(floatNode.executeWith(PythonBuiltinClassType.PFloat, asPythonObjectNode.execute(object)));
2228+
}
2229+
2230+
@Specialization(replaces = "doGeneric")
2231+
Object doGenericErr(Object module, Object object) {
2232+
try {
2233+
return doGeneric(module, object);
2234+
} catch (PException e) {
2235+
transformToNative(e);
2236+
return getNativeNull(module);
2237+
}
2238+
}
2239+
}
21402240
}

0 commit comments

Comments
 (0)