Skip to content

Commit 33a96f4

Browse files
committed
Refactor to-sulong/to-java conversion nodes.
1 parent bbb08e1 commit 33a96f4

File tree

6 files changed

+176
-136
lines changed

6 files changed

+176
-136
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@
5252
import com.oracle.graal.python.builtins.Builtin;
5353
import com.oracle.graal.python.builtins.CoreFunctions;
5454
import com.oracle.graal.python.builtins.PythonBuiltins;
55-
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltins.AsPythonObjectNode;
5655
import com.oracle.graal.python.builtins.objects.PNone;
56+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.AsPythonObjectNode;
5757
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.SetItemNode;
5858
import com.oracle.graal.python.builtins.objects.dict.PDict;
5959
import com.oracle.graal.python.builtins.objects.function.PArguments;

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

Lines changed: 8 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,8 @@
6161
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
6262
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins;
6363
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
64+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes;
6465
import com.oracle.graal.python.builtins.objects.cext.NativeCAPISymbols;
65-
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
66-
import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject;
6766
import com.oracle.graal.python.builtins.objects.cext.PythonObjectNativeWrapper;
6867
import com.oracle.graal.python.builtins.objects.cext.UnicodeObjectNodes.UnicodeAsWideCharNode;
6968
import com.oracle.graal.python.builtins.objects.complex.PComplex;
@@ -72,7 +71,6 @@
7271
import com.oracle.graal.python.builtins.objects.function.Arity;
7372
import com.oracle.graal.python.builtins.objects.function.PArguments;
7473
import com.oracle.graal.python.builtins.objects.ints.PInt;
75-
import com.oracle.graal.python.builtins.objects.object.PythonObject;
7674
import com.oracle.graal.python.builtins.objects.str.PString;
7775
import com.oracle.graal.python.builtins.objects.traceback.PTraceback;
7876
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
@@ -113,7 +111,6 @@
113111
import com.oracle.truffle.api.interop.UnsupportedTypeException;
114112
import com.oracle.truffle.api.nodes.Node;
115113
import com.oracle.truffle.api.nodes.RootNode;
116-
import com.oracle.truffle.api.profiles.ConditionProfile;
117114

118115
@CoreFunctions(defineModule = "python_cext")
119116
public class TruffleCextBuiltins extends PythonBuiltins {
@@ -129,45 +126,11 @@ protected List<? extends NodeFactory<? extends PythonBuiltinNode>> getNodeFactor
129126
*/
130127
@Builtin(name = "to_java", fixedNumOfArguments = 1)
131128
@GenerateNodeFactory
132-
public abstract static class AsPythonObjectNode extends PythonBuiltinNode {
133-
public abstract Object execute(Object value);
134-
135-
@Child GetClassNode getClassNode = GetClassNode.create();
136-
ConditionProfile branchCond = ConditionProfile.createBinaryProfile();
137-
138-
@Specialization
139-
Object run(PythonObjectNativeWrapper object) {
140-
return object.getPythonObject();
141-
}
142-
129+
public abstract static class AsPythonObjectNode extends PythonUnaryBuiltinNode {
143130
@Specialization
144-
Object run(PythonAbstractObject object) {
145-
return object;
146-
}
147-
148-
@Fallback
149-
Object run(Object obj) {
150-
if (branchCond.profile(getClassNode.execute(obj) == getCore().getForeignClass())) {
151-
// TODO: this should very likely only be done for objects that come from Sulong...
152-
// TODO: prevent calling this from any other place
153-
return factory().createNativeObjectWrapper(obj);
154-
} else {
155-
return obj;
156-
}
157-
}
158-
159-
@TruffleBoundary
160-
public static Object doSlowPath(Object object) {
161-
if (object instanceof PythonObjectNativeWrapper) {
162-
return ((PythonObjectNativeWrapper) object).getPythonObject();
163-
} else if (GetClassNode.getItSlowPath(object) == PythonLanguage.getCore().getForeignClass()) {
164-
throw new AssertionError("Unsupported slow path operation: converting 'to_java(" + object + ")");
165-
}
166-
return object;
167-
}
168-
169-
public static AsPythonObjectNode create() {
170-
return TruffleCextBuiltinsFactory.AsPythonObjectNodeFactory.create(null);
131+
Object run(Object object,
132+
@Cached("create()") CExtNodes.AsPythonObjectNode toJavaNode) {
133+
return toJavaNode.execute(object);
171134
}
172135
}
173136

@@ -232,67 +195,10 @@ Object run(String str) {
232195
@GenerateNodeFactory
233196
public abstract static class ToSulongNode extends PythonUnaryBuiltinNode {
234197

235-
/*
236-
* This is very sad. Only for Sulong, we cannot hand out java.lang.Strings, because then it
237-
* won't know what to do with them when they go native. So all places where Strings may be
238-
* passed from Python into C code need to wrap Strings into PStrings.
239-
*/
240-
@Specialization
241-
Object run(String str) {
242-
return PythonObjectNativeWrapper.wrap(factory().createString(str));
243-
}
244-
245-
@Specialization
246-
Object run(boolean b) {
247-
return PythonObjectNativeWrapper.wrap(factory().createInt(b));
248-
}
249-
250198
@Specialization
251-
Object run(int integer) {
252-
return PythonObjectNativeWrapper.wrap(factory().createInt(integer));
253-
}
254-
255-
@Specialization
256-
Object run(long integer) {
257-
return PythonObjectNativeWrapper.wrap(factory().createInt(integer));
258-
}
259-
260-
@Specialization
261-
Object run(double number) {
262-
return PythonObjectNativeWrapper.wrap(factory().createFloat(number));
263-
}
264-
265-
@Specialization
266-
Object runNativeClass(PythonNativeClass object) {
267-
return object.object;
268-
}
269-
270-
@Specialization
271-
Object runNativeObject(PythonNativeObject object) {
272-
return object.object;
273-
}
274-
275-
@Specialization(guards = "isNone(none)")
276-
Object run(PNone none) {
277-
return PythonObjectNativeWrapper.wrap(none);
278-
}
279-
280-
@Specialization(guards = "!isNativeClass(object)")
281-
Object runNativeObject(PythonObject object) {
282-
return PythonObjectNativeWrapper.wrap(object);
283-
}
284-
285-
@Fallback
286-
Object run(Object obj) {
287-
return obj;
288-
}
289-
290-
protected boolean isNativeClass(PythonObject o) {
291-
return o instanceof PythonNativeClass;
292-
}
293-
294-
public static ToSulongNode create() {
295-
return TruffleCextBuiltinsFactory.ToSulongNodeFactory.create(null);
199+
Object run(Object obj,
200+
@Cached("create()") CExtNodes.ToSulongNode toSulongNode) {
201+
return toSulongNode.execute(obj);
296202
}
297203
}
298204

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.oracle.graal.python.builtins.objects.cext;
2+
3+
import com.oracle.graal.python.PythonLanguage;
4+
import com.oracle.graal.python.builtins.objects.PNone;
5+
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
6+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.AsPythonObjectNodeGen;
7+
import com.oracle.graal.python.builtins.objects.cext.CExtNodesFactory.ToSulongNodeGen;
8+
import com.oracle.graal.python.nodes.PBaseNode;
9+
import com.oracle.graal.python.nodes.PGuards;
10+
import com.oracle.graal.python.nodes.object.GetClassNode;
11+
import com.oracle.truffle.api.CompilerDirectives;
12+
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
13+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
14+
import com.oracle.truffle.api.dsl.Fallback;
15+
import com.oracle.truffle.api.dsl.ImportStatic;
16+
import com.oracle.truffle.api.dsl.Specialization;
17+
import com.oracle.truffle.api.interop.TruffleObject;
18+
import com.oracle.truffle.api.profiles.ConditionProfile;
19+
20+
public abstract class CExtNodes {
21+
22+
@ImportStatic(PGuards.class)
23+
public abstract static class ToSulongNode extends PBaseNode {
24+
25+
public abstract Object execute(Object obj);
26+
27+
/*
28+
* This is very sad. Only for Sulong, we cannot hand out java.lang.Strings, because then it
29+
* won't know what to do with them when they go native. So all places where Strings may be
30+
* passed from Python into C code need to wrap Strings into PStrings.
31+
*/
32+
@Specialization
33+
Object run(String str) {
34+
return PythonObjectNativeWrapper.wrap(factory().createString(str));
35+
}
36+
37+
@Specialization
38+
Object run(boolean b) {
39+
return PythonObjectNativeWrapper.wrap(factory().createInt(b));
40+
}
41+
42+
@Specialization
43+
Object run(int integer) {
44+
return PythonObjectNativeWrapper.wrap(factory().createInt(integer));
45+
}
46+
47+
@Specialization
48+
Object run(long integer) {
49+
return PythonObjectNativeWrapper.wrap(factory().createInt(integer));
50+
}
51+
52+
@Specialization
53+
Object run(double number) {
54+
return PythonObjectNativeWrapper.wrap(factory().createFloat(number));
55+
}
56+
57+
@Specialization
58+
Object runNativeClass(PythonNativeClass object) {
59+
return object.object;
60+
}
61+
62+
@Specialization
63+
Object runNativeObject(PythonNativeObject object) {
64+
return object.object;
65+
}
66+
67+
@Specialization(guards = {"!isNativeClass(object)", "!isNativeObject(object)"})
68+
Object runNativeObject(PythonAbstractObject object) {
69+
assert object != PNone.NO_VALUE;
70+
return PythonObjectNativeWrapper.wrap(object);
71+
}
72+
73+
@Fallback
74+
Object run(Object obj) {
75+
return obj;
76+
}
77+
78+
protected static boolean isNativeClass(PythonAbstractObject o) {
79+
return o instanceof PythonNativeClass;
80+
}
81+
82+
protected static boolean isNativeObject(PythonAbstractObject o) {
83+
return o instanceof PythonNativeObject;
84+
}
85+
86+
public static ToSulongNode create() {
87+
return ToSulongNodeGen.create();
88+
}
89+
}
90+
91+
/**
92+
* Unwraps objects contained in {@link PythonObjectNativeWrapper} instances or wraps objects
93+
* allocated in native code for consumption in Java.
94+
*/
95+
@ImportStatic(PGuards.class)
96+
public abstract static class AsPythonObjectNode extends PBaseNode {
97+
public abstract Object execute(Object value);
98+
99+
@Child GetClassNode getClassNode = GetClassNode.create();
100+
ConditionProfile branchCond = ConditionProfile.createBinaryProfile();
101+
102+
@Specialization
103+
Object run(PythonObjectNativeWrapper object) {
104+
return object.getPythonObject();
105+
}
106+
107+
@Specialization
108+
Object run(PythonAbstractObject object) {
109+
return object;
110+
}
111+
112+
@Fallback
113+
Object run(Object obj) {
114+
if (branchCond.profile(getClassNode.execute(obj) == getCore().getForeignClass())) {
115+
// TODO: this should very likely only be done for objects that come from Sulong...
116+
// TODO: prevent calling this from any other place
117+
return factory().createNativeObjectWrapper(obj);
118+
} else {
119+
return obj;
120+
}
121+
}
122+
123+
@TruffleBoundary
124+
public static Object doSlowPath(Object object) {
125+
if (object instanceof PythonObjectNativeWrapper) {
126+
return ((PythonObjectNativeWrapper) object).getPythonObject();
127+
} else if (GetClassNode.getItSlowPath(object) == PythonLanguage.getCore().getForeignClass()) {
128+
throw new AssertionError("Unsupported slow path operation: converting 'to_java(" + object + ")");
129+
}
130+
return object;
131+
}
132+
133+
public static AsPythonObjectNode create() {
134+
return AsPythonObjectNodeGen.create();
135+
}
136+
}
137+
138+
/**
139+
* Does the same conversion as the native function {@code to_java}.
140+
*/
141+
static class ToJavaNode extends PBaseNode {
142+
@Child private PCallNativeNode callNativeNode = PCallNativeNode.create(1);
143+
@Child private AsPythonObjectNode toJavaNode = AsPythonObjectNode.create();
144+
145+
@CompilationFinal TruffleObject nativeToJavaFunction;
146+
147+
Object execute(Object value) {
148+
if (nativeToJavaFunction == null) {
149+
CompilerDirectives.transferToInterpreterAndInvalidate();
150+
nativeToJavaFunction = (TruffleObject) getContext().getEnv().importSymbol(NativeCAPISymbols.FUNCTION_NATIVE_TO_JAVA);
151+
}
152+
return toJavaNode.execute(callNativeNode.execute(nativeToJavaFunction, new Object[]{value}));
153+
}
154+
155+
public static ToJavaNode create() {
156+
return new ToJavaNode();
157+
}
158+
159+
}
160+
161+
}

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

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@
3838
*/
3939
package com.oracle.graal.python.builtins.objects.cext;
4040

41-
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltins.AsPythonObjectNode;
42-
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltins.ToSulongNode;
4341
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
42+
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.ToSulongNode;
4443
import com.oracle.graal.python.builtins.objects.cext.PySequenceArrayWrapperMRFactory.ReadArrayItemNodeGen;
4544
import com.oracle.graal.python.builtins.objects.cext.PySequenceArrayWrapperMRFactory.WriteArrayItemNodeGen;
4645
import com.oracle.graal.python.builtins.objects.list.ListBuiltins;
@@ -49,18 +48,15 @@
4948
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
5049
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
5150
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltinsFactory;
52-
import com.oracle.graal.python.nodes.PBaseNode;
5351
import com.oracle.graal.python.nodes.SpecialMethodNames;
5452
import com.oracle.graal.python.nodes.truffle.PythonTypes;
5553
import com.oracle.truffle.api.CompilerDirectives;
56-
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
5754
import com.oracle.truffle.api.dsl.Cached;
5855
import com.oracle.truffle.api.dsl.ImportStatic;
5956
import com.oracle.truffle.api.dsl.Specialization;
6057
import com.oracle.truffle.api.dsl.TypeSystemReference;
6158
import com.oracle.truffle.api.interop.MessageResolution;
6259
import com.oracle.truffle.api.interop.Resolve;
63-
import com.oracle.truffle.api.interop.TruffleObject;
6460
import com.oracle.truffle.api.nodes.Node;
6561

6662
@MessageResolution(receiverType = PySequenceArrayWrapper.class)
@@ -95,7 +91,7 @@ private ToSulongNode getToSulongNode() {
9591
@Resolve(message = "WRITE")
9692
abstract static class WriteNode extends Node {
9793
@Child private WriteArrayItemNode writeArrayItemNode;
98-
@Child private ToJavaNode toJavaNode;
94+
@Child private CExtNodes.ToJavaNode toJavaNode;
9995

10096
public Object access(PySequenceArrayWrapper object, Object key, Object value) {
10197
if (writeArrayItemNode == null) {
@@ -108,38 +104,15 @@ public Object access(PySequenceArrayWrapper object, Object key, Object value) {
108104
return value;
109105
}
110106

111-
private ToJavaNode getToJavaNode() {
107+
private CExtNodes.ToJavaNode getToJavaNode() {
112108
if (toJavaNode == null) {
113109
CompilerDirectives.transferToInterpreterAndInvalidate();
114-
toJavaNode = insert(ToJavaNode.create());
110+
toJavaNode = insert(CExtNodes.ToJavaNode.create());
115111
}
116112
return toJavaNode;
117113
}
118114
}
119115

120-
/**
121-
* Does the same conversion as the native function {@code to_java}.
122-
*/
123-
static class ToJavaNode extends PBaseNode {
124-
@Child private PCallNativeNode callNativeNode = PCallNativeNode.create(1);
125-
@Child private AsPythonObjectNode toJavaNode = AsPythonObjectNode.create();
126-
127-
@CompilationFinal TruffleObject nativeToJavaFunction;
128-
129-
Object execute(Object value) {
130-
if (nativeToJavaFunction == null) {
131-
CompilerDirectives.transferToInterpreterAndInvalidate();
132-
nativeToJavaFunction = (TruffleObject) getContext().getEnv().importSymbol(NativeCAPISymbols.FUNCTION_NATIVE_TO_JAVA);
133-
}
134-
return toJavaNode.execute(callNativeNode.execute(nativeToJavaFunction, new Object[]{value}));
135-
}
136-
137-
public static ToJavaNode create() {
138-
return new ToJavaNode();
139-
}
140-
141-
}
142-
143116
@ImportStatic(SpecialMethodNames.class)
144117
@TypeSystemReference(PythonTypes.class)
145118
abstract static class ReadArrayItemNode extends Node {

0 commit comments

Comments
 (0)