|
57 | 57 | import com.oracle.truffle.api.instrumentation.InstrumentableNode;
|
58 | 58 | import com.oracle.truffle.api.instrumentation.ProbeNode;
|
59 | 59 | import com.oracle.truffle.api.interop.InteropLibrary;
|
| 60 | +import com.oracle.truffle.api.interop.UnsupportedMessageException; |
60 | 61 | import com.oracle.truffle.api.library.CachedLibrary;
|
61 | 62 | import com.oracle.truffle.api.nodes.Node;
|
62 | 63 |
|
@@ -104,15 +105,8 @@ public boolean matchesPException(VirtualFrame frame, PException e) {
|
104 | 105 |
|
105 | 106 | public boolean matchesTruffleException(@SuppressWarnings("unused") VirtualFrame frame, AbstractTruffleException e) {
|
106 | 107 | assert !(e instanceof PException);
|
107 |
| - // TODO: (tfel) should we allow catching with the meta-object of arbitrary truffle |
108 |
| - // exceptions? |
109 |
| - return exceptType == null; |
110 |
| - } |
111 |
| - |
112 |
| - public boolean matchesHostException(VirtualFrame frame, Throwable e) { |
113 |
| - assert !(e instanceof AbstractTruffleException); |
114 | 108 | if (exceptType == null) {
|
115 |
| - return false; // host exceptions must be matched explicitly |
| 109 | + return true; |
116 | 110 | }
|
117 | 111 | return getMatchNode().executeMatch(frame, e, exceptType.execute(frame));
|
118 | 112 | }
|
@@ -147,16 +141,14 @@ public boolean isInstrumentable() {
|
147 | 141 | }
|
148 | 142 | }
|
149 | 143 |
|
150 |
| -interface EmulateJythonNode { |
151 |
| - default boolean emulateJython(PythonLanguage language) { |
152 |
| - return language.getEngineOption(PythonOptions.EmulateJython); |
153 |
| - } |
154 |
| -} |
155 |
| - |
156 | 144 | @ImportStatic(PythonOptions.class)
|
157 |
| -abstract class ValidExceptionNode extends Node implements EmulateJythonNode { |
| 145 | +abstract class ValidExceptionNode extends Node { |
158 | 146 | protected abstract boolean execute(VirtualFrame frame, Object type);
|
159 | 147 |
|
| 148 | + protected static boolean emulateJython(PythonLanguage language) { |
| 149 | + return language.getEngineOption(PythonOptions.EmulateJython); |
| 150 | + } |
| 151 | + |
160 | 152 | protected static boolean isPythonExceptionType(PythonBuiltinClassType type) {
|
161 | 153 | PythonBuiltinClassType base = type;
|
162 | 154 | while (base != null) {
|
@@ -209,7 +201,7 @@ static ValidExceptionNode create() {
|
209 | 201 | }
|
210 | 202 |
|
211 | 203 | @ImportStatic({PGuards.class, PythonOptions.class})
|
212 |
| -abstract class ExceptMatchNode extends Node implements EmulateJythonNode { |
| 204 | +abstract class ExceptMatchNode extends Node { |
213 | 205 | @Child private PRaiseNode raiseNode;
|
214 | 206 |
|
215 | 207 | protected abstract boolean executeMatch(VirtualFrame frame, Object exception, Object clause);
|
@@ -238,38 +230,20 @@ boolean matchPythonSingle(VirtualFrame frame, PException e, Object clause,
|
238 | 230 | return isSubtype.execute(frame, plib.getLazyPythonClass(e.getUnreifiedException()), clause);
|
239 | 231 | }
|
240 | 232 |
|
241 |
| - @Specialization(guards = {"emulateJython(language)", "context.getEnv().isHostException(e)", "context.getEnv().isHostObject(clause)"}) |
242 |
| - @SuppressWarnings("unused") |
243 |
| - boolean matchJava(VirtualFrame frame, Throwable e, Object clause, |
244 |
| - @Cached ValidExceptionNode isValidException, |
245 |
| - @CachedLanguage PythonLanguage language, |
246 |
| - @CachedContext(PythonLanguage.class) PythonContext context) { |
247 |
| - raiseIfNoException(frame, clause, isValidException); |
248 |
| - // cast must succeed due to ValidExceptionNode above |
249 |
| - Class<?> javaClause = (Class<?>) context.getEnv().asHostObject(clause); |
250 |
| - Throwable hostException = context.getEnv().asHostException(e); |
251 |
| - return javaClause.isInstance(hostException); |
252 |
| - } |
253 |
| - |
254 |
| - @Specialization(guards = {"emulateJython(language)", "context.getEnv().isHostObject(clause)"}) |
| 233 | + @Specialization(guards = {"eLib.isException(e)", "clauseLib.isMetaObject(clause)"}, limit = "3", replaces = "matchPythonSingle") |
255 | 234 | @SuppressWarnings("unused")
|
256 |
| - boolean doNotMatchPython(VirtualFrame frame, @SuppressWarnings("unused") PException e, Object clause, |
257 |
| - @CachedLanguage PythonLanguage language, |
258 |
| - @CachedContext(PythonLanguage.class) PythonContext context, |
259 |
| - @Cached ValidExceptionNode isValidException) { |
260 |
| - raiseIfNoException(frame, clause, isValidException); |
261 |
| - return false; |
262 |
| - } |
263 |
| - |
264 |
| - @Specialization(guards = {"lib.isLazyPythonClass(clause)", "emulateJython(language)", "context.getEnv().isHostException(e)"}) |
265 |
| - @SuppressWarnings("unused") |
266 |
| - boolean doNotMatchJava(VirtualFrame frame, @SuppressWarnings("unused") Throwable e, Object clause, |
267 |
| - @CachedLanguage PythonLanguage language, |
268 |
| - @CachedContext(PythonLanguage.class) PythonContext context, |
| 235 | + boolean matchJava(VirtualFrame frame, AbstractTruffleException e, Object clause, |
269 | 236 | @Cached ValidExceptionNode isValidException,
|
270 |
| - @CachedLibrary(limit = "2") PythonObjectLibrary lib) { |
| 237 | + @CachedLibrary("e") InteropLibrary eLib, |
| 238 | + @CachedLibrary("clause") InteropLibrary clauseLib) { |
| 239 | + // n.b.: we can only allow Java exceptions in clauses, because we cannot tell for other |
| 240 | + // foreign exception types if they *are* exception types |
271 | 241 | raiseIfNoException(frame, clause, isValidException);
|
272 |
| - return false; |
| 242 | + try { |
| 243 | + return clauseLib.isMetaInstance(clause, e); |
| 244 | + } catch (UnsupportedMessageException e1) { |
| 245 | + throw CompilerDirectives.shouldNotReachHere(); |
| 246 | + } |
273 | 247 | }
|
274 | 248 |
|
275 | 249 | @Specialization
|
|
0 commit comments