Skip to content

Commit afb998d

Browse files
committed
Refactor LookupAndCallBinaryNode
* when the callable is not found it throws ControlFlowException, PNotImplemented is valid return type * document the semantics w.r.t. CPython helper methods * revise all call-sites and use appropriate lookup/call node according to CPython semantics
1 parent d04c2cb commit afb998d

File tree

9 files changed

+215
-215
lines changed

9 files changed

+215
-215
lines changed

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

+20-17
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import static com.oracle.graal.python.builtins.modules.io.IONodes.T_WRITE;
3434
import static com.oracle.graal.python.builtins.objects.PNone.NONE;
3535
import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
36-
import static com.oracle.graal.python.builtins.objects.PNotImplemented.NOT_IMPLEMENTED;
3736
import static com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback.raiseSyntaxError;
3837
import static com.oracle.graal.python.nodes.BuiltinNames.J_ABS;
3938
import static com.oracle.graal.python.nodes.BuiltinNames.J_ALL;
@@ -166,7 +165,6 @@
166165
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode;
167166
import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsTypeNode;
168167
import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.CallSlotTpIterNextNode;
169-
import com.oracle.graal.python.lib.RichCmpOp;
170168
import com.oracle.graal.python.compiler.Compiler;
171169
import com.oracle.graal.python.compiler.RaisePythonExceptionErrorCallback;
172170
import com.oracle.graal.python.lib.IteratorExhausted;
@@ -200,6 +198,7 @@
200198
import com.oracle.graal.python.lib.PyObjectStrAsObjectNode;
201199
import com.oracle.graal.python.lib.PyObjectStrAsTruffleStringNode;
202200
import com.oracle.graal.python.lib.PyUnicodeFSDecoderNode;
201+
import com.oracle.graal.python.lib.RichCmpOp;
203202
import com.oracle.graal.python.nodes.BuiltinNames;
204203
import com.oracle.graal.python.nodes.ErrorMessages;
205204
import com.oracle.graal.python.nodes.PConstructAndRaiseNode;
@@ -224,6 +223,7 @@
224223
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
225224
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
226225
import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode;
226+
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
227227
import com.oracle.graal.python.nodes.classes.IsSubtypeNode;
228228
import com.oracle.graal.python.nodes.frame.GetFrameLocalsNode;
229229
import com.oracle.graal.python.nodes.frame.ReadCallerFrameNode;
@@ -1450,11 +1450,12 @@ public IsInstanceNode createRecursive(byte newDepth) {
14501450

14511451
private static TriState isInstanceCheckInternal(VirtualFrame frame, Object instance, Object cls, LookupAndCallBinaryNode instanceCheckNode,
14521452
PyObjectIsTrueNode castToBooleanNode) {
1453-
Object instanceCheckResult = instanceCheckNode.executeObject(frame, cls, instance);
1454-
if (instanceCheckResult == NOT_IMPLEMENTED) {
1453+
try {
1454+
Object instanceCheckResult = instanceCheckNode.executeObject(frame, cls, instance);
1455+
return TriState.valueOf(castToBooleanNode.execute(frame, instanceCheckResult));
1456+
} catch (SpecialMethodNotFound ignore) {
14551457
return TriState.UNDEFINED;
14561458
}
1457-
return TriState.valueOf(castToBooleanNode.execute(frame, instanceCheckResult));
14581459
}
14591460

14601461
@Specialization(guards = "isPythonClass(cls)")
@@ -1508,11 +1509,12 @@ static boolean isSubclass(VirtualFrame frame, Object derived, Object cls,
15081509
@Cached("create(Subclasscheck)") LookupAndCallBinaryNode subclassCheckNode,
15091510
@Cached PyObjectIsTrueNode castToBooleanNode,
15101511
@Cached IsSubtypeNode isSubtypeNode) {
1511-
Object instanceCheckResult = subclassCheckNode.executeObject(frame, cls, derived);
1512-
if (instanceCheckResult != NOT_IMPLEMENTED) {
1512+
try {
1513+
Object instanceCheckResult = subclassCheckNode.executeObject(frame, cls, derived);
15131514
return castToBooleanNode.execute(frame, instanceCheckResult);
1515+
} catch (SpecialMethodNotFound ignore) {
1516+
return isSubtypeNode.execute(frame, derived, cls);
15141517
}
1515-
return isSubtypeNode.execute(frame, derived, cls);
15161518
}
15171519

15181520
@NeverDefault
@@ -1930,14 +1932,15 @@ public static Object format(VirtualFrame frame, Object obj, Object formatSpec,
19301932
@Cached InlinedConditionProfile formatIsNoValueProfile,
19311933
@Cached PRaiseNode raiseNode) {
19321934
Object format = formatIsNoValueProfile.profile(inliningTarget, isNoValue(formatSpec)) ? T_EMPTY_STRING : formatSpec;
1933-
Object res = callFormat.executeObject(frame, obj, format);
1934-
if (res == NO_VALUE) {
1935+
try {
1936+
Object res = callFormat.executeObject(frame, obj, format);
1937+
if (!PGuards.isString(res)) {
1938+
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res);
1939+
}
1940+
return res;
1941+
} catch (SpecialMethodNotFound ignore) {
19351942
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj);
19361943
}
1937-
if (!PGuards.isString(res)) {
1938-
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res);
1939-
}
1940-
return res;
19411944
}
19421945

19431946
@NeverDefault
@@ -1980,11 +1983,11 @@ static Object round(VirtualFrame frame, Object x, Object n,
19801983
@Bind("this") Node inliningTarget,
19811984
@Cached("create(Round)") LookupAndCallBinaryNode callRound,
19821985
@Shared @Cached PRaiseNode raiseNode) {
1983-
Object result = callRound.executeObject(frame, x, n);
1984-
if (result == NOT_IMPLEMENTED) {
1986+
try {
1987+
return callRound.executeObject(frame, x, n);
1988+
} catch (SpecialMethodNotFound ignore) {
19851989
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_METHOD, x, T___ROUND__);
19861990
}
1987-
return result;
19881991
}
19891992
}
19901993

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

+4-7
Original file line numberDiff line numberDiff line change
@@ -151,30 +151,27 @@ protected ArgumentClinicProvider getArgumentClinic() {
151151
return DumpNodeClinicProviderGen.INSTANCE;
152152
}
153153

154-
@NeverDefault
155-
protected static LookupAndCallBinaryNode createCallWriteNode() {
156-
return LookupAndCallBinaryNode.create(T_WRITE);
157-
}
158-
159154
@Specialization
160155
static Object doit(VirtualFrame frame, Object value, Object file, int version,
161156
@Bind("this") Node inliningTarget,
162157
@Bind PythonContext context,
163158
@Cached("createFor(this)") IndirectCallData indirectCallData,
164-
@Cached("createCallWriteNode()") LookupAndCallBinaryNode callNode,
159+
@Cached PyObjectCallMethodObjArgs callMethod,
165160
@Cached PRaiseNode raiseNode) {
166161
PythonLanguage language = context.getLanguage(inliningTarget);
167162
PythonContext.PythonThreadState threadState = context.getThreadState(language);
168163
Object savedState = IndirectCallContext.enter(frame, threadState, indirectCallData);
164+
byte[] data;
169165
try {
170-
return callNode.executeObject(frame, file, PFactory.createBytes(language, Marshal.dump(context, value, version)));
166+
data = Marshal.dump(context, value, version);
171167
} catch (IOException e) {
172168
throw CompilerDirectives.shouldNotReachHere(e);
173169
} catch (Marshal.MarshalError me) {
174170
throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments);
175171
} finally {
176172
IndirectCallContext.exit(frame, threadState, savedState);
177173
}
174+
return callMethod.execute(frame, inliningTarget, file, T_WRITE, PFactory.createBytes(language, data));
178175
}
179176
}
180177

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

+9-1
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@
3737
import com.oracle.graal.python.builtins.objects.PNone;
3838
import com.oracle.graal.python.builtins.objects.random.PRandom;
3939
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
40+
import com.oracle.graal.python.nodes.PRaiseNode;
4041
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
42+
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
4143
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
4244
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
4345
import com.oracle.graal.python.runtime.object.PFactory;
46+
import com.oracle.truffle.api.CompilerDirectives;
4447
import com.oracle.truffle.api.dsl.Bind;
4548
import com.oracle.truffle.api.dsl.Cached;
4649
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
@@ -70,7 +73,12 @@ PRandom random(VirtualFrame frame, Object cls, Object seed,
7073
@Bind PythonLanguage language,
7174
@Cached TypeNodes.GetInstanceShape getInstanceShape) {
7275
PRandom random = PFactory.createRandom(language, cls, getInstanceShape.execute(cls));
73-
setSeed.executeObject(frame, random, seed != PNone.NO_VALUE ? seed : PNone.NONE);
76+
try {
77+
setSeed.executeObject(frame, random, seed != PNone.NO_VALUE ? seed : PNone.NONE);
78+
} catch (SpecialMethodNotFound ignore) {
79+
CompilerDirectives.transferToInterpreterAndInvalidate();
80+
throw PRaiseNode.raiseStatic(this, PythonBuiltinClassType.SystemError);
81+
}
7482
return random;
7583
}
7684
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/dict/DictBuiltins.java

