/// <summary> /// Interprets a raw method body to a CILMethodBody, disassembling all instructions, obtaining the local variables /// and reading the extra sections for exception handlers. /// </summary> /// <param name="method">The parent method the method body is associated to.</param> /// <param name="rawMethodBody">The raw method body to convert.</param> /// <returns>The converted method body.</returns> public static CilMethodBody FromRawMethodBody(MethodDefinition method, CilRawMethodBody rawMethodBody) { var body = new CilMethodBody(method); var fatBody = rawMethodBody as CilRawFatMethodBody; if (fatBody != null) { // Read fat method body header fields. body.MaxStack = fatBody.MaxStack; body.InitLocals = fatBody.InitLocals; if (method.Image.TryResolveMember(new MetadataToken(fatBody.LocalVarSigToken), out var signature)) { body.Signature = signature as StandAloneSignature; } } else { // Set values for tiny method bodies. body.MaxStack = 8; body.InitLocals = false; } // Read code. var codeReader = new MemoryStreamReader(rawMethodBody.Code); var disassembler = new CilDisassembler(codeReader, body); foreach (var instruction in disassembler.Disassemble()) { body.Instructions.Add(instruction); } if (fatBody != null) { // Read exception handlers. foreach (var section in fatBody.ExtraSections) { var sectionReader = new MemoryStreamReader(section.Data); while (sectionReader.CanRead(section.IsFat ? ExceptionHandler.FatExceptionHandlerSize : ExceptionHandler.SmallExceptionHandlerSize)) { body.ExceptionHandlers.Add(ExceptionHandler.FromReader(body, sectionReader, section.IsFat)); } } } return(body); }