📄 frame.cpp
字号:
// specified number of bytes. Adjust the pointer as required. If
// the thing is not a pointer, then this should be safe since all
// the entries in the THISDISP are 0.
DEBUGMSG(DBGEH,(TEXT("Object thrown is CT_ISSIMPLETYPE\r\n")));
memmove(pCatchBuffer, PER_PEXCEPTOBJ(pExcept), CT_SIZE(*pConv));
if (CT_SIZE(*pConv) == sizeof(void*) && *pCatchBuffer != NULL) {
*pCatchBuffer = AdjustPointer(*pCatchBuffer,
CT_THISDISP(*pConv));
}
} else {
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: Object thrown is UDT\r\n")));
if (CT_COPYFUNC(*pConv) == NULL) {
// The UDT had a simple ctor. Adjust in the thrown object,
// then copy n bytes.
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: No copy ctor is provided\r\n")));
memmove(pCatchBuffer, AdjustPointer(PER_PEXCEPTOBJ(pExcept),
CT_THISDISP(*pConv)),
CT_SIZE(*pConv));
} else {
// It's a UDT: make a copy using copy ctor
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: The copy ctor (0x%08x) provided \r\n"),
CT_COPYFUNC(*pConv)));
if (CT_HASVB(*pConv)) {
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: The class has virtual base 0x%08x\r\n"),
CT_HASVB(*pConv)));
_CallMemberFunction2((char *)pCatchBuffer,
CT_COPYFUNC(*pConv),
AdjustPointer(PER_PEXCEPTOBJ(pExcept),
CT_THISDISP(*pConv)), 1);
} else {
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: The class has No virtual base CT_HASVB\r\n")));
_CallMemberFunction1((char *)pCatchBuffer,
CT_COPYFUNC(*pConv),
AdjustPointer(PER_PEXCEPTOBJ(pExcept),
CT_THISDISP(*pConv)));
}
}
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: Something went wrong when building the catch object.\r\n")));
std::terminate();
}
DEBUGMSG(DBGEH,(TEXT("BuildCatchObject: EXIT\r\n")));
} // BuildCatchObject
////////////////////////////////////////////////////////////////////////////////
//
// _DestructExceptionObject - Call the destructor (if any) of the original
// exception object.
//
// Returns: None.
//
// Side-effects:
// Original exception object is destructed.
//
// Notes:
// If destruction throws any exception, and we are destructing the exception
// object as a result of a new exception, we give up. If the destruction
// throws otherwise, we let it be.
#define __ResetException(a)
void _DestructExceptionObject(
EHExceptionRecord *pExcept, // The original exception record
BOOLEAN fThrowNotAllowed // TRUE if destructor not allowed to throw
)
{
DEBUGMSG(DBGEH,(TEXT("_DestructExceptionObject: Func=%08x pExcept=%08x\r\n"),
THROW_UNWINDFUNC(*PER_PTHROW(pExcept)), pExcept));
if (pExcept != NULL && THROW_UNWINDFUNC(*PER_PTHROW(pExcept)) != NULL) {
__try {
// M00REVIEW: A destructor has additional hidden arguments, doesn't it?
DEBUGMSG(DBGEH,(TEXT("_DestructExceptionObject Func=%08x Obj=%08x\r\n"),
THROW_UNWINDFUNC(*PER_PTHROW(pExcept)),
PER_PEXCEPTOBJ(pExcept)));
#pragma warning(disable:4191)
_CallMemberFunction0(PER_PEXCEPTOBJ(pExcept),
THROW_UNWINDFUNC(*PER_PTHROW(pExcept)));
__ResetException(pExcept);
} __except(fThrowNotAllowed
? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {
// Can't have new exceptions when we're unwinding due to another
// exception.
std::terminate();
}
#pragma warning(default:4191)
}
}
////////////////////////////////////////////////////////////////////////////////
//
// AdjustPointer - Adjust the pointer to the exception object to a pointer to a
// base instance.
//
// Output:
// The address point of the base.
//
// Side-effects:
// NONE.
static void *AdjustPointer(
void *pThis, // Address point of exception object
const PMD& pmd // Generalized pointer-to-member descriptor
)
{
char *pRet = (char *)pThis + pmd.mdisp;
if (pmd.pdisp >= 0) {
pRet += *(ptrdiff_t *)((char *)*(ptrdiff_t *)((char *)pThis + pmd.pdisp)
+ pmd.vdisp);
pRet += pmd.pdisp;
}
return pRet;
}
///////////////////////////////////////////////////////////////////////////////
//
// std::uncaught_exception() - Returns true after completing evaluation of a
// throw-expression until either completing
// initialization of the exception-declaration in
// the matching handler.
//
bool __cdecl std::uncaught_exception()
{
return (__ProcessingThrow != 0);
}
#if !defined(_X86_)
//
// Used by BuildCatchObject to copy the thrown object. Since catch-handlers are
// nested functions, and access variables with up-level addressing, we have
// to find the frame of the outer-most parent.
//
PVOID _OffsetToAddress( ptrdiff_t offset, PULONG pBase, ULONG nesting_level )
{
#if (_M_SH == 5)
while (nesting_level-- > 1)
pBase = (PULONG)(*(PULONG)((char*)pBase));
#else
#if defined(_M_ARM)
CATCHFRAMEINFO *pCatchFrame = pCatchChain;
#endif
while( nesting_level > 1 ) {
#if defined(_M_ARM)
pBase = (PULONG)pCatchFrame->pRN ;
DEBUGMSG(DBGEH,(TEXT("pBASE %08x Nest Level %d\r\n"),
pBase, pCatchFrame->NestLevel)) ;
pCatchFrame = pCatchFrame->next;
#elif defined(_MIPS64) // MIPS64 in this context means 64-bit registers
pBase = (PULONG)(*(PULONG)((char*)pBase - 8));
#else
pBase = (PULONG)(*(PULONG)((char*)pBase - 4));
#endif
nesting_level--;
}
#endif
return (PVOID)(((char*)pBase) + (int)offset);
}
//
// This routine returns a corresponding frame info structure if we are executing
// from within a catch. Otherwise, NULL is returned.
//
FRAMEINFO *
FindFrameInfo(
EHRegistrationNode *pRN
)
{
FRAMEINFO *pFrameInfo = pFrameInfoChain;
while ( pFrameInfo != NULL ){
if ( pFrameInfo->pRN == pRN ) {
break;
}
pFrameInfo = pFrameInfo->next;
}
return pFrameInfo;
}
FRAMEINFO *
FindCatchFrameInfo(
EHRegistrationNode *pRN
)
{
FRAMEINFO *pFrameInfo = pFrameInfoChain;
while ( pFrameInfo != NULL ){
if ( pFrameInfo->pCatchRN == pRN ) {
break;
}
pFrameInfo = pFrameInfo->next;
}
return pFrameInfo;
}
#ifdef CC_OUTERTRY
// _GetRangeOfTrysToCheck - determine which try blocks are of interest, given
// the current catch block nesting depth. We only check the trys at a single
// depth.
//
// Returns:
// Address of first try block of interest is returned
// pStart and pEnd get the indices of the range in question
// This is the version of _GetRangeOfTrysToCheck that would work if
// CC_OUTERTRY is defined in the BE. To be compatible with EH format
// output by the OLD MIPS compiler, CC_OUTERTRY causes the MIPS-UTC compiler
// to emit the outer try index in the try block table instead of the
// "high catch state".
TryBlockMapEntry* _GetRangeOfTrysToCheck(
FuncInfo *pFuncInfo,
int CatchDepth,
__ehstate_t curState,
unsigned *pStart,
unsigned *pEnd
)
{
TryBlockMapEntry *pEntry;
unsigned num_of_try_blocks = FUNC_NTRYBLOCKS(*pFuncInfo);
DEBUGCHK( num_of_try_blocks > 0 );
for( unsigned int index = 0; index < num_of_try_blocks; index++ )
{
pEntry = FUNC_PTRYBLOCK(*pFuncInfo, index);
if(curState >= TBME_LOW(*pEntry) && curState <= TBME_HIGH(*pEntry) )
{
*pStart = index;
//
// It would be better to return the end-index itself, but I don't
// want to change the caller's code.
//
*pEnd = TBME_CATCHHIGH(*pEntry) + 1;
DEBUGCHK( *pEnd <= num_of_try_blocks && *pStart < *pEnd );
return pEntry;
}
}
*pStart = *pEnd = 0;
return NULL;
}
#else // CC_OUTERTRY
// _GetRangeOfTrysToCheck - determine which try blocks are of interest, given
// the current catch block nesting depth. We only check the trys at a single
// depth.
//
// Returns:
// Address of first try block of interest is returned
// pStart and pEnd get the indices of the range in question
TryBlockMapEntry *_GetRangeOfTrysToCheck(
FuncInfo *pFuncInfo,
int CatchDepth,
__ehstate_t curState,
unsigned *pStart,
unsigned *pEnd
)
{
TryBlockMapEntry *pEntry = FUNC_PTRYBLOCK(*pFuncInfo, 0);
int start;
int end = FUNC_NTRYBLOCKS(*pFuncInfo) - 1;
//
// First, find the innermost try block that contains this state. We
// must always check this try block.
//
for (start = 0; start <= end; start++)
{
if (TBME_LOW(pEntry[start]) <= curState &&
TBME_HIGH(pEntry[start]) >= curState)
{
break;
}
}
// We may not check try block if we are already in an associated catch.
// We know our current catch depth and that the try blocks are sorted
// innermost to outermost. Therefore, we start with the outermost try
// block and remove it from list of try blocks to check, if we are in
// its catch. We continue working inward until we have accounted for
// our current catch depth.
if(CatchDepth > 0 && start < end)
{
for (; CatchDepth > 0 && start < end; end--) {
if (TBME_HIGH(pEntry[end]) < curState &&
curState <= TBME_CATCHHIGH(pEntry[end]))
{
--CatchDepth;
}
}
end++;
}
*pStart = start;
*pEnd = end + 1;
DEBUGCHK(*pEnd >= *pStart && *pEnd <= FUNC_NTRYBLOCKS(*pFuncInfo));
return &(pEntry[start]);
}
#endif // CC_OUTERTRY
#endif // !_X86_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -