⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frame.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 4 页
字号:
            // 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 + -