aboutsummaryrefslogtreecommitdiff
path: root/libphobos
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-09-25 23:18:53 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2021-09-30 15:07:19 +0200
commit8088a33df5f62fd6416fb8cb158b791e639aa707 (patch)
tree5fb9d1c8bd0e552010f86971d057b92cac056014 /libphobos
parented3ec7343b7d104a3285336fbfc1e4719719f9b6 (diff)
downloadgcc-8088a33df5f62fd6416fb8cb158b791e639aa707.zip
gcc-8088a33df5f62fd6416fb8cb158b791e639aa707.tar.gz
gcc-8088a33df5f62fd6416fb8cb158b791e639aa707.tar.bz2
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.
Diffstat (limited to 'libphobos')
-rw-r--r--libphobos/libdruntime/gcc/deh.d74
1 files changed, 44 insertions, 30 deletions
diff --git a/libphobos/libdruntime/gcc/deh.d b/libphobos/libdruntime/gcc/deh.d
index a7eb37c..ba57fed 100644
--- a/libphobos/libdruntime/gcc/deh.d
+++ b/libphobos/libdruntime/gcc/deh.d
@@ -280,26 +280,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)
@@ -779,6 +760,41 @@ int actionTableLookup(_Unwind_Action actions, _Unwind_Exception* unwindHeader,
}
/**
+ * 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.