|
27 | 27 |
|
28 | 28 | import static com.oracle.graal.python.runtime.PythonOptions.CatchAllExceptions;
|
29 | 29 |
|
30 |
| -import java.util.ArrayList; |
31 |
| - |
32 | 30 | import com.oracle.graal.python.builtins.objects.PNone;
|
33 | 31 | import com.oracle.graal.python.builtins.objects.exception.PBaseException;
|
34 |
| -import com.oracle.graal.python.builtins.objects.function.PArguments; |
35 |
| -import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; |
36 |
| -import com.oracle.graal.python.builtins.objects.module.PythonModule; |
37 |
| -import com.oracle.graal.python.builtins.objects.tuple.PTuple; |
38 |
| -import com.oracle.graal.python.nodes.BuiltinNames; |
39 | 32 | import com.oracle.graal.python.nodes.PNode;
|
40 |
| -import com.oracle.graal.python.nodes.attributes.GetAttributeNode; |
41 |
| -import com.oracle.graal.python.nodes.frame.ReadGlobalOrBuiltinNode; |
42 |
| -import com.oracle.graal.python.nodes.literal.TupleLiteralNode; |
43 |
| -import com.oracle.graal.python.nodes.statement.TryExceptNode.ExceptBlockMR.CatchesFunction; |
44 |
| -import com.oracle.graal.python.nodes.statement.TryExceptNode.ExceptBlockMR.CatchesFunction.ExceptListMR.ExecuteNode; |
45 | 33 | import com.oracle.graal.python.runtime.PythonOptions;
|
46 | 34 | import com.oracle.graal.python.runtime.exception.ExceptionHandledException;
|
47 | 35 | import com.oracle.graal.python.runtime.exception.PException;
|
48 | 36 | import com.oracle.graal.python.runtime.exception.PythonErrorType;
|
49 | 37 | import com.oracle.truffle.api.CompilerDirectives;
|
50 | 38 | import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
|
51 | 39 | import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
|
52 |
| -import com.oracle.truffle.api.RootCallTarget; |
53 | 40 | import com.oracle.truffle.api.frame.VirtualFrame;
|
54 |
| -import com.oracle.truffle.api.instrumentation.StandardTags; |
55 |
| -import com.oracle.truffle.api.interop.ArityException; |
56 |
| -import com.oracle.truffle.api.interop.CanResolve; |
57 | 41 | import com.oracle.truffle.api.interop.ForeignAccess;
|
58 |
| -import com.oracle.truffle.api.interop.KeyInfo; |
59 |
| -import com.oracle.truffle.api.interop.MessageResolution; |
60 |
| -import com.oracle.truffle.api.interop.Resolve; |
61 | 42 | import com.oracle.truffle.api.interop.TruffleObject;
|
62 |
| -import com.oracle.truffle.api.interop.UnknownIdentifierException; |
63 | 43 | import com.oracle.truffle.api.nodes.ControlFlowException;
|
64 | 44 | import com.oracle.truffle.api.nodes.ExplodeLoop;
|
65 |
| -import com.oracle.truffle.api.nodes.Node; |
66 | 45 |
|
67 | 46 | public class TryExceptNode extends StatementNode implements TruffleObject {
|
68 |
| - |
69 | 47 | @Child private PNode body;
|
70 | 48 | @Children private final ExceptNode[] exceptNodes;
|
71 | 49 | @Child private PNode orelse;
|
72 |
| - |
73 |
| - @CompilationFinal CatchesFunction catchesFunction; |
| 50 | + @CompilationFinal private TryExceptNodeMessageResolution.CatchesFunction catchesFunction; |
74 | 51 |
|
75 | 52 | @CompilationFinal boolean seenException;
|
76 | 53 |
|
@@ -154,156 +131,15 @@ public PNode getOrelse() {
|
154 | 131 |
|
155 | 132 | @Override
|
156 | 133 | public ForeignAccess getForeignAccess() {
|
157 |
| - return ExceptBlockMRForeign.ACCESS; |
| 134 | + return TryExceptNodeMessageResolutionForeign.ACCESS; |
158 | 135 | }
|
159 | 136 |
|
160 |
| - @MessageResolution(receiverType = TryExceptNode.class) |
161 |
| - static class ExceptBlockMR { |
162 |
| - @Resolve(message = "HAS_KEYS") |
163 |
| - abstract static class HasKeysNode extends Node { |
164 |
| - Object access(@SuppressWarnings("unused") TryExceptNode object) { |
165 |
| - return true; |
166 |
| - } |
167 |
| - } |
168 |
| - |
169 |
| - @Resolve(message = "KEYS") |
170 |
| - abstract static class KeysNode extends Node { |
171 |
| - Object access(TryExceptNode object) { |
172 |
| - return object.getContext().getEnv().asGuestValue(new String[]{StandardTags.TryBlockTag.CATCHES}); |
173 |
| - } |
174 |
| - } |
175 |
| - |
176 |
| - @Resolve(message = "KEY_INFO") |
177 |
| - abstract static class KeyInfoNode extends Node { |
178 |
| - Object access(@SuppressWarnings("unused") TryExceptNode object, String name) { |
179 |
| - if (name.equals(StandardTags.TryBlockTag.CATCHES)) { |
180 |
| - return KeyInfo.INVOCABLE | KeyInfo.READABLE; |
181 |
| - } else { |
182 |
| - return KeyInfo.NONE; |
183 |
| - } |
184 |
| - } |
185 |
| - } |
186 |
| - |
187 |
| - @Resolve(message = "READ") |
188 |
| - abstract static class ReadNode extends Node { |
189 |
| - @Child GetAttributeNode getAttr = GetAttributeNode.create(); |
190 |
| - |
191 |
| - CatchesFunction access(TryExceptNode object, String name) { |
192 |
| - return doit(object, name, getAttr); |
193 |
| - } |
194 |
| - |
195 |
| - static CatchesFunction doit(TryExceptNode object, String name, GetAttributeNode getAttr) { |
196 |
| - if (name.equals(StandardTags.TryBlockTag.CATCHES)) { |
197 |
| - if (object.catchesFunction == null) { |
198 |
| - CompilerDirectives.transferToInterpreterAndInvalidate(); |
199 |
| - ArrayList<Object> literalCatches = new ArrayList<>(); |
200 |
| - ExceptNode[] exceptNodes = object.getExceptNodes(); |
201 |
| - PythonModule builtins = object.getContext().getBuiltins(); |
202 |
| - |
203 |
| - for (ExceptNode node : exceptNodes) { |
204 |
| - PNode exceptType = node.getExceptType(); |
205 |
| - if (exceptType instanceof ReadGlobalOrBuiltinNode) { |
206 |
| - try { |
207 |
| - literalCatches.add(getAttr.execute(builtins, ((ReadGlobalOrBuiltinNode) exceptType).getAttributeId())); |
208 |
| - } catch (PException e) { |
209 |
| - } |
210 |
| - } else if (exceptType instanceof TupleLiteralNode) { |
211 |
| - for (PNode tupleValue : ((TupleLiteralNode) exceptType).getValues()) { |
212 |
| - if (tupleValue instanceof ReadGlobalOrBuiltinNode) { |
213 |
| - try { |
214 |
| - literalCatches.add(getAttr.execute(builtins, ((ReadGlobalOrBuiltinNode) tupleValue).getAttributeId())); |
215 |
| - } catch (PException e) { |
216 |
| - } |
217 |
| - } |
218 |
| - } |
219 |
| - } |
220 |
| - } |
221 |
| - |
222 |
| - Object isinstanceFunc = getAttr.execute(builtins, BuiltinNames.ISINSTANCE); |
223 |
| - PTuple caughtClasses = object.factory().createTuple(literalCatches.toArray()); |
224 |
| - |
225 |
| - if (isinstanceFunc instanceof PBuiltinFunction) { |
226 |
| - RootCallTarget callTarget = ((PBuiltinFunction) isinstanceFunc).getCallTarget(); |
227 |
| - object.catchesFunction = new CatchesFunction(callTarget, caughtClasses); |
228 |
| - } else { |
229 |
| - throw new IllegalStateException("isinstance was redefined, cannot check exceptions"); |
230 |
| - } |
231 |
| - } |
232 |
| - return object.catchesFunction; |
233 |
| - } else { |
234 |
| - throw UnknownIdentifierException.raise(name); |
235 |
| - } |
236 |
| - } |
237 |
| - } |
238 |
| - |
239 |
| - @Resolve(message = "INVOKE") |
240 |
| - abstract static class InvokeNode extends Node { |
241 |
| - @Child GetAttributeNode getAttr = GetAttributeNode.create(); |
242 |
| - |
243 |
| - Object access(TryExceptNode object, String name, Object[] arguments) { |
244 |
| - CatchesFunction catchesFunction = ReadNode.doit(object, name, getAttr); |
245 |
| - return ExecuteNode.access(catchesFunction, arguments); |
246 |
| - } |
247 |
| - } |
248 |
| - |
249 |
| - @CanResolve |
250 |
| - abstract static class CheckFunction extends Node { |
251 |
| - protected static boolean test(TruffleObject receiver) { |
252 |
| - return receiver instanceof TryExceptNode; |
253 |
| - } |
254 |
| - } |
255 |
| - |
256 |
| - protected static class CatchesFunction implements TruffleObject { |
257 |
| - private final RootCallTarget isInstance; |
258 |
| - private final Object[] args = PArguments.create(2); |
259 |
| - |
260 |
| - CatchesFunction(RootCallTarget callTarget, PTuple caughtClasses) { |
261 |
| - this.isInstance = callTarget; |
262 |
| - PArguments.setArgument(args, 1, caughtClasses); |
263 |
| - } |
264 |
| - |
265 |
| - @ExplodeLoop |
266 |
| - boolean catches(Object exception) { |
267 |
| - if (exception instanceof PBaseException) { |
268 |
| - PArguments.setArgument(args, 0, exception); |
269 |
| - try { |
270 |
| - return isInstance.call(args) == Boolean.TRUE; |
271 |
| - } catch (PException e) { |
272 |
| - } |
273 |
| - } |
274 |
| - return false; |
275 |
| - } |
276 |
| - |
277 |
| - public ForeignAccess getForeignAccess() { |
278 |
| - return ExceptListMRForeign.ACCESS; |
279 |
| - } |
280 |
| - |
281 |
| - @MessageResolution(receiverType = CatchesFunction.class) |
282 |
| - static class ExceptListMR { |
283 |
| - @Resolve(message = "IS_EXECUTABLE") |
284 |
| - abstract static class IsExecutableNode extends Node { |
285 |
| - Object access(@SuppressWarnings("unused") CatchesFunction object) { |
286 |
| - return true; |
287 |
| - } |
288 |
| - } |
289 |
| - |
290 |
| - @Resolve(message = "EXECUTE") |
291 |
| - abstract static class ExecuteNode extends Node { |
292 |
| - static Object access(CatchesFunction object, Object[] arguments) { |
293 |
| - if (arguments.length != 1) { |
294 |
| - throw ArityException.raise(1, arguments.length); |
295 |
| - } |
296 |
| - return object.catches(arguments[0]); |
297 |
| - } |
298 |
| - } |
| 137 | + public TryExceptNodeMessageResolution.CatchesFunction getCatchesFunction() { |
| 138 | + return this.catchesFunction; |
| 139 | + } |
299 | 140 |
|
300 |
| - @CanResolve |
301 |
| - abstract static class CheckFunction extends Node { |
302 |
| - protected static boolean test(TruffleObject receiver) { |
303 |
| - return receiver instanceof TryExceptNode; |
304 |
| - } |
305 |
| - } |
306 |
| - } |
307 |
| - } |
| 141 | + public void setCatchesFunction(TryExceptNodeMessageResolution.CatchesFunction catchesFunction) { |
| 142 | + CompilerDirectives.transferToInterpreterAndInvalidate(); |
| 143 | + this.catchesFunction = catchesFunction; |
308 | 144 | }
|
309 | 145 | }
|
0 commit comments