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;
}