|
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