Пример #1
0
        /// <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);
        }