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

📄 frame.cpp

📁 不错的东西 请查看 WINCE OS
💻 CPP
📖 第 1 页 / 共 4 页
字号:

#endif

    // Determine range of try blocks to consider:
    // Only try blocks which are at the current catch depth are of interest.

    unsigned int curTryBlockIndex;    // the index of current try block.
    unsigned int endTryBlockIndex;    // the index of try block to end search, itself excluded

    TryBlockMapEntry *pEntry = _GetRangeOfTrysToCheck(pFuncInfo,
                                                      CatchDepth,
                                                      curState,
                                                      &curTryBlockIndex,
                                                      &endTryBlockIndex);

    DEBUGMSG(DBGEH,(TEXT("FindHandler: TBME=%08x  curTryBlockIndex=%d  endTryBlockIndex=%d  curState=%d\r\n"), 
                    pEntry, curTryBlockIndex, endTryBlockIndex, curState));

    // Scan the try blocks in the function:
    for (; curTryBlockIndex < endTryBlockIndex; curTryBlockIndex++, pEntry++) {

        DEBUGMSG(DBGEH,(TEXT("FindHandler: Scanning Try Block: pEntry=%08x curTryBlockIndex=%d  curState=%d\r\n"), 
                        pEntry, curTryBlockIndex, curState));
        DEBUGMSG(DBGEH,(TEXT("FindHandler: TBME_LOW=%d  TBME_HIGH=%d\r\n"), 
                        TBME_LOW(*pEntry), TBME_HIGH(*pEntry)));
                        
        if (TBME_LOW(*pEntry) > curState || curState > TBME_HIGH(*pEntry)) {
            DEBUGMSG(DBGEH,(TEXT("FindHandler: curState(%d) not in range. Skipping Try Block(%d)\r\n"),
                            curState, curTryBlockIndex));
            continue;
        }

#if !defined(_X86_)

        //
        //  Only consider catch blocks at a higher nesting level:
        //

        DEBUGMSG(DBGEH,(TEXT("FindHandler: CatchDepth=%d  HT_FRAMENEST=%d\r\n"), 
                        CatchDepth, HT_FRAMENEST(TBME_CATCH(*pEntry, 0))));

        if ( CatchDepth >= (int)HT_FRAMENEST(TBME_CATCH(*pEntry, 0)) ){
            DEBUGMSG(DBGEH,(TEXT("FindHandler: Skipping Enclosing Catch Block. \r\n")));
            continue;
        }

#endif // !defined(_X86_)

        DEBUGMSG(DBGEH,(TEXT("FindHandler: In Try block scope, TBME_NCATCHES=%d\r\n"),
                        TBME_NCATCHES(*pEntry)));

        // Try block was in scope for current state.  Scan catches for this try:

        for (int catchIndex = 0; catchIndex < TBME_NCATCHES(*pEntry); catchIndex++){
            HandlerType *pCatch;
            CatchableType * const *ppCatchable;

            // get pCatch with catchIndex
            pCatch  = TBME_PCATCH(*pEntry, catchIndex);

            DEBUGMSG(DBGEH,(TEXT("FindHandler: catchIndex(%d) pCatch=%08x is trying to catch\r\n"),
                            catchIndex, pCatch));

            if (!PER_IS_MSVC_EH(pExcept)){

                //
                //  Non EH exception, check for an ellipsis handler
                //
            
                DEBUGMSG(DBGEH,(TEXT("FindHandler: Non Eh\r\n")));
                Found = (HT_IS_TYPE_ELLIPSIS(TBME_CATCH(*pEntry, catchIndex))
                     && (!HT_IS_STD_DOTDOT(TBME_CATCH(*pEntry, catchIndex))));
                ppCatchable = NULL;

            } else {

                // 
                // Scan all types that thrown object can be converted to:
                // 
                DEBUGMSG(DBGEH,(TEXT("FindHandler: to scan %d thrown objects ...\r\n"),
                                THROW_COUNT(*PER_PTHROW(pExcept))));

                ppCatchable = THROW_CTLIST(*PER_PTHROW(pExcept));

                for (int catchableIndex = 0;
                     catchableIndex < THROW_COUNT(*PER_PTHROW(pExcept));
                     catchableIndex++, ppCatchable++) {
    
                    DEBUGMSG(DBGEH,(TEXT("FindHandler: catchableIndex(%d) ppCatchable=%08x  properties=%08x pCatch=%08x\r\n"),
                                    catchableIndex, ppCatchable, CT_PROPERTIES(**ppCatchable), pCatch));
    
                    if (TypeMatch(pCatch, *ppCatchable, PER_PTHROW(pExcept))) {
                        DEBUGMSG(DBGEH,(TEXT("FindHandler: Found: *ppCatchable=%08x TypeMatched pCatch=%08x\r\n"),
                                        *ppCatchable, pCatch));
                        Found = TRUE;
                        break;
                    }
    
                } // Scan possible conversions

            } // MSVC_EH exception

            if ( Found ) {

                DEBUGMSG(DBGEH,(TEXT("FindHandler: pNewExcept(0x%08x) obj(0x%08x) pthrow(0x%08x)\r\n"),
                                pNewExcept, PER_PEXCEPTOBJ(pNewExcept), PER_PTHROW(pNewExcept)));

                _pCurrExceptRethrow = pRethrowException;

                if (pRethrowException) {
                    DEBUGMSG(DBGEH,(TEXT("FindHandler: set pNewExcept(0x%08x) obj|pthrow to be pExcept(0x%08x)\r\n"),
                                    pNewExcept, pExcept));

                    PER_PEXCEPTOBJ(pNewExcept) = PER_PEXCEPTOBJ(pExcept);
                    PER_PTHROW(pNewExcept) = PER_PTHROW(pExcept);
                    
                    DEBUGMSG(DBGEH,(TEXT("FindHandler: pNewExcept(0x%08x) obj(0x%08x) pthrow(0x%08x)\r\n"),
                                    pNewExcept, PER_PEXCEPTOBJ(pNewExcept), PER_PTHROW(pNewExcept)));
                }

                //
                //  A handler was found. Save current state and build a
                //  catch object.
                //
    
                TargetEntry = pEntry;
    
                DEBUGMSG(DBGEH,(TEXT("FindHandler: Catch Block Found: Handler=%08x  TargetState=%d\r\n"), 
                                HT_HANDLER(*pCatch), TBME_LOW(*pEntry)));
                DEBUGMSG(DBGEH,(TEXT("FindHandler: set TargetEntry=pEntry=%08x\r\n"), 
                                pEntry));
    
                //
                //  Set the Unwind continuation address to the address of
                //  the catch handler.
                //
    
                pDC->ControlPc = (ULONG)HT_HANDLER(*pCatch);
    
                if (ppCatchable && *ppCatchable != NULL) {
                    DEBUGMSG(DBGEH,(TEXT("FindHandler: Call BuildCatchObject\r\n")));
                    BuildCatchObject(pExcept, pRN, pCatch, *ppCatchable);
                }
    
                DEBUGMSG(DBGEH,(TEXT("FindHandler: EXIT handler Found\r\n")));

                return TRUE;
            }

        } // Scan catch clauses

    } // Scan try blocks

    DEBUGMSG(DBGEH,(TEXT("FindHandler: EXIT return search again\r\n")));

    return FALSE;

} // FindHandler

