@@ -1044,7 +1044,6 @@ Object doObject(Object value,
1044
1044
*/
1045
1045
public abstract static class RecursiveBinaryCheckBaseNode extends PythonBinaryBuiltinNode {
1046
1046
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 ;
1048
1047
1049
1048
@ Child private SequenceStorageNodes .LenNode lenNode ;
1050
1049
@ Child private GetObjectArrayNode getObjectArrayNode ;
@@ -1056,10 +1055,14 @@ protected RecursiveBinaryCheckBaseNode(byte depth) {
1056
1055
1057
1056
public abstract boolean executeWith (VirtualFrame frame , Object instance , Object cls );
1058
1057
1059
- public final RecursiveBinaryCheckBaseNode createRecursive () {
1058
+ protected final RecursiveBinaryCheckBaseNode createRecursive () {
1060
1059
return createRecursive ((byte ) (depth + 1 ));
1061
1060
}
1062
1061
1062
+ protected final RecursiveBinaryCheckBaseNode createNonRecursive () {
1063
+ return createRecursive ((byte ) (PythonOptions .getNodeRecursionLimit () + 1 ));
1064
+ }
1065
+
1063
1066
protected RecursiveBinaryCheckBaseNode createRecursive (@ SuppressWarnings ("unused" ) byte newDepth ) {
1064
1067
throw new AbstractMethodError (); // Cannot be really abstract b/c Truffle DSL...
1065
1068
}
@@ -1096,19 +1099,23 @@ final boolean doRecursiveWithNode(VirtualFrame frame, Object instance, PTuple cl
1096
1099
}
1097
1100
1098
1101
@ 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 ) {
1100
1104
Object state = IndirectCallContext .enter (frame , getContext (), this );
1101
1105
try {
1102
1106
// 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 );
1104
1111
} finally {
1105
1112
IndirectCallContext .exit (frame , getContext (), state );
1106
1113
}
1107
1114
}
1108
1115
1109
1116
@ 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 );
1112
1119
}
1113
1120
1114
1121
protected final int getLength (PTuple t ) {
0 commit comments