diff --git a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py index 4851b4857c..9708fdabb0 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/test_interop.py @@ -427,6 +427,42 @@ def test_java_exceptions(): else: assert False + def test_java_exceptions_reraise(): + if __graalpython__.jython_emulation_enabled: + from java.lang import Integer, NumberFormatException + try: + try: + Integer.parseInt("99", 8) + except NumberFormatException: + raise + except NumberFormatException: + pass + else: + assert False + + def test_java_exceptions_reraise_explicit(): + if __graalpython__.jython_emulation_enabled: + from java.lang import Integer, NumberFormatException + try: + try: + Integer.parseInt("99", 8) + except NumberFormatException as e: + raise e + except NumberFormatException: + pass + else: + assert False + + def test_java_exception_state(): + if __graalpython__.jython_emulation_enabled: + from java.lang import Integer, NumberFormatException + try: + Integer.parseInt("99", 8) + except NumberFormatException as e: + assert sys.exc_info() == (type(e), e, None) + else: + assert False + @skipIf(is_native, "not supported in native mode") def test_foreign_object_does_not_leak_Javas_toString(): try: diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java index 76b66ea9be..aeccc72d52 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SysModuleBuiltins.java @@ -170,6 +170,7 @@ import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.frame.PFrame.Reference; @@ -248,6 +249,7 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; @@ -840,17 +842,18 @@ public abstract static class ExcInfoNode extends PythonBuiltinNode { static PTuple run(VirtualFrame frame, @Bind("this") Node inliningTarget, @Cached GetClassNode getClassNode, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached GetCaughtExceptionNode getCaughtExceptionNode, @Cached ExceptionNodes.GetTracebackNode getTracebackNode, @Cached PythonObjectFactory factory) { - PException currentException = getCaughtExceptionNode.execute(frame); + AbstractTruffleException currentException = getCaughtExceptionNode.execute(frame); assert currentException != PException.NO_EXCEPTION; if (currentException == null) { return factory.createTuple(new PNone[]{PNone.NONE, PNone.NONE, PNone.NONE}); } else { - Object exception = currentException.getEscapedException(); - Object traceback = getTracebackNode.execute(inliningTarget, exception); - return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, exception), exception, traceback}); + Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, currentException); + Object traceback = getTracebackNode.execute(inliningTarget, exceptionObject); + return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, exceptionObject), exceptionObject, traceback}); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java index d31e1052ad..419ff0b44b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextErrBuiltins.java @@ -96,6 +96,7 @@ import com.oracle.graal.python.builtins.objects.dict.DictBuiltins.SetItemNode; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.exception.PrepareExceptionNode; import com.oracle.graal.python.builtins.objects.function.PKeyword; @@ -133,6 +134,7 @@ import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -173,6 +175,7 @@ static Object run(Object typ, Object val, Object tb, @Cached PrepareExceptionNode prepareExceptionNode, @Cached ExceptionNodes.SetTracebackNode setTracebackNode, @Cached ExceptionNodes.SetContextNode setContextNode, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode) { if (typ != PNone.NO_VALUE) { PythonContext.PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, PythonContext.get(inliningTarget)); @@ -182,8 +185,9 @@ static Object run(Object typ, Object val, Object tb, if (tb != PNone.NO_VALUE) { setTracebackNode.execute(inliningTarget, exception, tb); } - Object currentException = threadState.getCurrentException().getEscapedException(); - setContextNode.execute(inliningTarget, currentException, exception); + AbstractTruffleException currentException = threadState.getCurrentException(); + Object currentExceptionObject = getEscapedExceptionNode.execute(inliningTarget, currentException); + setContextNode.execute(inliningTarget, currentExceptionObject, exception); } else { PException e = PException.fromExceptionInfo(exception, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(inliningTarget))); transformExceptionToNativeNode.execute(inliningTarget, e, tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null); @@ -399,14 +403,15 @@ Object info( @Cached GetClassNode getClassNode, @Cached ExceptionNodes.GetTracebackNode getTracebackNode, @Cached InlinedBranchProfile noExceptionProfile, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached PythonObjectFactory factory) { - PException currentException = getCaughtExceptionNode.executeFromNative(); + AbstractTruffleException currentException = getCaughtExceptionNode.executeFromNative(); if (currentException == null) { noExceptionProfile.enter(inliningTarget); return getNativeNull(); } assert currentException != PException.NO_EXCEPTION; - Object exception = currentException.getEscapedException(); + Object exception = getEscapedExceptionNode.execute(inliningTarget, currentException); Object traceback = noneToNativeNull(inliningTarget, getTracebackNode.execute(inliningTarget, exception)); return factory.createTuple(new Object[]{getClassNode.execute(inliningTarget, exception), exception, traceback}); } @@ -419,6 +424,7 @@ static Object write(Object msg, Object obj, @Bind("this") Node inliningTarget, @Cached GetThreadStateNode getThreadStateNode, @Cached WriteUnraisableNode writeUnraisableNode, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { PythonContext.PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, PythonContext.get(inliningTarget)); if (threadState.getCurrentException() == null) { @@ -426,12 +432,13 @@ static Object write(Object msg, Object obj, return PNone.NONE; } threadState.syncTracebackToException(); - Object exc = threadState.getCurrentException().getEscapedException(); + AbstractTruffleException exception = threadState.getCurrentException(); + Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, exception); TruffleString m = null; if (msg instanceof TruffleString) { m = (TruffleString) msg; } - writeUnraisableNode.execute(exc, m, (obj == PNone.NO_VALUE) ? PNone.NONE : obj); + writeUnraisableNode.execute(exceptionObject, m, (obj == PNone.NO_VALUE) ? PNone.NONE : obj); clearCurrentExceptionNode.execute(inliningTarget, threadState); return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java index 177ab16afb..54ca6de591 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/cext/PythonCextTracebackBuiltins.java @@ -57,11 +57,11 @@ import com.oracle.graal.python.builtins.objects.traceback.MaterializeLazyTracebackNode; import com.oracle.graal.python.builtins.objects.traceback.PTraceback; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -89,7 +89,7 @@ static int tbHere(PFrame frame, @Cached PythonObjectFactory factory) { PythonLanguage language = PythonLanguage.get(inliningTarget); PythonContext.PythonThreadState threadState = PythonContext.get(inliningTarget).getThreadState(language); - PException currentException = threadState.getCurrentException(); + AbstractTruffleException currentException = threadState.getCurrentException(); if (currentException != null) { PTraceback currentTraceback = null; if (threadState.getCurrentTraceback() != null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java index 44d855dd32..97d3d8ad3b 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java @@ -166,6 +166,7 @@ import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @@ -840,7 +841,7 @@ static void deallocWarn(VirtualFrame frame, PFileIO self, if (self.getFD() >= 0 && self.isCloseFD()) { try { warn.resourceWarning(frame, self, 1, UNCLOSED_FILE, self); - } catch (PException e) { + } catch (AbstractTruffleException e) { /* Spurious errors can appear at shutdown */ /* (mq) we aren't doing WriteUnraisable as WarnNode will take care of it */ } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index c2bd197e17..8696867d77 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -121,6 +121,8 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CStructs; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.complex.PComplex; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; +import com.oracle.graal.python.builtins.objects.exception.GetUnreifiedExceptionNode; import com.oracle.graal.python.builtins.objects.floats.PFloat; import com.oracle.graal.python.builtins.objects.function.PBuiltinFunction; import com.oracle.graal.python.builtins.objects.function.PKeyword; @@ -195,6 +197,7 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; @@ -1034,11 +1037,12 @@ public static Object executeUncached(PythonThreadState threadState) { @Specialization static Object doGeneric(Node inliningTarget, PythonThreadState threadState, - @Cached GetClassNode getClassNode) { - PException currentException = threadState.getCurrentException(); + @Cached GetClassNode getClassNode, + @Cached GetUnreifiedExceptionNode getUnreifiedExceptionNode) { + AbstractTruffleException currentException = threadState.getCurrentException(); if (currentException != null) { // getClassNode acts as a branch profile - return getClassNode.execute(inliningTarget, currentException.getUnreifiedException()); + return getClassNode.execute(inliningTarget, getUnreifiedExceptionNode.execute(inliningTarget, currentException)); } return null; } @@ -1062,8 +1066,9 @@ public static ExceptionState executeUncached(PythonThreadState threadState) { static ExceptionState doGeneric(Node inliningTarget, PythonThreadState threadState, @Cached GetClassNode getClassNode, @Cached MaterializeLazyTracebackNode materializeTraceback, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { - PException currentException = threadState.getCurrentException(); + AbstractTruffleException currentException = threadState.getCurrentException(); if (currentException == null) { /* * This should be caught in native by checking 'PyErr_Occurred' and avoiding the @@ -1071,7 +1076,7 @@ static ExceptionState doGeneric(Node inliningTarget, PythonThreadState threadSta */ return null; } - Object exception = currentException.getEscapedException(); + Object exception = getEscapedExceptionNode.execute(inliningTarget, currentException); Object traceback = null; if (threadState.getCurrentTraceback() != null) { traceback = materializeTraceback.execute(inliningTarget, threadState.getCurrentTraceback()); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java index 7e50438ee7..29769da5a9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ExternalFunctionNodes.java @@ -124,7 +124,6 @@ import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.GetThreadStateNode; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeObjectSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; @@ -151,6 +150,7 @@ import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.dsl.TypeSystemReference; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.ArityException; import com.oracle.truffle.api.interop.InteropLibrary; @@ -2436,7 +2436,7 @@ static Object doGeneric(PythonThreadState state, @SuppressWarnings("unused") Tru @Cached ClearCurrentExceptionNode clearCurrentExceptionNode, @Cached PRaiseNode raiseNode) { if (lib.isNull(result)) { - PException currentException = state.getCurrentException(); + AbstractTruffleException currentException = state.getCurrentException(); // if no exception occurred, the iterator is exhausted -> raise StopIteration if (currentException == null) { throw raiseNode.raiseStopIteration(); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java index d3814a686e..65983bc242 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PThreadState.java @@ -49,6 +49,7 @@ import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccessFactory; import com.oracle.graal.python.builtins.objects.cext.structs.CStructs; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.exception.GetUnreifiedExceptionNode; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; @@ -116,7 +117,7 @@ private static Object allocateCLayout(PythonThreadState threadState) { writePtrNode.write(ptr, CFields.PyThreadState__small_ints, cApiContext.getOrCreateSmallInts()); if (threadState.getCurrentException() != null) { // See TransformExceptionToNativeNode - Object exceptionType = GetClassNode.executeUncached(threadState.getCurrentException().getUnreifiedException()); + Object exceptionType = GetClassNode.executeUncached(GetUnreifiedExceptionNode.executeUncached(threadState.getCurrentException())); CStructAccess.WritePointerNode.getUncached().write(ptr, CFields.PyThreadState__curexc_type, PythonToNativeNode.getUncached().execute(exceptionType)); } return ptr; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java index 03d92431fc..14c747fc7a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/transitions/CApiTransitions.java @@ -95,7 +95,6 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PythonObjectFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; @@ -116,6 +115,7 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; @@ -401,7 +401,7 @@ public static void pollReferenceQueue() { * There can be an active exception. Since we might be calling arbitary python, we * need to stash it. */ - PException savedException = null; + AbstractTruffleException savedException = null; LazyTraceback savedTraceback = null; Object savedNativeException = null; if (threadState.getCurrentException() != null) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java index 73cba7798a..47c07193e6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtCommonNodes.java @@ -71,6 +71,7 @@ import com.oracle.graal.python.builtins.objects.cext.common.CExtCommonNodesFactory.ReadUnicodeArrayNodeGen; import com.oracle.graal.python.builtins.objects.cext.structs.CFields; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.traceback.LazyTraceback; @@ -114,6 +115,7 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.InteropLibrary; @@ -556,7 +558,7 @@ static void doGeneric(Node inliningTarget, PythonThreadState threadState, Truffl @Cached InlinedConditionProfile errOccurredProfile, @Cached InlinedConditionProfile indicatesErrorProfile, @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { - PException currentException = threadState.getCurrentException(); + AbstractTruffleException currentException = threadState.getCurrentException(); boolean errOccurred = errOccurredProfile.profile(inliningTarget, currentException != null); boolean indicatesErrorProfiled = indicatesErrorProfile.profile(inliningTarget, indicatesError); if (indicatesErrorProfiled || errOccurred) { @@ -568,7 +570,7 @@ static void doGeneric(Node inliningTarget, PythonThreadState threadState, Truffl @InliningCutoff private static void checkFunctionResultSlowpath(Node inliningTarget, PythonThreadState threadState, TruffleString name, boolean indicatesError, boolean strict, - TruffleString nullButNoErrorMessage, TruffleString resultWithErrorMessage, boolean errOccurred, PException currentException, + TruffleString nullButNoErrorMessage, TruffleString resultWithErrorMessage, boolean errOccurred, AbstractTruffleException currentException, ClearCurrentExceptionNode clearCurrentExceptionNode) { if (indicatesError) { if (errOccurred) { @@ -592,9 +594,9 @@ private static PException raiseNullButNoError(Node node, TruffleString name, Tru } @TruffleBoundary - private static PException raiseResultWithError(Node node, TruffleString name, PException currentException, TruffleString resultWithErrorMessage) { + private static PException raiseResultWithError(Node node, TruffleString name, AbstractTruffleException currentException, TruffleString resultWithErrorMessage) { PBaseException sysExc = PythonObjectFactory.getUncached().createBaseException(SystemError, resultWithErrorMessage, new Object[]{name}); - sysExc.setCause(currentException.getEscapedException()); + sysExc.setCause(GetEscapedExceptionNode.executeUncached(currentException)); throw PRaiseNode.raiseExceptionObject(node, sysExc, PythonOptions.isPExceptionWithJavaStacktrace(PythonLanguage.get(null))); } } @@ -1271,8 +1273,8 @@ public abstract static class ClearCurrentExceptionNode extends Node { public abstract void execute(Node inliningTarget, PythonThreadState threadState); - public final PException getCurrentExceptionForReraise(Node inliningTarget, PythonThreadState threadState) { - PException exceptionForReraise = threadState.getCurrentExceptionForReraise(); + public final AbstractTruffleException getCurrentExceptionForReraise(Node inliningTarget, PythonThreadState threadState) { + AbstractTruffleException exceptionForReraise = threadState.getCurrentExceptionForReraise(); execute(inliningTarget, threadState); return exceptionForReraise; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java index 7e4fa70612..038394f06e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java @@ -288,6 +288,8 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.NoGeneralizationNode; import com.oracle.graal.python.builtins.objects.contextvars.PContextVar; import com.oracle.graal.python.builtins.objects.dict.PDict; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; +import com.oracle.graal.python.builtins.objects.exception.GetUnreifiedExceptionNode; import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.ints.PInt; @@ -378,6 +380,7 @@ import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; @@ -1700,15 +1703,17 @@ public abstract static class GraalHPyErrExceptionMatches extends HPyBinaryContex static Object doGeneric(GraalHPyContext hpyContext, Object exc, @Bind("this") Node inliningTarget, @Cached GetThreadStateNode getThreadStateNode, + @Cached GetUnreifiedExceptionNode getUnreifiedExceptionNode, @Cached RecursiveExceptionMatches exceptionMatches) { - PException err = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()).getCurrentException(); + AbstractTruffleException err = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()).getCurrentException(); if (err == null) { return 0; } if (exc == NULL_HANDLE_DELEGATE) { return 0; } - return exceptionMatches.execute(hpyContext, err.getUnreifiedException(), exc); + Object exceptionObject = getUnreifiedExceptionNode.execute(inliningTarget, err); + return exceptionMatches.execute(hpyContext, exceptionObject, exc); } } @@ -1752,11 +1757,13 @@ static Object doGeneric(GraalHPyContext hpyContext, Object object, @Bind("this") Node inliningTarget, @Cached GetThreadStateNode getThreadStateNode, @Cached WriteUnraisableNode writeUnraisableNode, + @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Cached ClearCurrentExceptionNode clearCurrentExceptionNode) { PythonThreadState threadState = getThreadStateNode.execute(inliningTarget, hpyContext.getContext()); - PException exception = threadState.getCurrentException(); + AbstractTruffleException exception = threadState.getCurrentException(); clearCurrentExceptionNode.execute(inliningTarget, threadState); - writeUnraisableNode.execute(null, exception.getEscapedException(), null, (object instanceof PNone) ? PNone.NONE : object); + Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, exception); + writeUnraisableNode.execute(null, exceptionObject, null, (object instanceof PNone) ? PNone.NONE : object); return 0; // void } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetEscapedExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetEscapedExceptionNode.java new file mode 100644 index 0000000000..6a76536546 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetEscapedExceptionNode.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.exception; + +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; +import com.oracle.truffle.api.nodes.Node; + +/** + * Use this node to get a python exception object from an exception. + */ +@GenerateUncached +@GenerateInline +@GenerateCached(false) +public abstract class GetEscapedExceptionNode extends Node { + + public abstract Object execute(Node inliningTarget, AbstractTruffleException e); + + public static Object executeUncached(AbstractTruffleException e) { + return GetEscapedExceptionNodeGen.getUncached().execute(null, e); + } + + @Specialization + static Object doPException(PException e) { + return e.getEscapedException(); + } + + @Fallback + static Object doForeign(AbstractTruffleException e) { + return e; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetUnreifiedExceptionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetUnreifiedExceptionNode.java new file mode 100644 index 0000000000..783a13f934 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/GetUnreifiedExceptionNode.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * The Universal Permissive License (UPL), Version 1.0 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.exception; + +import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateCached; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; +import com.oracle.truffle.api.nodes.Node; + +/** + * Use this node to get a python exception object from an exception. + */ +@GenerateUncached +@GenerateInline +@GenerateCached(false) +public abstract class GetUnreifiedExceptionNode extends Node { + + public abstract Object execute(Node inliningTarget, AbstractTruffleException e); + + public static Object executeUncached(AbstractTruffleException e) { + return GetUnreifiedExceptionNodeGen.getUncached().execute(null, e); + } + + @Specialization + static Object doPException(PException e) { + return e.getUnreifiedException(); + } + + @Fallback + static Object doForeign(AbstractTruffleException e) { + return e; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java index 0f4e1c3a9d..25baa2d572 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/function/PArguments.java @@ -28,9 +28,9 @@ import com.oracle.graal.python.builtins.objects.cell.PCell; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.object.PythonObject; -import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerAsserts; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.frame.VirtualFrame; @@ -205,23 +205,23 @@ public static void setCurrentFrameInfo(Object[] arguments, PFrame.Reference info arguments[INDEX_CURRENT_FRAME_INFO] = info; } - public static PException getException(Object[] arguments) { - return (PException) getExceptionUnchecked(arguments); + public static AbstractTruffleException getException(Object[] arguments) { + return (AbstractTruffleException) getExceptionUnchecked(arguments); } - public static PException getException(Frame frame) { - return (PException) getExceptionUnchecked(frame.getArguments()); + public static AbstractTruffleException getException(Frame frame) { + return (AbstractTruffleException) getExceptionUnchecked(frame.getArguments()); } public static Object getExceptionUnchecked(Object[] arguments) { return arguments[INDEX_CURRENT_EXCEPTION]; } - public static void setException(Frame frame, PException exc) { + public static void setException(Frame frame, AbstractTruffleException exc) { setException(frame.getArguments(), exc); } - public static void setException(Object[] arguments, PException exc) { + public static void setException(Object[] arguments, AbstractTruffleException exc) { setExceptionUnchecked(arguments, exc); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitAWithNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitAWithNode.java index ee64cbe570..6b1964778f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitAWithNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitAWithNode.java @@ -44,7 +44,6 @@ import com.oracle.graal.python.builtins.objects.function.PArguments; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; @@ -65,14 +64,13 @@ public abstract class ExitAWithNode extends PNodeWithContext { @Specialization int exit(VirtualFrame virtualFrame, int stackTopIn, boolean rootNodeVisible, @Bind("this") Node inliningTarget, - @Cached PyObjectIsTrueNode isTrueNode, - @Cached PRaiseNode raiseNode) { + @Cached PyObjectIsTrueNode isTrueNode) { int stackTop = stackTopIn; Object result = virtualFrame.getObject(stackTop); virtualFrame.setObject(stackTop--, null); Object exception = virtualFrame.getObject(stackTop); virtualFrame.setObject(stackTop--, null); - PException savedExcState = PArguments.getException(virtualFrame); + AbstractTruffleException savedExcState = PArguments.getException(virtualFrame); try { if (!isTrueNode.execute(virtualFrame, inliningTarget, result) && exception != PNone.NONE) { if (exception instanceof PException) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java index 10d92f3bdf..f47bce0519 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ExitWithNode.java @@ -85,12 +85,14 @@ int exit(VirtualFrame virtualFrame, int stackTopIn, boolean rootNodeVisible, if (exception == PNone.NONE) { callExit.execute(virtualFrame, exit, contextManager, PNone.NONE, PNone.NONE, PNone.NONE); } else { - PException savedExcState = PArguments.getException(virtualFrame); + AbstractTruffleException savedExcState = PArguments.getException(virtualFrame); try { Object pythonException = exception; if (exception instanceof PException) { PArguments.setException(virtualFrame, (PException) exception); pythonException = ((PException) exception).getEscapedException(); + } else if (exception instanceof AbstractTruffleException) { + PArguments.setException(virtualFrame, (AbstractTruffleException) exception); } Object excType = getClassNode.execute(inliningTarget, pythonException); Object excTraceback = getTracebackNode.execute(inliningTarget, pythonException); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java index bcb58a96ce..8d5ed625b3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/PBytecodeRootNode.java @@ -77,6 +77,7 @@ import com.oracle.graal.python.builtins.objects.ellipsis.PEllipsis; import com.oracle.graal.python.builtins.objects.exception.ChainExceptionsNode; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltins; import com.oracle.graal.python.builtins.objects.floats.FloatBuiltinsFactory; import com.oracle.graal.python.builtins.objects.frame.PFrame; @@ -197,7 +198,6 @@ import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.ExceptionUtils; import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.exception.PythonExitException; import com.oracle.graal.python.runtime.exception.PythonThreadKillException; import com.oracle.graal.python.runtime.object.PythonObjectFactory; @@ -1211,8 +1211,8 @@ private static final class InstrumentationData { * from the outer frame because that changes with every resume. */ boolean fetchedException; - PException outerException; - PException localException; + AbstractTruffleException outerException; + AbstractTruffleException localException; } Object executeFromBci(VirtualFrame virtualFrame, Frame localFrame, BytecodeOSRNode osrNode, int initialBci, int initialStackTop) { @@ -2313,36 +2313,35 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod if (e instanceof ThreadDeath) { throw e; } - PException pe = null; - boolean isInteropException = false; - if (e instanceof PException) { - pe = (PException) e; - } else if (e instanceof AbstractTruffleException) { - isInteropException = true; + AbstractTruffleException exception; + if (e instanceof AbstractTruffleException) { + exception = (AbstractTruffleException) e; } else { - pe = wrapJavaExceptionIfApplicable(e); - if (pe == null) { + exception = wrapJavaExceptionIfApplicable(e); + if (exception == null) { throw e; } } tracingOrProfilingEnabled = checkTracingAndProfilingEnabled(noTraceOrProfile, mutableData); - if (isTracingEnabled(tracingOrProfilingEnabled) && pe != null && !mutableData.getThreadState(this).isTracing()) { - traceException(virtualFrame, mutableData, beginBci, pe); + if (isTracingEnabled(tracingOrProfilingEnabled) && exception != null && !mutableData.getThreadState(this).isTracing()) { + traceException(virtualFrame, mutableData, beginBci, exception); } int targetIndex = findHandler(beginBci); CompilerAsserts.partialEvaluationConstant(targetIndex); - chainPythonExceptions(virtualFrame, mutableData, pe); + chainPythonExceptions(virtualFrame, mutableData, exception); if (targetIndex == -1) { - reraiseUnhandledException(virtualFrame, localFrame, initialStackTop, isGeneratorOrCoroutine, mutableData, bciSlot, beginBci, pe, tracingOrProfilingEnabled); - if (pe != null) { - throw pe; + prepareForReraise(virtualFrame, localFrame, initialStackTop, isGeneratorOrCoroutine, mutableData, bciSlot, beginBci, tracingOrProfilingEnabled); + if (exception instanceof PException) { + ((PException) exception).notifyAddedTracebackFrame(frameIsVisibleToPython()); + throw exception; + } else { + throw e; } - throw e; } - if (pe != null) { - pe.setCatchingFrameReference(virtualFrame, this, beginBci); + if (exception instanceof PException) { + ((PException) exception).setCatchingFrameReference(virtualFrame, this, beginBci); } int stackSizeOnEntry = exceptionHandlerRanges[targetIndex + 1]; int targetStackTop = stackSizeOnEntry + stackoffset; @@ -2351,7 +2350,7 @@ private Object bytecodeLoop(VirtualFrame virtualFrame, Frame localFrame, Bytecod * Handler range encodes the stack size, not the top of stack. so the stackTop * is to be replaced with the exception */ - virtualFrame.setObject(stackTop, isInteropException ? e : pe); + virtualFrame.setObject(stackTop, exception); bci = exceptionHandlerRanges[targetIndex]; oparg = 0; if (instrumentation != null) { @@ -2532,11 +2531,7 @@ private boolean bytecodeMatchExc(VirtualFrame virtualFrame, boolean useCachedNod Object matchType = virtualFrame.getObject(stackTop); virtualFrame.setObject(stackTop, null); ExceptMatchNode matchNode = insertChildNode(localNodes, beginBci, UNCACHED_EXCEPT_MATCH, ExceptMatchNodeGen.class, NODE_EXCEPT_MATCH, useCachedNodes); - boolean match = !(exception instanceof PException) && matchType == null; - if (!match) { - match = matchNode.executeMatch(virtualFrame, exception, matchType); - } - return match; + return matchNode.executeMatch(virtualFrame, exception, matchType); } @BytecodeInterpreterSwitch @@ -2589,12 +2584,9 @@ private boolean bytecodeSend(VirtualFrame virtualFrame, int stackTop, Node[] loc @BytecodeInterpreterSwitch private boolean bytecodeThrow(VirtualFrame virtualFrame, int stackTop, Node[] localNodes, int beginBci) { Object exception = virtualFrame.getObject(stackTop); - if (!(exception instanceof PException)) { - throw CompilerDirectives.shouldNotReachHere("interop exceptions not supported in throw"); - } Object obj = virtualFrame.getObject(stackTop - 1); ThrowNode throwNode = insertChildNode(localNodes, beginBci, ThrowNodeGen.class, NODE_THROW); - return throwNode.execute(virtualFrame, stackTop, obj, (PException) exception); + return throwNode.execute(virtualFrame, stackTop, obj, (AbstractTruffleException) exception); } @BytecodeInterpreterSwitch @@ -2624,18 +2616,14 @@ private void bytecodeResumeYield(VirtualFrame virtualFrame, boolean useCachedNod @BytecodeInterpreterSwitch private void bytecodePushExcInfo(VirtualFrame virtualFrame, Object[] arguments, MutableLoopData mutableData, int stackTop) { Object exception = virtualFrame.getObject(stackTop); - Object origException = exception; - if (!(exception instanceof PException)) { - exception = ExceptionUtils.wrapJavaException((Throwable) exception, this, factory.createBaseException(PythonErrorType.SystemError, ErrorMessages.M, new Object[]{exception})); - } if (!mutableData.fetchedException) { mutableData.outerException = PArguments.getException(arguments); mutableData.fetchedException = true; } virtualFrame.setObject(stackTop++, mutableData.localException); - mutableData.localException = (PException) exception; + mutableData.localException = (AbstractTruffleException) exception; PArguments.setException(arguments, mutableData.localException); - virtualFrame.setObject(stackTop, origException); + virtualFrame.setObject(stackTop, exception); } @BytecodeInterpreterSwitch @@ -2870,15 +2858,17 @@ private void traceOrProfileReturnCutoff(VirtualFrame virtualFrame, MutableLoopDa } @InliningCutoff - private void traceException(VirtualFrame virtualFrame, MutableLoopData mutableData, int bci, PException pe) { + private void traceException(VirtualFrame virtualFrame, MutableLoopData mutableData, int bci, AbstractTruffleException exception) { mutableData.setPyFrame(ensurePyFrame(virtualFrame)); if (mutableData.getPyFrame().getLocalTraceFun() != null) { - pe.setCatchingFrameReference(virtualFrame, this, bci); - Object peForPython = pe.getEscapedException(); - Object peType = GetClassNode.executeUncached(peForPython); - Object traceback = ExceptionNodes.GetTracebackNode.executeUncached(peForPython); + if (exception instanceof PException) { + ((PException) exception).setCatchingFrameReference(virtualFrame, this, bci); + } + Object exceptionObject = GetEscapedExceptionNode.executeUncached(exception); + Object peType = GetClassNode.executeUncached(exceptionObject); + Object traceback = ExceptionNodes.GetTracebackNode.executeUncached(exception); invokeTraceFunction(virtualFrame, - factory.createTuple(new Object[]{peType, peForPython, traceback}), mutableData.getThreadState(this), + factory.createTuple(new Object[]{peType, exceptionObject, traceback}), mutableData.getThreadState(this), mutableData, PythonContext.TraceEvent.EXCEPTION, bciToLine(bci), true); } @@ -3233,13 +3223,10 @@ private void unboxVariables(Frame localFrame) { } @InliningCutoff - private void reraiseUnhandledException(VirtualFrame virtualFrame, Frame localFrame, int initialStackTop, boolean isGeneratorOrCoroutine, MutableLoopData mutableData, int bciSlot, - int beginBci, PException pe, byte tracingOrProfilingEnabled) { + private void prepareForReraise(VirtualFrame virtualFrame, Frame localFrame, int initialStackTop, boolean isGeneratorOrCoroutine, MutableLoopData mutableData, int bciSlot, + int beginBci, byte tracingOrProfilingEnabled) { // For tracebacks setCurrentBci(virtualFrame, bciSlot, beginBci); - if (pe != null) { - pe.notifyAddedTracebackFrame(frameIsVisibleToPython()); - } if (isGeneratorOrCoroutine) { if (localFrame != virtualFrame) { // Unwind the generator frame stack @@ -3253,18 +3240,18 @@ private void reraiseUnhandledException(VirtualFrame virtualFrame, Frame localFra } @InliningCutoff - private void chainPythonExceptions(VirtualFrame virtualFrame, MutableLoopData mutableData, PException pe) { - if (pe != null) { - if (mutableData.localException != null) { - chainPythonExceptions(pe, mutableData.localException); + private void chainPythonExceptions(VirtualFrame virtualFrame, MutableLoopData mutableData, AbstractTruffleException exception) { + if (exception instanceof PException pe) { + if (mutableData.localException instanceof PException pe2) { + chainPythonExceptions(pe, pe2); } else { if (getCaughtExceptionNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); getCaughtExceptionNode = insert(ExceptionStateNodes.GetCaughtExceptionNode.create()); } - PException exceptionState = getCaughtExceptionNode.execute(virtualFrame); - if (exceptionState != null) { - chainPythonExceptions(pe, exceptionState); + AbstractTruffleException exceptionState = getCaughtExceptionNode.execute(virtualFrame); + if (exceptionState instanceof PException pe2) { + chainPythonExceptions(pe, pe2); } } } @@ -4755,18 +4742,20 @@ private int bytecodeClosureFromStack(VirtualFrame virtualFrame, int stackTop, in return stackTop; } - private PException popExceptionState(Object[] arguments, Object savedException, PException outerException) { - PException localException = null; - if (savedException instanceof PException) { - localException = (PException) savedException; + private AbstractTruffleException popExceptionState(Object[] arguments, Object savedException, AbstractTruffleException outerException) { + AbstractTruffleException localException = null; + if (savedException instanceof AbstractTruffleException) { + localException = (AbstractTruffleException) savedException; PArguments.setException(arguments, localException); } else if (savedException == null) { PArguments.setException(arguments, outerException); + } else { + throw CompilerDirectives.shouldNotReachHere("expected exception on the stack"); } return localException; } - private PException bytecodeEndExcHandler(VirtualFrame virtualFrame, int stackTop) { + private AbstractTruffleException bytecodeEndExcHandler(VirtualFrame virtualFrame, int stackTop) { Object exception = virtualFrame.getObject(stackTop); if (exception instanceof PException) { throw ((PException) exception).getExceptionForReraise(frameIsVisibleToPython()); @@ -5106,9 +5095,9 @@ private int bytecodeCallFunctionKw(VirtualFrame virtualFrame, int initialStackTo try { result = callNode.execute(virtualFrame, callable, args, (PKeyword[]) virtualFrame.getObject(stackTop)); profileCEvent(virtualFrame, callable, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, callable, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop - 2, result); @@ -5130,9 +5119,9 @@ private int bytecodeCallFunctionVarargs(VirtualFrame virtualFrame, int initialSt try { result = callNode.execute(virtualFrame, callable, args, PKeyword.EMPTY_KEYWORDS); profileCEvent(virtualFrame, callable, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, callable, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop - 1, result); @@ -5153,9 +5142,9 @@ private int bytecodeCallMethodVarargs(VirtualFrame virtualFrame, int initialStac try { result = callNode.execute(virtualFrame, func, args, PKeyword.EMPTY_KEYWORDS); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop - 1, result); @@ -5184,9 +5173,9 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc try { result = callNode.execute(virtualFrame, func, PythonUtils.EMPTY_OBJECT_ARRAY, PKeyword.EMPTY_KEYWORDS); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); @@ -5199,9 +5188,9 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc try { result = callNode.executeObject(virtualFrame, func, virtualFrame.getObject(stackTop)); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop--, null); @@ -5219,9 +5208,9 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc try { result = callNode.executeObject(virtualFrame, func, arg0, arg1); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); @@ -5240,9 +5229,9 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc try { result = callNode.execute(virtualFrame, func, arg0, arg1, arg2); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); @@ -5263,9 +5252,9 @@ private int bytecodeCallFunction(VirtualFrame virtualFrame, int stackTop, int bc try { result = callNode.execute(virtualFrame, func, arg0, arg1, arg2, arg3); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); @@ -5287,9 +5276,9 @@ private int bytecodeCallComprehension(VirtualFrame virtualFrame, int stackTop, i PArguments.setArgument(arguments, 0, virtualFrame.getObject(stackTop)); result = callNode.execute(virtualFrame, func, func.getGlobals(), func.getClosure(), arguments); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop--, null); @@ -5323,9 +5312,9 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, try { result = callNode.executeObject(virtualFrame, func, rcvr); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop--, null); @@ -5339,9 +5328,9 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, try { result = callNode.executeObject(virtualFrame, func, rcvr, virtualFrame.getObject(stackTop)); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop--, null); @@ -5361,9 +5350,9 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, try { result = callNode.execute(virtualFrame, func, rcvr, arg0, arg1); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); @@ -5385,9 +5374,9 @@ private int bytecodeCallMethod(VirtualFrame virtualFrame, int stackTop, int bci, try { result = callNode.execute(virtualFrame, func, rcvr, arg0, arg1, arg2); profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_RETURN, mutableData, tracingOrProfilingEnabled); - } catch (PException pe) { + } catch (AbstractTruffleException e) { profileCEvent(virtualFrame, func, PythonContext.ProfileEvent.C_EXCEPTION, mutableData, tracingOrProfilingEnabled); - throw pe; + throw e; } virtualFrame.setObject(stackTop, result); break; @@ -5407,7 +5396,7 @@ private int bytecodeStoreName(VirtualFrame virtualFrame, int initialStackTop, in } @InliningCutoff - private PException bytecodeRaiseVarargs(VirtualFrame virtualFrame, int stackTop, int bci, int count, Node[] localNodes) { + private AbstractTruffleException bytecodeRaiseVarargs(VirtualFrame virtualFrame, int stackTop, int bci, int count, Node[] localNodes) { RaiseNode raiseNode = insertChildNode(localNodes, bci, RaiseNodeGen.class, NODE_RAISENODE); Object cause; Object exception; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java index c46e9fc593..4202c74e1e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/RaiseNode.java @@ -52,6 +52,7 @@ import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.ImportStatic; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnsupportedMessageException; @@ -127,16 +128,19 @@ static void setCause(@SuppressWarnings("unused") VirtualFrame frame, @SuppressWa // raise @Specialization(guards = "isNoValue(type)") - public static void reraise(VirtualFrame frame, @SuppressWarnings("unused") PNone type, @SuppressWarnings("unused") Object cause, boolean rootNodeVisible, + static void reraise(VirtualFrame frame, @SuppressWarnings("unused") PNone type, @SuppressWarnings("unused") Object cause, boolean rootNodeVisible, @Bind("this") Node inliningTarget, - @Exclusive @Cached PRaiseNode.Lazy raise, - @Exclusive @Cached GetCaughtExceptionNode getCaughtExceptionNode, - @Exclusive @Cached InlinedConditionProfile hasCurrentException) { - PException caughtException = getCaughtExceptionNode.execute(frame); - if (hasCurrentException.profile(inliningTarget, caughtException == null)) { - throw raise.get(inliningTarget).raise(RuntimeError, ErrorMessages.NO_ACTIVE_EX_TO_RERAISE); + @Cached PRaiseNode raise, + @Cached GetCaughtExceptionNode getCaughtExceptionNode, + @Cached InlinedConditionProfile hasPException) { + AbstractTruffleException caughtException = getCaughtExceptionNode.execute(frame); + if (hasPException.profile(inliningTarget, caughtException instanceof PException)) { + throw ((PException) caughtException).getExceptionForReraise(rootNodeVisible); + } else if (caughtException != null) { + throw caughtException; + } else { + throw raise.raise(RuntimeError, ErrorMessages.NO_ACTIVE_EX_TO_RERAISE); } - throw caughtException.getExceptionForReraise(rootNodeVisible); } // raise diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ThrowNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ThrowNode.java index b5e1341d94..9b89f0a291 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ThrowNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/bytecode/ThrowNode.java @@ -44,6 +44,8 @@ import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.exception.StopIterationBuiltins; import com.oracle.graal.python.builtins.objects.generator.CommonGeneratorBuiltins; @@ -53,6 +55,7 @@ import com.oracle.graal.python.nodes.WriteUnraisableNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; +import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -60,6 +63,7 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; @@ -71,22 +75,24 @@ public abstract class ThrowNode extends PNodeWithContext { private static final TruffleString T_THROW = tsLiteral("throw"); // Returns true when the generator finished - public abstract boolean execute(VirtualFrame frame, int stackTop, Object iter, PException exception); + public abstract boolean execute(VirtualFrame frame, int stackTop, Object iter, AbstractTruffleException exception); @Specialization - boolean doGenerator(VirtualFrame frame, int stackTop, PGenerator generator, PException exception, + static boolean doGenerator(VirtualFrame frame, int stackTop, PGenerator generator, AbstractTruffleException exception, @Bind("this") Node inliningTarget, @Cached CommonGeneratorBuiltins.ThrowNode throwNode, @Cached CommonGeneratorBuiltins.CloseNode closeNode, + @Exclusive @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Exclusive @Cached IsBuiltinObjectProfile profileExit, @Exclusive @Cached IsBuiltinObjectProfile stopIterationProfile, @Exclusive @Cached StopIterationBuiltins.StopIterationValueNode getValue) { - if (profileExit.profileException(inliningTarget, exception, GeneratorExit)) { + Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, exception); + if (profileExit.profileObject(inliningTarget, exceptionObject, GeneratorExit)) { closeNode.execute(frame, generator); throw exception; } else { try { - Object value = throwNode.execute(frame, generator, exception.getEscapedException(), PNone.NO_VALUE, PNone.NO_VALUE); + Object value = throwNode.execute(frame, generator, exceptionObject, PNone.NO_VALUE, PNone.NO_VALUE); frame.setObject(stackTop, value); return false; } catch (PException e) { @@ -97,17 +103,21 @@ boolean doGenerator(VirtualFrame frame, int stackTop, PGenerator generator, PExc } @Fallback - static boolean doOther(VirtualFrame frame, int stackTop, Object obj, PException exception, + static boolean doOther(VirtualFrame frame, int stackTop, Object obj, AbstractTruffleException exception, @Bind("this") Node inliningTarget, @Cached PyObjectLookupAttr lookupThrow, @Cached PyObjectLookupAttr lookupClose, @Cached CallNode callThrow, @Cached CallNode callClose, @Cached WriteUnraisableNode writeUnraisableNode, + @Cached GetClassNode getClassNode, + @Cached ExceptionNodes.GetTracebackNode getTracebackNode, + @Exclusive @Cached GetEscapedExceptionNode getEscapedExceptionNode, @Exclusive @Cached IsBuiltinObjectProfile profileExit, @Exclusive @Cached IsBuiltinObjectProfile stopIterationProfile, @Exclusive @Cached StopIterationBuiltins.StopIterationValueNode getValue) { - if (profileExit.profileException(inliningTarget, exception, GeneratorExit)) { + Object exceptionObject = getEscapedExceptionNode.execute(inliningTarget, exception); + if (profileExit.profileObject(inliningTarget, exceptionObject, GeneratorExit)) { Object close = PNone.NO_VALUE; try { close = lookupClose.execute(frame, inliningTarget, obj, T_CLOSE); @@ -124,7 +134,9 @@ static boolean doOther(VirtualFrame frame, int stackTop, Object obj, PException throw exception; } try { - Object value = callThrow.execute(frame, throwMethod, exception.getEscapedException()); + Object type = getClassNode.execute(inliningTarget, exceptionObject); + Object tb = getTracebackNode.execute(inliningTarget, exceptionObject); + Object value = callThrow.execute(frame, throwMethod, type, exceptionObject, tb); frame.setObject(stackTop, value); return false; } catch (PException e) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/ExceptionStateNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/ExceptionStateNodes.java index 9f2c4c3404..670903a643 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/ExceptionStateNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/util/ExceptionStateNodes.java @@ -52,10 +52,9 @@ import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; -import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.FrameInstance.FrameAccess; -import com.oracle.truffle.api.frame.FrameInstanceVisitor; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.RootNode; @@ -75,11 +74,11 @@ public static final class GetCaughtExceptionNode extends Node { private final ConditionProfile hasExceptionProfile = ConditionProfile.create(); private final ConditionProfile needsStackWalkProfile = ConditionProfile.create(); - public PException execute(VirtualFrame frame) { + public AbstractTruffleException execute(VirtualFrame frame) { if (nullFrameProfile.profile(frame == null)) { return getFromContext(); } - PException e = PArguments.getException(frame); + AbstractTruffleException e = PArguments.getException(frame); if (needsStackWalkProfile.profile(e == null)) { e = fromStackWalk(); if (e == null) { @@ -91,18 +90,18 @@ public PException execute(VirtualFrame frame) { return ensure(e); } - public PException executeFromNative() { + public AbstractTruffleException executeFromNative() { return getFromContext(); } - private PException getFromContext() { + private AbstractTruffleException getFromContext() { // contextRef acts as a branch profile if (getThreadStateNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); getThreadStateNode = insert(GetThreadStateNodeGen.create()); } PythonThreadState threadState = getThreadStateNode.executeCached(); - PException fromContext = threadState.getCaughtException(); + AbstractTruffleException fromContext = threadState.getCaughtException(); if (needsStackWalkProfile.profile(fromContext == null)) { fromContext = fromStackWalk(); @@ -112,7 +111,7 @@ private PException getFromContext() { return ensure(fromContext); } - private static PException fromStackWalk() { + private static AbstractTruffleException fromStackWalk() { // The very-slow path: This is the first time we want to fetch the exception state // from the context. The caller didn't know that it is necessary to provide the // exception in the context. So, we do a full stack walk until the first frame @@ -125,27 +124,24 @@ private static PException fromStackWalk() { } @TruffleBoundary - public static PException fullStackWalk() { + public static AbstractTruffleException fullStackWalk() { - return Truffle.getRuntime().iterateFrames(new FrameInstanceVisitor() { - public PException visitFrame(FrameInstance frameInstance) { - RootCallTarget target = (RootCallTarget) frameInstance.getCallTarget(); - RootNode rootNode = target.getRootNode(); - Node callNode = frameInstance.getCallNode(); - IndirectCallData.setEncapsulatingNeedsToPassExceptionState(callNode); - if (rootNode instanceof PRootNode) { - PRootNode pRootNode = (PRootNode) rootNode; - pRootNode.setNeedsExceptionState(); - Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY); - return PArguments.getException(frame); - } - return null; + return Truffle.getRuntime().iterateFrames(frameInstance -> { + RootCallTarget target = (RootCallTarget) frameInstance.getCallTarget(); + RootNode rootNode = target.getRootNode(); + Node callNode = frameInstance.getCallNode(); + IndirectCallData.setEncapsulatingNeedsToPassExceptionState(callNode); + if (rootNode instanceof PRootNode pRootNode) { + pRootNode.setNeedsExceptionState(); + Frame frame = frameInstance.getFrame(FrameAccess.READ_ONLY); + return PArguments.getException(frame); } + return null; }); } - private PException ensure(PException e) { + private AbstractTruffleException ensure(AbstractTruffleException e) { if (hasExceptionProfile.profile(e == PException.NO_EXCEPTION)) { return null; } else { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java index 745c1f12e2..2dee13fd81 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/ExecutionContext.java @@ -61,6 +61,7 @@ import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.RootCallTarget; import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.frame.FrameInstance; import com.oracle.truffle.api.frame.VirtualFrame; @@ -142,12 +143,12 @@ private void prepareCall(VirtualFrame frame, Object[] callArguments, Node callNo CompilerDirectives.transferToInterpreterAndInvalidate(); neededExceptionState = true; } - PException curExc; + AbstractTruffleException curExc; if (isPythonFrame(frame, callNode)) { curExc = PArguments.getException(frame); if (curExc == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - PException fromStackWalk = GetCaughtExceptionNode.fullStackWalk(); + AbstractTruffleException fromStackWalk = GetCaughtExceptionNode.fullStackWalk(); curExc = fromStackWalk != null ? fromStackWalk : PException.NO_EXCEPTION; // now, set in our args, such that we won't do this again PArguments.setException(frame, curExc); @@ -290,9 +291,9 @@ public static CalleeContext create() { @ValueType private static final class IndirectCallState { private final PFrame.Reference info; - private final PException curExc; + private final AbstractTruffleException curExc; - private IndirectCallState(PFrame.Reference info, PException curExc) { + private IndirectCallState(PFrame.Reference info, AbstractTruffleException curExc) { this.info = info; this.curExc = curExc; } @@ -384,8 +385,8 @@ private static IndirectCallState enter(VirtualFrame frame, PythonThreadState pyt info.setCallNode(callNode); pythonThreadState.setTopFrameInfo(info); } - PException curExc = pythonThreadState.getCaughtException(); - PException exceptionState = PArguments.getException(frame); + AbstractTruffleException curExc = pythonThreadState.getCaughtException(); + AbstractTruffleException exceptionState = PArguments.getException(frame); if (needsExceptionState) { pythonThreadState.setCaughtException(exceptionState); } else if (exceptionState != curExc) { @@ -480,7 +481,7 @@ private static Object enter(PythonThreadState threadState, Object[] pArguments, PArguments.setCallerFrameInfo(pArguments, popTopFrameInfo); if (needsExceptionState) { - PException curExc = threadState.getCaughtException(); + AbstractTruffleException curExc = threadState.getCaughtException(); if (curExc != null) { threadState.setCaughtException(null); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java index 5710671d69..1e1bdbc4f7 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/PythonContext.java @@ -131,6 +131,7 @@ import com.oracle.graal.python.builtins.objects.contextvars.PContextVarsContext; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.exception.ExceptionNodes; +import com.oracle.graal.python.builtins.objects.exception.GetEscapedExceptionNode; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.frame.PFrame; import com.oracle.graal.python.builtins.objects.frame.PFrame.Reference; @@ -194,6 +195,7 @@ import com.oracle.truffle.api.dsl.GenerateUncached; import com.oracle.truffle.api.dsl.NonIdempotent; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.exception.AbstractTruffleException; import com.oracle.truffle.api.instrumentation.AllocationReporter; import com.oracle.truffle.api.interop.ExceptionType; import com.oracle.truffle.api.interop.InteropLibrary; @@ -288,13 +290,13 @@ public static final class PythonThreadState { WeakReference sentinelLock; /* corresponds to 'PyThreadState.curexc_value' */ - private PException currentException; + private AbstractTruffleException currentException; /* corresponds to 'PyThreadState.curexc_traceback' */ private LazyTraceback currentTraceback; /* corresponds to 'PyThreadState.exc_info' */ - private PException caughtException = PException.NO_EXCEPTION; + private AbstractTruffleException caughtException = PException.NO_EXCEPTION; /* set to emulate Py_ReprEnter/Leave */ HashSet reprObjectSet; @@ -390,7 +392,7 @@ void reprLeave(Object item) { reprObjectSet.remove(item); } - public PException getCurrentException() { + public AbstractTruffleException getCurrentException() { return currentException; } @@ -399,32 +401,39 @@ public void clearCurrentException() { this.currentTraceback = null; } - public void setCurrentException(PException currentException) { + public void setCurrentException(AbstractTruffleException currentException) { this.currentException = currentException; - if (currentException.getEscapedException() instanceof PBaseException pythonException) { + if (currentException instanceof PException pe && pe.getEscapedException() instanceof PBaseException pythonException) { this.currentTraceback = pythonException.getTraceback(); } else { - Object tb = ExceptionNodes.GetTracebackNode.executeUncached(currentException.getEscapedException()); + Object exceptionObject = GetEscapedExceptionNode.executeUncached(currentException); + Object tb = ExceptionNodes.GetTracebackNode.executeUncached(exceptionObject); this.currentTraceback = tb instanceof PTraceback ptb ? new LazyTraceback(ptb) : null; } } - public void setCurrentException(PException currentException, LazyTraceback currentTraceback) { + public void setCurrentException(AbstractTruffleException currentException, LazyTraceback currentTraceback) { this.currentException = currentException; this.currentTraceback = currentTraceback; } - public PException getCurrentExceptionForReraise() { + public AbstractTruffleException getCurrentExceptionForReraise() { syncTracebackToException(); - return currentException.getExceptionForReraise(false); + if (currentException instanceof PException pe) { + return pe.getExceptionForReraise(false); + } else { + return currentException; + } } public void syncTracebackToException() { - if (currentException.getUnreifiedException() instanceof PBaseException pythonException) { - pythonException.setTraceback(currentTraceback); - } else { - PTraceback materialized = currentTraceback != null ? MaterializeLazyTracebackNode.executeUncached(currentTraceback) : null; - ExceptionNodes.SetTracebackNode.executeUncached(currentException.getUnreifiedException(), materialized != null ? materialized : PNone.NONE); + if (currentException instanceof PException pe) { + if (pe.getUnreifiedException() instanceof PBaseException pythonException) { + pythonException.setTraceback(currentTraceback); + } else { + PTraceback materialized = currentTraceback != null ? MaterializeLazyTracebackNode.executeUncached(currentTraceback) : null; + ExceptionNodes.SetTracebackNode.executeUncached(pe.getUnreifiedException(), materialized != null ? materialized : PNone.NONE); + } } } @@ -436,11 +445,11 @@ public void setCurrentTraceback(LazyTraceback currentTraceback) { this.currentTraceback = currentTraceback; } - public PException getCaughtException() { + public AbstractTruffleException getCaughtException() { return caughtException; } - public void setCaughtException(PException caughtException) { + public void setCaughtException(AbstractTruffleException caughtException) { this.caughtException = caughtException; }