Skip to content

Commit a9776e3

Browse files
committed
Merge branch 'msimacek/GR-26767_migrate_truffle_exception' into update/GR-21590/151020
2 parents 275b20a + c042bbc commit a9776e3

File tree

27 files changed

+457
-241
lines changed

27 files changed

+457
-241
lines changed

graalpython/com.oracle.graal.python.test/src/com/oracle/graal/python/test/parser/ParserTestBase.java

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151
import com.oracle.graal.python.test.PythonTests;
5252
import com.oracle.truffle.api.TruffleFile;
5353
import com.oracle.truffle.api.frame.Frame;
54+
import com.oracle.truffle.api.interop.ExceptionType;
55+
import com.oracle.truffle.api.interop.InteropLibrary;
56+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
5457
import com.oracle.truffle.api.nodes.Node;
5558
import com.oracle.truffle.api.source.Source;
5659
import java.io.File;
@@ -127,7 +130,7 @@ public void checkSyntaxError(String source) throws Exception {
127130
try {
128131
parse(source, name.getMethodName(), PythonParser.ParserMode.File);
129132
} catch (PException e) {
130-
thrown = e.isSyntaxError();
133+
thrown = isSyntaxError(e);
131134
}
132135

133136
assertTrue("Expected SyntaxError was not thrown.", thrown);
@@ -138,7 +141,7 @@ public void checkSyntaxErrorMessageContains(String source, String expectedMessag
138141
try {
139142
parse(source, name.getMethodName(), PythonParser.ParserMode.File);
140143
} catch (PException e) {
141-
thrown = e.isSyntaxError();
144+
thrown = isSyntaxError(e);
142145
Assert.assertTrue("The expected message:\n\"" + expectedMessage + "\"\nwas not found in\n\"" + e.getMessage() + "\"", e.getMessage().contains(expectedMessage));
143146
}
144147

@@ -150,13 +153,17 @@ public void checkSyntaxErrorMessage(String source, String expectedMessage) throw
150153
try {
151154
parse(source, name.getMethodName(), PythonParser.ParserMode.File);
152155
} catch (PException e) {
153-
thrown = e.isSyntaxError();
156+
thrown = isSyntaxError(e);
154157
Assert.assertEquals(expectedMessage, e.getMessage());
155158
}
156159

157160
assertTrue("Expected SyntaxError was not thrown.", thrown);
158161
}
159162

163+
private static boolean isSyntaxError(PException e) throws UnsupportedMessageException {
164+
return InteropLibrary.getUncached().getExceptionType(e) == ExceptionType.PARSE_ERROR;
165+
}
166+
160167
public void saveNewTreeResult(File testFile, boolean goldenFileNextToTestFile) throws Exception {
161168
assertTrue("The test files " + testFile.getAbsolutePath() + " was not found.", testFile.exists());
162169
TruffleFile src = context.getEnv().getInternalTruffleFile(testFile.getAbsolutePath());

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,7 +638,7 @@ Object run(Object errorMarker,
638638
PException currentException = getContext().getCurrentException();
639639
if (currentException != null) {
640640
// getClassNode acts as a branch profile
641-
return getClassNode.execute(currentException.getExceptionObject());
641+
return getClassNode.execute(currentException.getUnreifiedException());
642642
}
643643
return errorMarker;
644644
}
@@ -1495,7 +1495,7 @@ int tbHere(PFrame frame,
14951495
}
14961496
PTraceback newTraceback = factory().createTraceback(frame, frame.getLine(), traceback);
14971497
boolean withJavaStacktrace = PythonOptions.isPExceptionWithJavaStacktrace(language);
1498-
context.setCurrentException(PException.fromExceptionInfo(currentException.getExceptionObject(), newTraceback, withJavaStacktrace));
1498+
context.setCurrentException(PException.fromExceptionInfo(currentException.getUnreifiedException(), newTraceback, withJavaStacktrace));
14991499
}
15001500

15011501
return 0;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SREModuleBuiltins.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@
7171
import com.oracle.truffle.api.CompilerAsserts;
7272
import com.oracle.truffle.api.CompilerDirectives;
7373
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
74-
import com.oracle.truffle.api.TruffleException;
7574
import com.oracle.truffle.api.dsl.Cached;
7675
import com.oracle.truffle.api.dsl.Cached.Shared;
7776
import com.oracle.truffle.api.dsl.CachedContext;
@@ -83,6 +82,7 @@
8382
import com.oracle.truffle.api.dsl.TypeSystemReference;
8483
import com.oracle.truffle.api.frame.VirtualFrame;
8584
import com.oracle.truffle.api.interop.ArityException;
85+
import com.oracle.truffle.api.interop.ExceptionType;
8686
import com.oracle.truffle.api.interop.InteropLibrary;
8787
import com.oracle.truffle.api.interop.UnsupportedMessageException;
8888
import com.oracle.truffle.api.interop.UnsupportedTypeException;
@@ -211,6 +211,7 @@ Object call(VirtualFrame frame, Object callable, Object arg1, Object arg2,
211211
@Cached BranchProfile syntaxError,
212212
@Cached BranchProfile typeError,
213213
@CachedLibrary("callable") InteropLibrary interop,
214+
@CachedLibrary(limit = "1") InteropLibrary exceptionLib,
214215
@CachedContext(PythonLanguage.class) PythonContext context) {
215216
Object state = IndirectCallContext.enter(frame, context, this);
216217
try {
@@ -219,20 +220,23 @@ Object call(VirtualFrame frame, Object callable, Object arg1, Object arg2,
219220
typeError.enter();
220221
throw raise(TypeError, "%s", e);
221222
} catch (RuntimeException e) {
222-
return handleError(e, syntaxError, potentialSyntaxError);
223+
return handleError(e, syntaxError, potentialSyntaxError, exceptionLib);
223224
} finally {
224225
IndirectCallContext.exit(frame, context, state);
225226
}
226227
}
227228

228-
@TruffleBoundary
229-
private Object handleError(RuntimeException e, BranchProfile syntaxError, BranchProfile potentialSyntaxError) {
230-
if (e instanceof TruffleException) {
231-
potentialSyntaxError.enter(); // this guards the TruffleBoundary invoke
232-
if (((TruffleException) e).isSyntaxError()) {
233-
syntaxError.enter();
234-
throw raise(ValueError, "%s", e);
229+
private Object handleError(RuntimeException e, BranchProfile syntaxError, BranchProfile potentialSyntaxError, InteropLibrary exceptionLib) {
230+
try {
231+
if (exceptionLib.isException(e)) {
232+
potentialSyntaxError.enter();
233+
if (exceptionLib.getExceptionType(e) == ExceptionType.PARSE_ERROR) {
234+
syntaxError.enter();
235+
throw raise(ValueError, "%s", e);
236+
}
235237
}
238+
} catch (UnsupportedMessageException e1) {
239+
throw CompilerDirectives.shouldNotReachHere();
236240
}
237241
// just re-throw
238242
throw e;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ public static Object fast(VirtualFrame frame, GetClassNode getClassNode, GetCaug
333333
if (currentException == null) {
334334
return factory.createTuple(new PNone[]{PNone.NONE});
335335
}
336-
return factory.createTuple(new Object[]{getClassNode.execute(currentException.getExceptionObject())});
336+
return factory.createTuple(new Object[]{getClassNode.execute(currentException.getUnreifiedException())});
337337
}
338338

339339
@Specialization

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PThreadState.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ Object doCurExcType(@SuppressWarnings("unused") String key,
154154
PException currentException = context.getCurrentException();
155155
Object result = null;
156156
if (currentException != null) {
157-
result = getClassNode.execute(currentException.getExceptionObject());
157+
result = getClassNode.execute(currentException.getUnreifiedException());
158158
}
159159
return toSulongNode.execute(result != null ? result : PNone.NO_VALUE);
160160
}
@@ -192,7 +192,7 @@ Object doExcType(@SuppressWarnings("unused") String key,
192192
PException currentException = context.getCaughtException();
193193
Object result = null;
194194
if (currentException != null) {
195-
result = getClassNode.execute(currentException.getExceptionObject());
195+
result = getClassNode.execute(currentException.getUnreifiedException());
196196
}
197197
return toSulongNode.execute(result != null ? result : PNone.NO_VALUE);
198198
}
@@ -349,7 +349,7 @@ static PTraceback doCurExcTraceback(@SuppressWarnings("unused") String key, PTra
349349
@Shared("language") @CachedLanguage PythonLanguage language,
350350
@Shared("context") @CachedContext(PythonLanguage.class) PythonContext context) {
351351
PException e = context.getCurrentException();
352-
context.setCurrentException(PException.fromExceptionInfo(e.getExceptionObject(), value, PythonOptions.isPExceptionWithJavaStacktrace(language)));
352+
context.setCurrentException(PException.fromExceptionInfo(e.getUnreifiedException(), value, PythonOptions.isPExceptionWithJavaStacktrace(language)));
353353
return value;
354354
}
355355

@@ -376,7 +376,7 @@ static PTraceback doExcTraceback(@SuppressWarnings("unused") String key, PTraceb
376376
@Shared("context") @CachedContext(PythonLanguage.class) PythonContext context) {
377377
PException e = context.getCaughtException();
378378
boolean withJavaStacktrace = PythonOptions.isPExceptionWithJavaStacktrace(language);
379-
context.setCaughtException(PException.fromExceptionInfo(e.getExceptionObject(), value, withJavaStacktrace));
379+
context.setCaughtException(PException.fromExceptionInfo(e.getUnreifiedException(), value, withJavaStacktrace));
380380
return value;
381381
}
382382

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/PBaseException.java

Lines changed: 101 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,38 @@
4040
*/
4141
package com.oracle.graal.python.builtins.objects.exception;
4242

43+
import com.oracle.graal.python.PythonLanguage;
44+
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4345
import com.oracle.graal.python.builtins.objects.PNone;
4446
import com.oracle.graal.python.builtins.objects.frame.PFrame;
4547
import com.oracle.graal.python.builtins.objects.object.PythonObject;
4648
import com.oracle.graal.python.builtins.objects.object.PythonObjectLibrary;
4749
import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback;
4850
import com.oracle.graal.python.builtins.objects.traceback.PTraceback;
4951
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
52+
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
5053
import com.oracle.graal.python.builtins.objects.type.TypeNodes.GetNameNode;
5154
import com.oracle.graal.python.nodes.PRaiseNode;
55+
import com.oracle.graal.python.nodes.attributes.ReadAttributeFromDynamicObjectNode;
5256
import com.oracle.graal.python.runtime.exception.PException;
5357
import com.oracle.graal.python.runtime.formatting.ErrorMessageFormatter;
5458
import com.oracle.graal.python.runtime.sequence.storage.BasicSequenceStorage;
5559
import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage;
56-
import com.oracle.graal.python.util.PythonUtils;
5760
import com.oracle.truffle.api.CompilerAsserts;
61+
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5862
import com.oracle.truffle.api.dsl.Cached;
63+
import com.oracle.truffle.api.dsl.Cached.Shared;
64+
import com.oracle.truffle.api.dsl.CachedLanguage;
65+
import com.oracle.truffle.api.interop.ExceptionType;
66+
import com.oracle.truffle.api.interop.InteropLibrary;
67+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
5968
import com.oracle.truffle.api.library.CachedLibrary;
69+
import com.oracle.truffle.api.library.ExportLibrary;
6070
import com.oracle.truffle.api.library.ExportMessage;
6171
import com.oracle.truffle.api.object.Shape;
72+
import com.oracle.truffle.api.profiles.BranchProfile;
6273

74+
@ExportLibrary(InteropLibrary.class)
6375
public final class PBaseException extends PythonObject {
6476
private static final ErrorMessageFormatter FORMATTER = new ErrorMessageFormatter();
6577

@@ -183,6 +195,7 @@ public Object[] getMessageArgs() {
183195
return messageArgs.clone();
184196
}
185197

198+
@TruffleBoundary
186199
public String getFormattedMessage(PythonObjectLibrary lib) {
187200
final Object clazz;
188201
if (lib == null) {
@@ -222,26 +235,6 @@ public LazyTraceback internalReifyException(PFrame.Reference curFrameInfo) {
222235
return traceback;
223236
}
224237

225-
@ExportMessage
226-
@SuppressWarnings("static-method")
227-
boolean isException() {
228-
return true;
229-
}
230-
231-
@ExportMessage
232-
RuntimeException throwException(@CachedLibrary("this") PythonObjectLibrary lib,
233-
@Cached PRaiseNode raiseNode) {
234-
Object[] newArgs = messageArgs;
235-
if (newArgs == null) {
236-
newArgs = PythonUtils.EMPTY_OBJECT_ARRAY;
237-
}
238-
Object format = messageFormat;
239-
if (format == null) {
240-
format = PNone.NO_VALUE;
241-
}
242-
throw raiseNode.execute(lib.getLazyPythonClass(this), this, format, newArgs);
243-
}
244-
245238
/**
246239
* Prepare a {@link PException} for reraising this exception, as done by <code>raise</code>
247240
* without arguments.
@@ -271,4 +264,91 @@ public PException getExceptionForReraise(LazyTraceback reraiseTraceback) {
271264
newException.setHideLocation(true);
272265
return newException;
273266
}
267+
268+
@ExportMessage
269+
@SuppressWarnings("static-method")
270+
boolean isException() {
271+
return true;
272+
}
273+
274+
@ExportMessage
275+
RuntimeException throwException(
276+
@Cached PRaiseNode raiseNode,
277+
@CachedLanguage PythonLanguage language) {
278+
throw raiseNode.raiseExceptionObject(this, language);
279+
}
280+
281+
@ExportMessage
282+
ExceptionType getExceptionType(
283+
@CachedLibrary("this") PythonObjectLibrary lib) {
284+
Object clazz = lib.getLazyPythonClass(this);
285+
if (clazz instanceof PythonBuiltinClass) {
286+
clazz = ((PythonBuiltinClass) clazz).getType();
287+
}
288+
// these are the only ones we'll raise, we don't want to report user subtypes of
289+
// SyntaxError as Truffle syntax errors
290+
if (clazz == PythonBuiltinClassType.SyntaxError || clazz == PythonBuiltinClassType.IndentationError || clazz == PythonBuiltinClassType.TabError) {
291+
return ExceptionType.PARSE_ERROR;
292+
}
293+
if (clazz == PythonBuiltinClassType.SystemExit) {
294+
return ExceptionType.EXIT;
295+
}
296+
return ExceptionType.RUNTIME_ERROR;
297+
}
298+
299+
@ExportMessage
300+
@SuppressWarnings("static-method")
301+
boolean isExceptionIncompleteSource() {
302+
return false;
303+
}
304+
305+
@ExportMessage
306+
@SuppressWarnings("static-method")
307+
boolean hasExceptionMessage() {
308+
return true;
309+
}
310+
311+
@ExportMessage
312+
String getExceptionMessage(@CachedLibrary("this") PythonObjectLibrary lib) {
313+
return getFormattedMessage(lib);
314+
}
315+
316+
@ExportMessage
317+
int getExceptionExitStatus(
318+
@CachedLibrary("this") PythonObjectLibrary lib,
319+
@Cached ReadAttributeFromDynamicObjectNode readNode,
320+
@Shared("unsupportedProfile") @Cached BranchProfile unsupportedProfile) throws UnsupportedMessageException {
321+
if (getExceptionType(lib) == ExceptionType.EXIT) {
322+
try {
323+
// Avoiding getattr because this message shouldn't have side-effects
324+
Object code = readNode.execute(this, "code");
325+
if (code == PNone.NO_VALUE) {
326+
return 1;
327+
}
328+
return (int) lib.asJavaLong(code);
329+
} catch (PException e) {
330+
return 1;
331+
}
332+
}
333+
unsupportedProfile.enter();
334+
throw UnsupportedMessageException.create();
335+
}
336+
337+
@ExportMessage
338+
boolean hasExceptionCause() {
339+
return cause != null || (!suppressContext && context != null);
340+
}
341+
342+
@ExportMessage
343+
Object getExceptionCause(
344+
@Shared("unsupportedProfile") @Cached BranchProfile unsupportedProfile) throws UnsupportedMessageException {
345+
if (cause != null) {
346+
return cause;
347+
}
348+
if (!suppressContext && context != null) {
349+
return context;
350+
}
351+
unsupportedProfile.enter();
352+
throw UnsupportedMessageException.create();
353+
}
274354
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PBuiltinFunction.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,17 @@ public boolean isCallable() {
175175
return true;
176176
}
177177

178+
@ExportMessage
179+
@SuppressWarnings("static-method")
180+
boolean hasExecutableName() {
181+
return true;
182+
}
183+
184+
@ExportMessage
185+
String getExecutableName() {
186+
return getName();
187+
}
188+
178189
@Override
179190
@ExportMessage
180191
@SuppressWarnings("static-method")

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PFunction.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,17 @@ public boolean isCallable() {
200200
return true;
201201
}
202202

203+
@ExportMessage
204+
@SuppressWarnings("static-method")
205+
boolean hasExecutableName() {
206+
return true;
207+
}
208+
209+
@ExportMessage
210+
String getExecutableName() {
211+
return getName();
212+
}
213+
203214
@ExportMessage
204215
public SourceSection getSourceLocation() throws UnsupportedMessageException {
205216
SourceSection result = getSourceLocationDirect();

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/generator/GeneratorBuiltins.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,7 @@ private Object doThrow(VirtualFrame frame, ResumeGeneratorNode resumeGeneratorNo
415415
instance.ensureReified();
416416
// Pass it to the generator where it will be thrown by the last yield, the location
417417
// will be filled there
418-
PException pException = PException.fromObject(instance, null, PythonOptions.isPExceptionWithJavaStacktrace(language));
419-
return resumeGeneratorNode.execute(frame, self, pException);
418+
return resumeGeneratorNode.execute(frame, self, new ThrowData(instance, PythonOptions.isPExceptionWithJavaStacktrace(language)));
420419
} else {
421420
// Unstarted generator, we cannot pass the exception into the generator as there is
422421
// nothing that would handle it.
@@ -477,9 +476,8 @@ Object close(VirtualFrame frame, PGenerator self,
477476
// Pass it to the generator where it will be thrown by the last yield, the location
478477
// will be filled there
479478
boolean withJavaStacktrace = PythonOptions.isPExceptionWithJavaStacktrace(language);
480-
PException pException = PException.fromObject(pythonException, null, withJavaStacktrace);
481479
try {
482-
resumeGeneratorNode.execute(frame, self, pException);
480+
resumeGeneratorNode.execute(frame, self, new ThrowData(pythonException, withJavaStacktrace));
483481
} catch (PException pe) {
484482
if (isGeneratorExit.profileException(pe, GeneratorExit, lib) || isStopIteration.profileException(pe, StopIteration, lib)) {
485483
// This is the "success" path

0 commit comments

Comments
 (0)