HRESULT MicrosoftInstrumentationEngine::CInstruction::InstructionFromBytes()

in src/InstrumentationEngine/Instruction.cpp [194:286]


HRESULT MicrosoftInstrumentationEngine::CInstruction::InstructionFromBytes(
    _In_ LPCBYTE pCode,
    _In_ LPCBYTE pEndOfCode,
    _Out_ CInstruction** ppInstruction)
{
    HRESULT hr = S_OK;
    *ppInstruction = NULL;
    ILOrdinalOpcode opcode;
    CInstruction::OrdinalOpcodeFromBytes(pCode, pEndOfCode, &opcode);

    if ( opcode < 0 || opcode >= _countof(CInstruction::s_ilOpcodeInfo) )
    {
        CLogging::LogError(_T("CInstruction::InstructionFromBytes - incorrect il stream;"));
        return E_FAIL;
    }

    ILOpcodeFlags flags = CInstruction::s_ilOpcodeInfo[opcode].m_flags;
    ILOperandType type = CInstruction::s_ilOpcodeInfo[opcode].m_type;

    CComPtr<CInstruction> pInstruction;
    if (opcode == Cee_Switch)
    {
        CComPtr<CSwitchInstruction> pSwitchInstruction;
        pSwitchInstruction.Attach(new CSwitchInstruction(opcode, FALSE));
        if (!pSwitchInstruction)
        {
            return E_OUTOFMEMORY;
        }

        IfFailRet(pSwitchInstruction->InitializeFromBytes(pCode, pEndOfCode));
        *ppInstruction = pSwitchInstruction.Detach();
    }
    else
    {
        if ((flags & ILOpcodeFlag_Branch) != 0)
        {
            CComPtr<CBranchInstruction> pBranchInstruction;
            pBranchInstruction.Attach(new CBranchInstruction(opcode, FALSE));
            if (!pBranchInstruction)
            {
                return E_OUTOFMEMORY;
            }

            IfFailRet(pBranchInstruction->InitializeFromBytes(pCode, pEndOfCode));
            *ppInstruction = pBranchInstruction.Detach();
        }
        else
        {
            switch (type)
            {
                case ILOperandType_None:
                {
                    CComPtr<CInstruction> pNoneInstruction;
                    pNoneInstruction.Attach(new CInstruction(opcode, FALSE));
                    if (!pNoneInstruction)
                    {
                        return E_OUTOFMEMORY;
                    }

                    IfFailRet(pNoneInstruction->InitializeFromBytes(pCode, pEndOfCode));
                    *ppInstruction = pNoneInstruction.Detach();
                    break;
                }

                case ILOperandType_Byte:
                case ILOperandType_UShort:
                case ILOperandType_Int:
                case ILOperandType_Long:
                case ILOperandType_Single:
                case ILOperandType_Double:
                case ILOperandType_Token:
                {
                    CComPtr<COperandInstruction> pNumericOperandInstruction;
                    pNumericOperandInstruction.Attach(new COperandInstruction(opcode, FALSE));
                    if (!pNumericOperandInstruction)
                    {
                        return E_OUTOFMEMORY;
                    }

                    IfFailRet(pNumericOperandInstruction->InitializeFromBytes(pCode, pEndOfCode));
                    *ppInstruction = pNumericOperandInstruction.Detach();
                    break;
                }

                default:
                {
                    return E_FAIL;
                }
            }
        }
    }
    return S_OK;
}