Exception handling support for Dwarf-style portable exceptions.
Wrap the unwinder's data with our own compiler specific struct with our own data.
static @nogc ExceptionHeader*
create(Throwable
o);
Allocate and initialize an ExceptionHeader.
Returns:allocated and initalized ExceptionHeader
static void
free(ExceptionHeader*
eh);
Free ExceptionHeader that was created by create().
Parameters:ExceptionHeader*eh | ExceptionHeader to free |
Push this onto stack of chained exceptions.
static ExceptionHeader*
pop();
Pop and return top of chained exception stack.
static ExceptionHeader*
toExceptionHeader(_Unwind_Exception*
eo);
Convert from pointer to exception_object to pointer to ExceptionHeader that it is embedded inside of.
Parameters:_Unwind_Exception*eo | pointer to exception_object field |
Returns:pointer to ExceptionHeader that eo points into.
Throwable
__dmd_begin_catch(_Unwind_Exception*
exceptionObject);
The first thing a catch handler does is call this.
Parameters:_Unwind_Exception*exceptionObject | value passed to catch handler by unwinder |
Returns:object that was caught
nothrow @nogc void*
_d_eh_swapContextDwarf(void*
newContext);
Called when fibers switch contexts.
Parameters:void*newContext | stack to switch to |
Returns:previous value of stack
void
_d_throwdwarf(Throwable
o);
Called by D code to throw an exception via
throwo;
Parameters:Throwableo | Object to throw |
_Unwind_Reason_Code
__dmd_personality_v0(int
ver, _Unwind_Action
actions, _Unwind_Exception_Class
exceptionClass, _Unwind_Exception*
exceptionObject, _Unwind_Context*
context);
"personality" function, specific to each language. This one, of course, is specific to DMD.
Parameters:intver | version must be 1 |
_Unwind_Actionactions | bitwise OR of the 4 actions UA_xxx. UA_SEARCH_PHASE means return URC_HANDLER_FOUND if current frame has a handler, URC_CONTINUE_UNWIND if not. Cannot be used with UA_CLEANUP_PHASE. UA_CLEANUP_PHASE means perform cleanup for current frame by calling nested functions and returning URC_CONTINUE_UNWIND. Or, set up registers and IP for Landing Pad and return URC_INSTALL_CONTEXT. UA_HANDLER_FRAME means this frame was the one with the handler in Phase 1, and now it is Phase 2 and the handler must be run. UA_FORCE_UNWIND means unwinding the stack for longjmp or thread cancellation. Run finally clauses, not catch clauses, finallys must end with call to Uwind_Resume(). |
_Unwind_Exception_ClassexceptionClass | 8 byte value indicating type of thrown exception. If the low 4 bytes are "C++\0", it's a C++ exception. |
_Unwind_Exception*exceptionObject | language specific exception information |
_Unwind_Context*context | opaque type of unwinder state information |
ClassInfo
getClassInfo(_Unwind_Exception*
exceptionObject, const(ubyte)*
currentLsd);
Look at the chain of inflight exceptions and pick the class type that'll be looked for in catch clauses.
Parameters:_Unwind_Exception*exceptionObject | language specific exception information |
const(ubyte)*currentLsd | pointer to LSDA table |
Returns:class type to look for
_uleb128_t
uLEB128(const(ubyte)**
p);
Decode Unsigned LEB128.
Parameters:const(ubyte)**p | pointer to data pointer, *p is updated to point past decoded value |
_sleb128_t
sLEB128(const(ubyte)**
p);
Decode Signed LEB128.
Parameters:const(ubyte)**p | pointer to data pointer, *p is updated to point past decoded value |
LsdaResult
scanLSDA(const(ubyte)*
lsda, _Unwind_Ptr
ip, _Unwind_Exception_Class
exceptionClass, bool
cleanupsOnly, bool
preferHandler, _Unwind_Exception*
exceptionObject, out _Unwind_Ptr
landingPad, out int
handler);
Read and extract information from the LSDA (aka gcc_except_table section). The dmd Call Site Table is structurally different from other implementations. It is organized as nested ranges, and one ip can map to multiple ranges. The most nested candidate is selected when searched. Other implementations have one candidate per ip.
Parameters:const(ubyte)*lsda | pointer to LSDA table |
_Unwind_Ptrip | offset from start of function at which exception happened |
_Unwind_Exception_ClassexceptionClass | which language threw the exception |
boolcleanupsOnly | only look for cleanups |
boolpreferHandler | if a handler encloses a cleanup, prefer the handler |
_Unwind_Exception*exceptionObject | language specific exception information |
_Unwind_PtrlandingPad | set to landing pad |
inthandler | set to index of which catch clause was matched |
int
actionTableLookup(_Unwind_Exception*
exceptionObject, uint
actionRecordPtr, const(ubyte)*
pActionTable, const(ubyte)*
tt, ubyte
TType, _Unwind_Exception_Class
exceptionClass, const(ubyte)*
lsda);
Look up classType in Action Table.
Parameters:_Unwind_Exception*exceptionObject | language specific exception information |
uintactionRecordPtr | starting index in Action Table + 1 |
const(ubyte)*pActionTable | pointer to start of Action Table |
const(ubyte)*tt | pointer past end of Type Table |
ubyteTType | encoding of entries in Type Table |
_Unwind_Exception_ClassexceptionClass | which language threw the exception |
const(ubyte)*lsda | pointer to LSDA table |
Returns:- >=1 means the handler index of the classType
- 0 means classType is not in the Action Table
- <0 means corrupt
enum _Unwind_Exception_Class
cppExceptionClass;
C++ Support
void*
getCppPtrToThrownObject(_Unwind_Exception*
exceptionObject, CppTypeInfo
sti);
Get Pointer to Thrown Object if type of thrown object is implicitly convertible to the catch type.
Parameters:_Unwind_Exception*exceptionObject | language specific exception information |
CppTypeInfosti | type of catch clause |
Returns:null if not caught, pointer to thrown object if caught
Access C++ std::type_info's virtual functions from D, being careful to not require linking with libstd++ or interfere with core.stdcpp.typeinfo. So, give it a different name.
struct
CppExceptionHeader;
The C++ version of D's ExceptionHeader wrapper
static CppExceptionHeader*
toExceptionHeader(_Unwind_Exception*
eo);
Convert from pointer to exception_object field to pointer to CppExceptionHeader that it is embedded inside of.
Parameters:_Unwind_Exception*eo | pointer to exception_object field |
Returns:pointer to CppExceptionHeader that eo points into.