Skip to content

Commit 39207c8

Browse files
committed
intrinsified python_cext PyComplex_XXX
1 parent f9dfae1 commit 39207c8

File tree

4 files changed

+141
-32
lines changed

4 files changed

+141
-32
lines changed

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_complex.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ def _reference_realasdouble(args):
6565
raise SystemError
6666
else:
6767
return -1.0
68-
68+
69+
def _reference_fromdoubles(args):
70+
if isinstance(args[0], float) and isinstance(args[1], float):
71+
return complex(args[0], args[1])
72+
raise SystemError
6973

7074
class DummyNonComplex():
7175
pass
@@ -167,3 +171,15 @@ def compile_module(self, name):
167171
arguments=["PyObject* obj"],
168172
cmpfunc=unhandled_error_compare
169173
)
174+
175+
test_PyComplex_FromDoubles = CPyExtFunction(
176+
_reference_fromdoubles,
177+
lambda: (
178+
(float(0.0), float(2.0), ),
179+
(1.0, 2.0, ),
180+
),
181+
resultspec="O",
182+
argspec='dd',
183+
arguments=["double r", "double i"],
184+
cmpfunc=unhandled_error_compare
185+
)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ public PByteArray setEmpty(Object cls, @SuppressWarnings("unused") Object arg) {
355355
"Create a complex number from a real part and an optional imaginary part.\n" +
356356
"This is equivalent to (real + imag*1j) where imag defaults to 0.")
357357
@GenerateNodeFactory
358-
public abstract static class ComplexNode extends PythonBuiltinNode {
358+
public abstract static class ComplexNode extends PythonTernaryBuiltinNode {
359359

360360
@Child private IsBuiltinClassProfile isPrimitiveProfile = IsBuiltinClassProfile.create();
361361
@Child private IsBuiltinClassProfile isComplexTypeProfile;

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

Lines changed: 123 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@
9090
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
9191
import com.oracle.graal.python.builtins.PythonBuiltins;
9292
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.BytesNode;
93+
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.ComplexNode;
9394
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.FrozenSetNode;
9495
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.MappingproxyNode;
9596
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.StrNode;
@@ -204,6 +205,7 @@
204205
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemNode;
205206
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetItemScalarNode;
206207
import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.LenNode;
208+
import com.oracle.graal.python.builtins.objects.complex.PComplex;
207209
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins;
208210
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.DelItemNode;
209211
import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.ItemsNode;
@@ -282,6 +284,7 @@
282284
import com.oracle.graal.python.nodes.PRaiseNode;
283285
import com.oracle.graal.python.nodes.SpecialAttributeNames;
284286
import com.oracle.graal.python.nodes.SpecialMethodNames;
287+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__FLOAT__;
285288
import com.oracle.graal.python.nodes.WriteUnraisableNode;
286289
import com.oracle.graal.python.nodes.argument.CreateArgumentsNode.CreateAndCheckArgumentsNode;
287290
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
@@ -2219,7 +2222,7 @@ protected boolean isListSubtype(VirtualFrame frame, Object obj, GetClassNode get
22192222
return isSubtypeNode.execute(frame, getClassNode.execute(obj), PythonBuiltinClassType.PList);
22202223
}
22212224
}
2222-
2225+
22232226
///////////// long /////////////
22242227

22252228
@Builtin(name = "_PyLong_Sign", minNumOfPositionalArgs = 1)
@@ -2333,7 +2336,7 @@ Object fromDouble(VirtualFrame frame, double d,
23332336

23342337
@Builtin(name = "PyLong_FromString", minNumOfPositionalArgs = 3)
23352338
@TypeSystemReference(PythonTypes.class)
2336-
@GenerateNodeFactory
2339+
@GenerateNodeFactory
23372340
abstract static class PyLongFromStringNode extends PythonTernaryBuiltinNode {
23382341

23392342
@Specialization(guards = "negative == 0")
@@ -2363,7 +2366,7 @@ Object fromString(VirtualFrame frame, String s, long base, @SuppressWarnings("un
23632366
}
23642367
}
23652368
}
2366-
2369+
23672370
///////////// float /////////////
23682371

23692372
@Builtin(name = "PyFloat_FromDouble", minNumOfPositionalArgs = 1)
@@ -2385,7 +2388,123 @@ public Object fromDouble(VirtualFrame frame, Object obj,
23852388
return raiseNativeNode.raiseInt(frame, -1, SystemError, BAD_ARG_TO_INTERNAL_FUNC_WAS_S_P, strNode.executeWith(frame, obj), obj);
23862389
}
23872390
}
2388-
2391+
2392+
///////////// complex /////////////
2393+
2394+
@Builtin(name = "PyComplex_AsCComplex", minNumOfPositionalArgs = 1)
2395+
@GenerateNodeFactory
2396+
abstract static class PyComplexAsCComplexNode extends PythonUnaryBuiltinNode {
2397+
@Specialization
2398+
PTuple asComplex(PComplex c) {
2399+
return factory().createTuple(new Object[]{c.getReal(), c.getImag()});
2400+
}
2401+
2402+
@Specialization(guards = "!isPComplex(obj)")
2403+
Object asComplex(VirtualFrame frame, Object obj,
2404+
@Cached ComplexNode complexNode,
2405+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode,
2406+
@Cached GetNativeNullNode getNativeNullNode) {
2407+
try {
2408+
PComplex c = (PComplex) complexNode.execute(frame, PythonBuiltinClassType.PComplex, obj, PNone.NO_VALUE);
2409+
return factory().createTuple(new Object[]{c.getReal(), c.getImag()});
2410+
} catch (PException e) {
2411+
transformExceptionToNativeNode.execute(e);
2412+
return getNativeNullNode.execute();
2413+
}
2414+
}
2415+
}
2416+
2417+
@Builtin(name = "PyComplex_RealAsDouble", minNumOfPositionalArgs = 1)
2418+
@GenerateNodeFactory
2419+
abstract static class PyComplexRealAsDoubleNode extends PythonUnaryBuiltinNode {
2420+
2421+
@Specialization
2422+
double asDouble(PComplex d) {
2423+
return d.getReal();
2424+
}
2425+
2426+
@Specialization(guards = {"!isPComplex(obj)", "isComplexSubtype(frame, obj, getClassNode, isSubtypeNode)"})
2427+
public Object asDouble(VirtualFrame frame, Object obj,
2428+
@Cached PyObjectGetAttr getAttr,
2429+
@Cached CallNode callNode,
2430+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
2431+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
2432+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
2433+
try {
2434+
return callNode.execute(getAttr.execute(frame, obj, "real"));
2435+
} catch (PException e) {
2436+
transformExceptionToNativeNode.execute(e);
2437+
return -1.0;
2438+
}
2439+
}
2440+
2441+
@Specialization(guards = {"!isPComplex(obj)", "!isComplexSubtype(frame, obj, getClassNode, isSubtypeNode)"})
2442+
public Object asDoubleFloat(VirtualFrame frame, Object obj,
2443+
@Cached PyObjectGetAttr getAttr,
2444+
@Cached CallNode callNode,
2445+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
2446+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
2447+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
2448+
try {
2449+
return callNode.execute(getAttr.execute(frame, obj, __FLOAT__));
2450+
} catch (PException e) {
2451+
transformExceptionToNativeNode.execute(e);
2452+
return -1.0;
2453+
}
2454+
}
2455+
2456+
protected boolean isComplexSubtype(VirtualFrame frame, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) {
2457+
return isSubtypeNode.execute(frame, getClassNode.execute(obj), PythonBuiltinClassType.PComplex);
2458+
}
2459+
}
2460+
2461+
@Builtin(name = "PyComplex_ImagAsDouble", minNumOfPositionalArgs = 1)
2462+
@GenerateNodeFactory
2463+
abstract static class PyComplexImagAsDoubleNode extends PythonUnaryBuiltinNode {
2464+
2465+
@Specialization
2466+
double asDouble(PComplex d) {
2467+
return d.getImag();
2468+
}
2469+
2470+
@Specialization(guards = {"!isPComplex(obj)", "isComplexSubtype(frame, obj, getClassNode, isSubtypeNode)"})
2471+
public Object asDouble(VirtualFrame frame, Object obj,
2472+
@Cached PyObjectGetAttr getAttr,
2473+
@Cached CallNode callNode,
2474+
@SuppressWarnings("unused") @Cached GetClassNode getClassNode,
2475+
@SuppressWarnings("unused") @Cached IsSubtypeNode isSubtypeNode,
2476+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
2477+
try {
2478+
return callNode.execute(getAttr.execute(frame, obj, "imag"));
2479+
} catch (PException e) {
2480+
transformExceptionToNativeNode.execute(e);
2481+
return -1;
2482+
}
2483+
}
2484+
2485+
@SuppressWarnings("unused")
2486+
@Specialization(guards = {"!isPComplex(obj)", "!isComplexSubtype(frame, obj, getClassNode, isSubtypeNode)"})
2487+
public Object asDouble(VirtualFrame frame, Object obj,
2488+
@Cached GetClassNode getClassNode,
2489+
@Cached IsSubtypeNode isSubtypeNode) {
2490+
return 0.0;
2491+
}
2492+
2493+
protected boolean isComplexSubtype(VirtualFrame frame, Object obj, GetClassNode getClassNode, IsSubtypeNode isSubtypeNode) {
2494+
return isSubtypeNode.execute(frame, getClassNode.execute(obj), PythonBuiltinClassType.PComplex);
2495+
}
2496+
}
2497+
2498+
@Builtin(name = "PyComplex_FromDoubles", minNumOfPositionalArgs = 1)
2499+
@GenerateNodeFactory
2500+
abstract static class PyComplexFromDoublesNode extends PythonBinaryBuiltinNode {
2501+
2502+
@Specialization
2503+
public PComplex asDouble(double r, double i) {
2504+
return factory().createComplex(r, i);
2505+
}
2506+
}
2507+
23892508
/**
23902509
* This is used in the ExternalFunctionNode below, so all arguments passed from Python code into
23912510
* a C function are automatically unwrapped if they are wrapped. This function is also called

graalpython/lib-graalpython/python_cext.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -66,32 +66,6 @@ def PyDictProxy_New(mapping):
6666
mappingproxy = type(type.__dict__)
6767
return mappingproxy(mapping)
6868

69-
##################### COMPLEX
70-
71-
@may_raise
72-
def PyComplex_AsCComplex(n):
73-
obj = complex(n)
74-
return (obj.real, obj.imag)
75-
76-
77-
@may_raise(-1.0)
78-
def PyComplex_RealAsDouble(n):
79-
if isinstance(n, complex):
80-
return n.real
81-
return n.__float__()
82-
83-
84-
def PyComplex_ImagAsDouble(n):
85-
if isinstance(n, complex):
86-
return n.imag
87-
return 0.0
88-
89-
90-
@may_raise
91-
def PyComplex_FromDoubles(real, imag):
92-
return complex(real, imag)
93-
94-
9569
##################### NUMBER
9670

9771
def _safe_check(v, type_check):

0 commit comments

Comments
 (0)