public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r12-3989] libphobos: Select the appropriate exception handler in getClassInfo
@ 2021-09-30 16:41 Iain Buclaw
0 siblings, 0 replies; only message in thread
From: Iain Buclaw @ 2021-09-30 16:41 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:8088a33df5f62fd6416fb8cb158b791e639aa707
commit r12-3989-g8088a33df5f62fd6416fb8cb158b791e639aa707
Author: Iain Buclaw <ibuclaw@gdcproject.org>
Date: Sat Sep 25 23:18:53 2021 +0200
libphobos: Select the appropriate exception handler in getClassInfo
This is analogous to __gdc_personality, which ignores in-flight
exceptions that we haven't collided with yet.
libphobos/ChangeLog:
* libdruntime/gcc/deh.d (ExceptionHeader.getClassInfo): Move to...
(getClassInfo): ...here as free function. Add lsda parameter.
(scanLSDA): Pass lsda to actionTableLookup.
(actionTableLookup): Add lsda parameter, pass to getClassInfo.
(__gdc_personality): Remove currentCfa variable.
Diff:
---
libphobos/libdruntime/gcc/deh.d | 74 ++++++++++++++++++++++++-----------------
1 file changed, 44 insertions(+), 30 deletions(-)
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index a7eb37cfd9e..ba57fed38dc 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -279,26 +279,6 @@ struct ExceptionHeader
}
}
- /**
- * Look at the chain of inflight exceptions and pick the class type that'll
- * be looked for in catch clauses.
- */
- static ClassInfo getClassInfo(_Unwind_Exception* unwindHeader) @nogc
- {
- ExceptionHeader* eh = toExceptionHeader(unwindHeader);
- // The first thrown Exception at the top of the stack takes precedence
- // over others that are inflight, unless an Error was thrown, in which
- // case, we search for error handlers instead.
- Throwable ehobject = eh.object;
- for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next)
- {
- Error e = cast(Error)ehobject;
- if (e is null || (cast(Error)ehn.object) !is null)
- ehobject = ehn.object;
- }
- return ehobject.classinfo;
- }
-
/**
* Convert from pointer to unwindHeader to pointer to ExceptionHeader
* that it is embedded inside of.
@@ -666,7 +646,7 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
{
// Otherwise we have a catch handler or exception specification.
handler = actionTableLookup(actions, unwindHeader, actionRecord,
- exceptionClass, TTypeBase,
+ lsda, exceptionClass, TTypeBase,
TType, TTypeEncoding,
saw_handler, saw_cleanup);
}
@@ -694,7 +674,8 @@ _Unwind_Reason_Code scanLSDA(const(ubyte)* lsda, _Unwind_Exception_Class excepti
* Look up and return the handler index of the classType in Action Table.
*/
int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
- const(ubyte)* actionRecord, _Unwind_Exception_Class exceptionClass,
+ const(ubyte)* actionRecord, const(ubyte)* lsda,
+ _Unwind_Exception_Class exceptionClass,
_Unwind_Ptr TTypeBase, const(ubyte)* TType,
ubyte TTypeEncoding,
out bool saw_handler, out bool saw_cleanup)
@@ -702,7 +683,7 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
ClassInfo thrownType;
if (isGdcExceptionClass(exceptionClass))
{
- thrownType = ExceptionHeader.getClassInfo(unwindHeader);
+ thrownType = getClassInfo(unwindHeader, lsda);
}
while (1)
@@ -778,6 +759,41 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
return 0;
}
+/**
+ * Look at the chain of inflight exceptions and pick the class type that'll
+ * be looked for in catch clauses.
+ */
+ClassInfo getClassInfo(_Unwind_Exception* unwindHeader,
+ const(ubyte)* currentLsd) @nogc
+{
+ ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader);
+ // The first thrown Exception at the top of the stack takes precedence
+ // over others that are inflight, unless an Error was thrown, in which
+ // case, we search for error handlers instead.
+ Throwable ehobject = eh.object;
+ for (ExceptionHeader* ehn = eh.next; ehn; ehn = ehn.next)
+ {
+ const(ubyte)* nextLsd = void;
+ _Unwind_Ptr nextLandingPad = void;
+ _Unwind_Word nextCfa = void;
+ int nextHandler = void;
+
+ ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa);
+
+ // Don't combine when the exceptions are from different functions.
+ if (currentLsd != nextLsd)
+ break;
+
+ Error e = cast(Error)ehobject;
+ if (e is null || (cast(Error)ehn.object) !is null)
+ {
+ currentLsd = nextLsd;
+ ehobject = ehn.object;
+ }
+ }
+ return ehobject.classinfo;
+}
+
/**
* Called when the personality function has found neither a cleanup or handler.
* To support ARM EABI personality routines, that must also unwind the stack.
@@ -934,16 +950,15 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions,
// current object onto the end of the prevous object.
ExceptionHeader* eh = ExceptionHeader.toExceptionHeader(unwindHeader);
auto currentLsd = lsda;
- auto currentCfa = cfa;
bool bypassed = false;
while (eh.next)
{
ExceptionHeader* ehn = eh.next;
- const(ubyte)* nextLsd;
- _Unwind_Ptr nextLandingPad;
- _Unwind_Word nextCfa;
- int nextHandler;
+ const(ubyte)* nextLsd = void;
+ _Unwind_Ptr nextLandingPad = void;
+ _Unwind_Word nextCfa = void;
+ int nextHandler = void;
ExceptionHeader.restore(&ehn.unwindHeader, nextHandler, nextLsd, nextLandingPad, nextCfa);
@@ -952,14 +967,13 @@ private _Unwind_Reason_Code __gdc_personality(_Unwind_Action actions,
{
// We found an Error, bypass the exception chain.
currentLsd = nextLsd;
- currentCfa = nextCfa;
eh = ehn;
bypassed = true;
continue;
}
// Don't combine when the exceptions are from different functions.
- if (currentLsd != nextLsd && currentCfa != nextCfa)
+ if (currentLsd != nextLsd)
break;
// Add our object onto the end of the existing chain.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2021-09-30 16:41 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-30 16:41 [gcc r12-3989] libphobos: Select the appropriate exception handler in getClassInfo Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).