Skip to content

Commit 2806671

Browse files
committed
Fix 'Invoke node was initialized for a null frame' caused by RecursiveBinaryCheckBaseNode
1 parent 7375cfa commit 2806671

File tree

1 file changed

+13
-6
lines changed

1 file changed

+13
-6
lines changed

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,7 +1044,6 @@ Object doObject(Object value,
10441044
*/
10451045
public abstract static class RecursiveBinaryCheckBaseNode extends PythonBinaryBuiltinNode {
10461046
static final int MAX_EXPLODE_LOOP = 16; // is also shifted to the left by recursion depth
1047-
static final byte STOP_RECURSION = Byte.MAX_VALUE;
10481047

10491048
@Child private SequenceStorageNodes.LenNode lenNode;
10501049
@Child private GetObjectArrayNode getObjectArrayNode;
@@ -1056,10 +1055,14 @@ protected RecursiveBinaryCheckBaseNode(byte depth) {
10561055

10571056
public abstract boolean executeWith(VirtualFrame frame, Object instance, Object cls);
10581057

1059-
public final RecursiveBinaryCheckBaseNode createRecursive() {
1058+
protected final RecursiveBinaryCheckBaseNode createRecursive() {
10601059
return createRecursive((byte) (depth + 1));
10611060
}
10621061

1062+
protected final RecursiveBinaryCheckBaseNode createNonRecursive() {
1063+
return createRecursive((byte) (PythonOptions.getNodeRecursionLimit() + 1));
1064+
}
1065+
10631066
protected RecursiveBinaryCheckBaseNode createRecursive(@SuppressWarnings("unused") byte newDepth) {
10641067
throw new AbstractMethodError(); // Cannot be really abstract b/c Truffle DSL...
10651068
}
@@ -1096,19 +1099,23 @@ final boolean doRecursiveWithNode(VirtualFrame frame, Object instance, PTuple cl
10961099
}
10971100

10981101
@Specialization(guards = "depth >= getNodeRecursionLimit()")
1099-
final boolean doRecursiveWithLoop(VirtualFrame frame, Object instance, PTuple clsTuple) {
1102+
final boolean doRecursiveWithLoop(VirtualFrame frame, Object instance, PTuple clsTuple,
1103+
@Cached("createNonRecursive()") RecursiveBinaryCheckBaseNode node) {
11001104
Object state = IndirectCallContext.enter(frame, getContext(), this);
11011105
try {
11021106
// Note: we need actual recursion to trigger the stack overflow error like CPython
1103-
return callRecursiveWithNodeTruffleBoundary(instance, clsTuple);
1107+
// Note: we need fresh RecursiveBinaryCheckBaseNode and cannot use "this", because
1108+
// children of this executed by other specializations may assume they'll always get
1109+
// non-null frame
1110+
return callRecursiveWithNodeTruffleBoundary(instance, clsTuple, node);
11041111
} finally {
11051112
IndirectCallContext.exit(frame, getContext(), state);
11061113
}
11071114
}
11081115

11091116
@TruffleBoundary
1110-
private boolean callRecursiveWithNodeTruffleBoundary(Object instance, PTuple clsTuple) {
1111-
return doRecursiveWithNode(null, instance, clsTuple, this);
1117+
private boolean callRecursiveWithNodeTruffleBoundary(Object instance, PTuple clsTuple, RecursiveBinaryCheckBaseNode node) {
1118+
return doRecursiveWithNode(null, instance, clsTuple, node);
11121119
}
11131120

11141121
protected final int getLength(PTuple t) {

0 commit comments

Comments
 (0)