////////////////////////////////////////////////////////////////////////////////
//
// TypeMatch - Check if the catch type matches the given throw conversion.
//
// Returns:
//     TRUE if the catch can catch using this throw conversion, FALSE otherwise.

static __inline int TypeMatch(
    HandlerType   *pCatch,         // Type of the 'catch' clause
    CatchableType *pCatchable,     // Type conversion under consideration
    ThrowInfo     *pThrow          // General information about the thrown type.
    ) 
{
    // First, check for match with ellipsis:
    if (HT_IS_TYPE_ELLIPSIS(*pCatch)) {
        return TRUE;
    }

    // Not ellipsis; the basic types match if it's the same record *or* the
    // names are identical.
    if (HT_PTD(*pCatch) != CT_PTD(*pCatchable)
        && strcmp(HT_NAME(*pCatch), CT_NAME(*pCatchable)) != 0) {
        return FALSE;
    }

    // Basic types match.  The actual conversion is valid if:
    //   caught by ref if ref required *and*
    //   the qualifiers are compatible *and*
    //   the alignments match *and*
    //   the volatility matches

    return (!CT_BYREFONLY(*pCatchable) || HT_ISREFERENCE(*pCatch))
        && (!THROW_ISCONST(*pThrow) || HT_ISCONST(*pCatch))
#if !defined(_X86_)
        && (!THROW_ISUNALIGNED(*pThrow) || HT_ISUNALIGNED(*pCatch))
#endif
        && (!THROW_ISVOLATILE(*pThrow) || HT_ISVOLATILE(*pCatch));

} // TypeMatch


////////////////////////////////////////////////////////////////////////////////
//
// FrameUnwindFilter - Allows possibility of continuing through SEH during
//   unwind.
//