+6-9
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@
8484
import com.oracle.graal.python.nodes.PGuards;
8585
import com.oracle.graal.python.nodes.PRaiseNode;
8686
import com.oracle.graal.python.nodes.call.CallNode;
87-
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
88-
import com.oracle.graal.python.nodes.call.special.LookupSpecialMethodSlotNode;
87+
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
88+
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
8989
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
9090
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
9191
import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode;
@@ -94,7 +94,6 @@
9494
import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode;
9595
import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode;
9696
import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider;
97-
import com.oracle.graal.python.nodes.object.GetClassNode;
9897
import com.oracle.graal.python.runtime.object.PFactory;
9998
import com.oracle.truffle.api.CompilerDirectives;
10099
import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff;
@@ -341,15 +340,13 @@ protected abstract static class DispatchMissingNode extends Node {
341340
@Specialization
342341
static Object missing(VirtualFrame frame, Object self, Object key,
343342
@Bind("this") Node inliningTarget,
344-
@Cached GetClassNode getClassNode,
345-
@Cached("create(Missing)") LookupSpecialMethodSlotNode lookupMissingNode,
346-
@Cached CallBinaryMethodNode callMissingNode,
343+
@Cached("create(Missing)") LookupAndCallBinaryNode callMissing,
347344
@Cached PRaiseNode raiseNode) {
348-
Object missingFun = lookupMissingNode.execute(frame, getClassNode.execute(inliningTarget, self), self);
349-
if (PGuards.isNoValue(missingFun)) {
345+
try {
346+
return callMissing.executeObject(frame, self, key);
347+
} catch (SpecialMethodNotFound ignored) {
350348
throw raiseNode.raise(inliningTarget, KeyError, new Object[]{key});
351349
}
352-
return callMissingNode.executeObject(frame, missingFun, self, key);
353350
}
354351
}
355352

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/foreign/ForeignNumberBuiltins.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import com.oracle.graal.python.nodes.SpecialMethodNames;
8282
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
8383
import com.oracle.graal.python.nodes.call.special.LookupAndCallUnaryNode;
84+
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
8485
import com.oracle.graal.python.nodes.expression.BinaryOpNode;
8586
import com.oracle.graal.python.nodes.expression.UnaryOpNode;
8687
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
@@ -609,7 +610,11 @@ Object doGeneric(VirtualFrame frame, Object self, Object n,
609610
@Cached UnboxNode unboxNode,
610611
@Cached("create(Round)") LookupAndCallBinaryNode callRound) {
611612
Object unboxed = unboxNode.execute(inliningTarget, self);
612-
return callRound.executeObject(frame, unboxed, n);
613+
try {
614+
return callRound.executeObject(frame, unboxed, n);
615+
} catch (SpecialMethodNotFound ignore) {
616+
throw CompilerDirectives.shouldNotReachHere();
617+
}
613618
}
614619
}
615620

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectFormat.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
*/
4141
package com.oracle.graal.python.lib;
4242

43-
import static com.oracle.graal.python.builtins.objects.PNone.NO_VALUE;
4443
import static com.oracle.graal.python.nodes.SpecialMethodNames.T___FORMAT__;
4544
import static com.oracle.graal.python.nodes.StringLiterals.T_EMPTY_STRING;
4645
import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError;
@@ -55,6 +54,7 @@
5554
import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode;
5655
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
5756
import com.oracle.graal.python.nodes.call.special.LookupAndCallBinaryNode;
57+
import com.oracle.graal.python.nodes.call.special.SpecialMethodNotFound;
5858
import com.oracle.graal.python.nodes.object.GetClassNode;
5959
import com.oracle.graal.python.util.PythonUtils;
6060
import com.oracle.truffle.api.dsl.Bind;
@@ -124,14 +124,15 @@ static Object doLong(long obj, Object formatSpec) {
124124
static Object doGeneric(VirtualFrame frame, Node inliningTarget, Object obj, Object formatSpec,
125125
@Cached(parameters = "Format", inline = false) LookupAndCallBinaryNode callFormat,
126126
@Exclusive @Cached PRaiseNode raiseNode) {
127-
Object res = callFormat.executeObject(frame, obj, formatSpec);
128-
if (res == NO_VALUE) {
127+
try {
128+
Object res = callFormat.executeObject(frame, obj, formatSpec);
129+
if (!PGuards.isString(res)) {
130+
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res);
131+
}
132+
return res;
133+
} catch (SpecialMethodNotFound ignore) {
129134
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.TYPE_DOESNT_DEFINE_FORMAT, obj);
130135
}
131-
if (!PGuards.isString(res)) {
132-
throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_MUST_RETURN_S_NOT_P, T___FORMAT__, "str", res);
133-
}
134-
return res;
135136
}
136137

137138
@Specialization(guards = "isString(formatSpec)", replaces = "doGeneric")

0 commit comments

Comments
 (0)