< Summary

Line coverage
0%
Covered lines: 0
Uncovered lines: 127
Coverable lines: 127
Total lines: 227
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 20
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%110%
GetILBytes()100%110%
GetILContent()100%110%
GetILReader()100%110%
Create(...)0%16160%
ReadSmallExceptionHandlers(...)0%220%
ReadFatExceptionHandlers(...)0%220%

File(s)

https://raw.githubusercontent.com/dotnet/runtime/811a7eabb75c42db53440e8ba3f60c07511cfd1f/src/libraries/System.Reflection.Metadata/src/System/Reflection/Metadata/IL/MethodBodyBlock.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System.Collections.Immutable;
 5using System.Diagnostics;
 6using System.Reflection.Internal;
 7using System.Reflection.Metadata.Ecma335;
 8using System.Runtime.InteropServices;
 9
 10namespace System.Reflection.Metadata
 11{
 12    public sealed class MethodBodyBlock
 13    {
 14        private readonly MemoryBlock _il;
 15        private readonly int _size;
 16        private readonly ushort _maxStack;
 17        private readonly bool _localVariablesInitialized;
 18        private readonly StandaloneSignatureHandle _localSignature;
 19        private readonly ImmutableArray<ExceptionRegion> _exceptionRegions;
 20
 021        private MethodBodyBlock(
 022            bool localVariablesInitialized,
 023            ushort maxStack,
 024            StandaloneSignatureHandle localSignatureHandle,
 025            MemoryBlock il,
 026            ImmutableArray<ExceptionRegion> exceptionRegions,
 027            int size)
 028        {
 029            Debug.Assert(!exceptionRegions.IsDefault);
 30
 031            _localVariablesInitialized = localVariablesInitialized;
 032            _maxStack = maxStack;
 033            _localSignature = localSignatureHandle;
 034            _il = il;
 035            _exceptionRegions = exceptionRegions;
 036            _size = size;
 037        }
 38
 39        /// <summary>
 40        /// Size of the method body - includes the header, IL and exception regions.
 41        /// </summary>
 42        public int Size
 43        {
 044            get { return _size; }
 45        }
 46
 47        public int MaxStack
 48        {
 049            get { return _maxStack; }
 50        }
 51
 52        public bool LocalVariablesInitialized
 53        {
 054            get { return _localVariablesInitialized; }
 55        }
 56
 57        public StandaloneSignatureHandle LocalSignature
 58        {
 059            get { return _localSignature; }
 60        }
 61
 62        public ImmutableArray<ExceptionRegion> ExceptionRegions
 63        {
 064            get { return _exceptionRegions; }
 65        }
 66
 67        public byte[]? GetILBytes()
 068        {
 069            return _il.ToArray();
 070        }
 71
 72        public ImmutableArray<byte> GetILContent()
 073        {
 074            byte[]? bytes = GetILBytes();
 075            return ImmutableCollectionsMarshal.AsImmutableArray(bytes);
 076        }
 77
 78        public BlobReader GetILReader()
 079        {
 080            return new BlobReader(_il);
 081        }
 82
 83        private const byte ILTinyFormat = 0x02;
 84        private const byte ILFatFormat = 0x03;
 85        private const byte ILFormatMask = 0x03;
 86        private const int ILTinyFormatSizeShift = 2;
 87        private const byte ILMoreSects = 0x08;
 88        private const byte ILInitLocals = 0x10;
 89        private const byte ILFatFormatHeaderSize = 0x03;
 90        private const int ILFatFormatHeaderSizeShift = 4;
 91        private const byte SectEHTable = 0x01;
 92        private const byte SectFatFormat = 0x40;
 93
 94        public static MethodBodyBlock Create(BlobReader reader)
 095        {
 096            int startOffset = reader.Offset;
 97            int ilSize;
 98
 99            // Error need to check if the Memory Block is empty. This is false for all the calls...
 0100            byte headByte = reader.ReadByte();
 0101            if ((headByte & ILFormatMask) == ILTinyFormat)
 0102            {
 103                // tiny IL can't have locals so technically this shouldn't matter,
 104                // but false is consistent with other metadata readers and helps
 105                // for use cases involving comparing our output with theirs.
 106                const bool initLocalsForTinyIL = false;
 107
 0108                ilSize = headByte >> ILTinyFormatSizeShift;
 0109                return new MethodBodyBlock(
 0110                    initLocalsForTinyIL,
 0111                    8,
 0112                    default(StandaloneSignatureHandle),
 0113                    reader.GetMemoryBlockAt(0, ilSize),
 0114                    ImmutableArray<ExceptionRegion>.Empty,
 0115                    1 + ilSize // header + IL
 0116                );
 117            }
 118
 0119            if ((headByte & ILFormatMask) != ILFatFormat)
 0120            {
 0121                throw new BadImageFormatException(SR.Format(SR.InvalidMethodHeader1, headByte));
 122            }
 123
 124            // FatILFormat
 0125            byte headByte2 = reader.ReadByte();
 0126            if ((headByte2 >> ILFatFormatHeaderSizeShift) != ILFatFormatHeaderSize)
 0127            {
 0128                throw new BadImageFormatException(SR.Format(SR.InvalidMethodHeader2, headByte, headByte2));
 129            }
 130
 0131            bool localsInitialized = (headByte & ILInitLocals) == ILInitLocals;
 0132            bool hasExceptionHandlers = (headByte & ILMoreSects) == ILMoreSects;
 133
 0134            ushort maxStack = reader.ReadUInt16();
 0135            ilSize = reader.ReadInt32();
 136
 0137            int localSignatureToken = reader.ReadInt32();
 138            StandaloneSignatureHandle localSignatureHandle;
 0139            if (localSignatureToken == 0)
 0140            {
 0141                localSignatureHandle = default(StandaloneSignatureHandle);
 0142            }
 0143            else if ((localSignatureToken & TokenTypeIds.TypeMask) == TokenTypeIds.Signature)
 0144            {
 0145                localSignatureHandle = StandaloneSignatureHandle.FromRowId((int)((uint)localSignatureToken & TokenTypeId
 0146            }
 147            else
 0148            {
 0149                throw new BadImageFormatException(SR.Format(SR.InvalidLocalSignatureToken, unchecked((uint)localSignatur
 150            }
 151
 0152            var ilBlock = reader.GetMemoryBlockAt(0, ilSize);
 0153            reader.Offset += ilSize;
 154
 155            ImmutableArray<ExceptionRegion> exceptionHandlers;
 0156            if (hasExceptionHandlers)
 0157            {
 0158                reader.Align(4);
 0159                byte sehHeader = reader.ReadByte();
 0160                if ((sehHeader & SectEHTable) != SectEHTable)
 0161                {
 0162                    throw new BadImageFormatException(SR.Format(SR.InvalidSehHeader, sehHeader));
 163                }
 164
 0165                bool sehFatFormat = (sehHeader & SectFatFormat) == SectFatFormat;
 0166                int dataSize = reader.ReadByte();
 0167                if (sehFatFormat)
 0168                {
 0169                    dataSize += reader.ReadUInt16() << 8;
 0170                    exceptionHandlers = ReadFatExceptionHandlers(ref reader, dataSize / 24);
 0171                }
 172                else
 0173                {
 0174                    reader.Offset += 2; // skip over reserved field
 0175                    exceptionHandlers = ReadSmallExceptionHandlers(ref reader, dataSize / 12);
 0176                }
 0177            }
 178            else
 0179            {
 0180                exceptionHandlers = ImmutableArray<ExceptionRegion>.Empty;
 0181            }
 182
 0183            return new MethodBodyBlock(
 0184                localsInitialized,
 0185                maxStack,
 0186                localSignatureHandle,
 0187                ilBlock,
 0188                exceptionHandlers,
 0189                reader.Offset - startOffset);
 0190        }
 191
 192        private static ImmutableArray<ExceptionRegion> ReadSmallExceptionHandlers(ref BlobReader memReader, int count)
 0193        {
 0194            var result = ImmutableArray.CreateBuilder<ExceptionRegion>(count);
 0195            for (int i = 0; i < count; i++)
 0196            {
 0197                var kind = (ExceptionRegionKind)memReader.ReadUInt16();
 0198                var tryOffset = memReader.ReadUInt16();
 0199                var tryLength = memReader.ReadByte();
 0200                var handlerOffset = memReader.ReadUInt16();
 0201                var handlerLength = memReader.ReadByte();
 0202                var classTokenOrFilterOffset = memReader.ReadInt32();
 0203                result.Add(new ExceptionRegion(kind, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFil
 0204            }
 205
 0206            return result.MoveToImmutable();
 0207        }
 208
 209        private static ImmutableArray<ExceptionRegion> ReadFatExceptionHandlers(ref BlobReader memReader, int count)
 0210        {
 0211            var result = ImmutableArray.CreateBuilder<ExceptionRegion>(count);
 0212            for (int i = 0; i < count; i++)
 0213            {
 0214                var kind = (ExceptionRegionKind)memReader.ReadUInt32();
 0215                int tryOffset = memReader.ReadInt32();
 0216                int tryLength = memReader.ReadInt32();
 0217                int handlerOffset = memReader.ReadInt32();
 0218                int handlerLength = memReader.ReadInt32();
 0219                int classTokenOrFilterOffset = memReader.ReadInt32();
 0220                result.Add(new ExceptionRegion(kind, tryOffset, tryLength, handlerOffset, handlerLength, classTokenOrFil
 0221            }
 222
 0223            return result.MoveToImmutable();
 0224        }
 225    }
 226}
 227