static int FrameUnwindFilter(
    EXCEPTION_POINTERS *pExPtrs
    ) 
{
    EHExceptionRecord *pExcept = (EHExceptionRecord *)pExPtrs->ExceptionRecord;

    switch (PER_CODE(pExcept)) {
    case EH_EXCEPTION_NUMBER:
        __ProcessingThrow = 0;
        std::terminate();

#ifdef ALLOW_UNWIND_ABORT
    case EH_ABORT_FRAME_UNWIND_PART:
        return EXCEPTION_EXECUTE_HANDLER;
#endif

    default:
        return EXCEPTION_CONTINUE_SEARCH;
    }
}


////////////////////////////////////////////////////////////////////////////////
//
// __FrameUnwindToState - Unwind this frame until specified state is reached.
//
// Returns:
//     No return value.
//
// Side Effects:
//     All objects on frame which go out of scope as a result of the unwind are
//       destructed.
//     Registration node is updated to reflect new state.
//
// Usage:
//      This function is called both to do full-frame unwind during the unwind
//      phase (targetState = -1), and to do partial unwinding when the current
//      frame has an appropriate catch.

extern "C" void __FrameUnwindToState (
    EHRegistrationNode *pRN,            // Registration node for subject function
    PDISPATCHER_CONTEXT pDC,            // Context within subject frame
    FuncInfo           *pFuncInfo,      // Static information for subject function
    __ehstate_t         targetState     // State to unwind to
    ) 
{
    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: ENTER: pRN=%08x  pDC->ControlPc=%08x targetState=%d\r\n"), 
                    pRN, pDC->ControlPc, targetState));

    __ehstate_t curState = GetCurrentState(pRN, pDC, pFuncInfo);
    __ProcessingThrow++;

    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: curState=GetCurrentState=%d\r\n"), 
                    curState));

#if !defined(_X86_)
    //
    //  If unwinding from a catch block which threw, use the unwind state from
    //  the catch block. (CatchExceptRN is set in CallCatchBlock)
    //

    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: CatchExceptRN=%08x CatchExceptState=%d\r\n"), 
                    CatchExceptRN, CatchExceptState));

    if ( pRN == CatchExceptRN ) {
        curState = CatchExceptState;

        DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: pRN=CatchExceptRN=%08x\r\n"), pRN));
        DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: reset curState=%d\r\n"), curState));
    }
    CatchExceptRN = 0;

#endif // !defined(_X86_)

    __try {
        while (curState != targetState)
        {

            // The unwind-map may have a shortcut by using EH_EMPTY_STATE
            if ( curState == EH_EMPTY_STATE ){
                break;
            }

            DEBUGCHK((curState > EH_EMPTY_STATE) && (curState < FUNC_MAXSTATE(*pFuncInfo)));

            DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: curState=%d\r\n"), curState));

            __try {

                // Call the unwind action (if one exists):
                if (UWE_ACTION(FUNC_UNWIND(*pFuncInfo, curState)) != NULL) {

#if defined(_M_ARM)
                    pRN = FindFrameForUnwind (pRN, pFuncInfo);
                    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: ARM adjusted pRN=%08x\r\n"),
                                    UWE_ACTION(FUNC_UNWIND(*pFuncInfo, curState)), pRN));
                    // pass correct frame pointer for unwind funclet. In ARM
                    // the frame pointer is not stored in stack when catch
                    // block is called. so we need to pass the correct frame
                    // to access the locals
#endif // _M_ARM

                    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: to call _CallSettingFrame with action @%08x pRN=%08x\r\n"),
                                    UWE_ACTION(FUNC_UNWIND(*pFuncInfo, curState)), pRN));

                    _CallSettingFrame(UWE_ACTION(FUNC_UNWIND(*pFuncInfo, curState)),
                                      pRN, DC_CONTEXTRECORD(pDC), NULL);
                } 
                else {
                    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: no action for curState=%d\r\n"),
                                    curState));
                }
            } __except(FrameUnwindFilter(exception_info())) {
            }

            // Adjust the state:
            curState = UWE_TOSTATE(FUNC_UNWIND(*pFuncInfo, curState));

            DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: adjust curState=%d\r\n"), curState));
        }
    } __finally {
        if (__ProcessingThrow > 0) {
            __ProcessingThrow--;
        }
    }

    DEBUGCHK(curState == targetState);

    DEBUGMSG(DBGEH,(TEXT("__FrameUnwindToState: EXIT curState=targetState=%d\r\n"), curState));

} // __FrameUnwindToState



#define IS_RETHROW(pNewExcept, pExcept)  \
       ( pNewExcept && pExcept && pNewExcept!=pExcept \
       && PER_PEXCEPTOBJ(pNewExcept)==PER_PEXCEPTOBJ(pExcept) \
       && PER_PTHROW(pNewExcept)==PER_PTHROW(pExcept))


////////////////////////////////////////////////////////////////////////////////
//
//  CanThisExceptionObjectBeDestructed
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -