|
46 | 46 | import com.oracle.graal.python.builtins.Builtin;
|
47 | 47 | import com.oracle.graal.python.builtins.PythonBuiltinClassType;
|
48 | 48 | import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor;
|
| 49 | +import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.BinaryBuiltinDescriptor; |
| 50 | +import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.TernaryBuiltinDescriptor; |
| 51 | +import com.oracle.graal.python.builtins.objects.function.BuiltinMethodDescriptor.UnaryBuiltinDescriptor; |
49 | 52 | import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction;
|
50 | 53 | import com.oracle.graal.python.builtins.objects.method.PBuiltinMethod;
|
51 | 54 | import com.oracle.graal.python.builtins.objects.method.PMethod;
|
|
72 | 75 | import com.oracle.truffle.api.dsl.NodeField;
|
73 | 76 | import com.oracle.truffle.api.dsl.TypeSystemReference;
|
74 | 77 | import com.oracle.truffle.api.frame.VirtualFrame;
|
| 78 | +import com.oracle.truffle.api.nodes.Node; |
75 | 79 | import com.oracle.truffle.api.nodes.NodeUtil;
|
76 | 80 | import com.oracle.truffle.api.nodes.RootNode;
|
77 | 81 | import com.oracle.truffle.api.nodes.UnexpectedResultException;
|
@@ -112,9 +116,49 @@ private <T extends PythonBuiltinBaseNode> T getBuiltin(VirtualFrame frame, PBuil
|
112 | 116 | return null;
|
113 | 117 | }
|
114 | 118 |
|
| 119 | + public PythonUnaryBuiltinNode getBuiltin(UnaryBuiltinDescriptor descriptor) { |
| 120 | + PythonUnaryBuiltinNode builtin = descriptor.createNode(); |
| 121 | + if (!callerExceedsMaxSize(builtin)) { |
| 122 | + return builtin; |
| 123 | + } |
| 124 | + return null; |
| 125 | + } |
| 126 | + |
| 127 | + public PythonBinaryBuiltinNode getBuiltin(BinaryBuiltinDescriptor descriptor) { |
| 128 | + PythonBinaryBuiltinNode builtin = descriptor.createNode(); |
| 129 | + if (!callerExceedsMaxSize(builtin)) { |
| 130 | + return builtin; |
| 131 | + } |
| 132 | + return null; |
| 133 | + } |
| 134 | + |
| 135 | + public PythonTernaryBuiltinNode getBuiltin(TernaryBuiltinDescriptor descriptor) { |
| 136 | + PythonTernaryBuiltinNode builtin = descriptor.createNode(); |
| 137 | + if (!callerExceedsMaxSize(builtin)) { |
| 138 | + return builtin; |
| 139 | + } |
| 140 | + return null; |
| 141 | + } |
| 142 | + |
115 | 143 | private <T extends PythonBuiltinBaseNode> boolean callerExceedsMaxSize(T builtinNode) {
|
116 | 144 | CompilerAsserts.neverPartOfCompilation();
|
117 | 145 | if (isAdoptable() && !isMaxSizeExceeded()) {
|
| 146 | + // to avoid building up AST of recursive builtin calls we check that the same builtin |
| 147 | + // isn't already our parent. |
| 148 | + Class<? extends PythonBuiltinBaseNode> builtinClass = builtinNode.getClass(); |
| 149 | + Node parent = getParent(); |
| 150 | + int recursiveCalls = 0; |
| 151 | + while (parent != null && !(parent instanceof RootNode)) { |
| 152 | + if (parent.getClass() == builtinClass) { |
| 153 | + int recursionLimit = PythonLanguage.get(this).getEngineOption(PythonOptions.NodeRecursionLimit); |
| 154 | + if (recursiveCalls == recursionLimit) { |
| 155 | + return true; |
| 156 | + } |
| 157 | + recursiveCalls++; |
| 158 | + } |
| 159 | + parent = parent.getParent(); |
| 160 | + } |
| 161 | + |
118 | 162 | RootNode root = getRootNode();
|
119 | 163 | int n = root instanceof PRootNode ? ((PRootNode) root).getNodeCount() : NodeUtil.countNodes(root);
|
120 | 164 | // nb: option 'BuiltinsInliningMaxCallerSize' is defined as a compatible option, i.e.,
|
|
0 commit comments