}
}
- /**
- * 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.
{
// 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);
}
* 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)
ClassInfo thrownType;
if (isGdcExceptionClass(exceptionClass))
{
- thrownType = ExceptionHeader.getClassInfo(unwindHeader);
+ thrownType = getClassInfo(unwindHeader, lsda);
}
while (1)
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.
// 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);
{
// 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.