bool ByteCode::Finish() { if ( !ResolveBranches()) return false; codes= codes->cloneSize(codeIndex, mustAllocate); literals= literals->cloneSize(literalIndex, mustAllocate); if ( codes == failedAllocationOop ) { errorMessage= "out of memory for codes in ByteCode::Finish"; ranOutOfMemory= true; return false; } if ( literals == failedAllocationOop) { errorMessage= "out of memory for literals in ByteCode::Finish"; ranOutOfMemory= true; return false; } return true; }
/// <summary>Read in a method body and any section handlers.</summary> /// <remarks>Also converts all short branches to long branches and calls <c>RecalculateOffsets</c></remarks> void Method::ReadBody() { _ASSERTE(m_header.CodeSize != 0); _ASSERTE(GetPosition() == 0); while (GetPosition() < m_header.CodeSize) { Instruction* pInstruction = new Instruction(); pInstruction->m_offset = GetPosition(); pInstruction->m_origOffset = pInstruction->m_offset; BYTE op1 = REFPRE; BYTE op2 = Read<BYTE>(); if (STP1 == op2) { op1 = STP1; op2 = Read<BYTE>(); } OperationDetails &details = Operations::m_mapOpsOperationDetails[MAKEWORD(op1, op2)]; pInstruction->m_operation = details.canonicalName; switch (details.operandSize) { case Null: break; case Byte: pInstruction->m_operand = Read<BYTE>(); break; case Word: pInstruction->m_operand = Read<USHORT>(); break; case Dword: pInstruction->m_operand = Read<ULONG>(); break; case Qword: pInstruction->m_operand = Read<ULONGLONG>(); break; default: break; } // are we a branch or a switch pInstruction->m_isBranch = (details.controlFlow == BRANCH || details.controlFlow == COND_BRANCH); if (pInstruction->m_isBranch && pInstruction->m_operation != CEE_SWITCH) { if (details.operandSize == 1) { pInstruction->m_branchOffsets.push_back(static_cast<char>(static_cast<BYTE>(pInstruction->m_operand))); } else { pInstruction->m_branchOffsets.push_back(static_cast<ULONG>(pInstruction->m_operand)); } } if (pInstruction->m_operation == CEE_SWITCH) { auto numbranches = static_cast<DWORD>(pInstruction->m_operand); while (numbranches-- != 0) pInstruction->m_branchOffsets.push_back(Read<long>()); } m_instructions.push_back(pInstruction); } ReadSections(); SetBuffer(nullptr); ResolveBranches(); ConvertShortBranches(); RecalculateOffsets(); }