/// <summary> /// Encodes a method body and adds it to the method body stream. /// </summary> /// <param name="codeSize">Number of bytes to be reserved for instructions.</param> /// <param name="maxStack">Max stack.</param> /// <param name="exceptionRegionCount">Number of exception regions.</param> /// <param name="hasSmallExceptionRegions">True if the exception regions should be encoded in 'small' format.</param> /// <param name="localVariablesSignature">Local variables signature handle.</param> /// <param name="attributes">Attributes.</param> /// <param name="hasDynamicStackAllocation">True if the method allocates from dynamic local memory pool (<c>localloc</c> instruction).</param> /// <returns>The offset of the encoded body within the method body stream.</returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="codeSize"/>, <paramref name="exceptionRegionCount"/>, or <paramref name="maxStack"/> is out of allowed range. /// </exception> public MethodBody AddMethodBody( int codeSize, int maxStack = 8, int exceptionRegionCount = 0, bool hasSmallExceptionRegions = true, StandaloneSignatureHandle localVariablesSignature = default, MethodBodyAttributes attributes = MethodBodyAttributes.InitLocals, bool hasDynamicStackAllocation = false) { if (codeSize < 0) { Throw.ArgumentOutOfRange(nameof(codeSize)); } if (unchecked ((uint)maxStack) > ushort.MaxValue) { Throw.ArgumentOutOfRange(nameof(maxStack)); } if (!ExceptionRegionEncoder.IsExceptionRegionCountInBounds(exceptionRegionCount)) { Throw.ArgumentOutOfRange(nameof(exceptionRegionCount)); } int bodyOffset = SerializeHeader(codeSize, (ushort)maxStack, exceptionRegionCount, attributes, localVariablesSignature, hasDynamicStackAllocation); var instructions = Builder.ReserveBytes(codeSize); var regionEncoder = (exceptionRegionCount > 0) ? ExceptionRegionEncoder.SerializeTableHeader(Builder, exceptionRegionCount, hasSmallExceptionRegions) : default; return(new MethodBody(bodyOffset, instructions, regionEncoder)); }
public void SerializeTableHeader() { var builder = new BlobBuilder(); builder.WriteByte(0xff); ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxSmallExceptionRegions, hasSmallRegions: true); AssertEx.Equal(new byte[] { 0xff, 0x00, 0x00, 0x00, // padding 0x01, // flags 0xf4, // size 0x00, 0x00 }, builder.ToArray()); builder.Clear(); builder.WriteByte(0xff); ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxExceptionRegions, hasSmallRegions: false); AssertEx.Equal(new byte[] { 0xff, 0x00, 0x00, 0x00, // padding 0x41, // flags 0xf4, 0xff, 0xff, // size }, builder.ToArray()); }