Ejemplo n.º 1
0
 /// <summary>
 /// Creates a new <see cref="MethodHeaderSection"/> with the
 /// <paramref name="flags"/> provided.
 /// </summary>
 /// <param name="flags">The <see cref="MethodHeaderSectionFlags"/>
 /// which determine information about the <see cref="MethodHeaderSection"/>.</param>
 internal CliMetadataMethodHeaderSection(MethodHeaderSectionFlags flags)
 {
     this.flags = flags;
 }
Ejemplo n.º 2
0
        private void ReadWide(EndianAwareBinaryReader reader, ICliMetadataRoot metadataRoot, Action <byte[]> bodyBuilder)
        {
            var flagsAndSize = reader.ReadUInt16();

            this.flags      = ((MethodHeaderFlags)(flagsAndSize & 0x0FFF)) & ~MethodHeaderFlags.WideFormat;
            this.headerSize = (byte)((flagsAndSize & 0xF000) >> 0xA);
            this.maxStack   = reader.ReadUInt16();
            this.codeSize   = reader.ReadUInt32();
            var localVarSigToken = reader.ReadUInt32();

            if (localVarSigToken != 0)
            {
                var sigTableKind = (CliMetadataTableKinds)(1UL << (int)((localVarSigToken & 0xFF000000) >> 24));
                var sigIndex     = localVarSigToken & 0x00FFFFFF;
                ICliMetadataTable table;
                if (metadataRoot.TableStream.TryGetValue(sigTableKind, out table))
                {
                    if (table is ICliMetadataStandAloneSigTable)
                    {
                        ICliMetadataStandAloneSigTable sigTable = (ICliMetadataStandAloneSigTable)table;
                        var entry = sigTable[(int)sigIndex];
                        if (entry.Signature is ICliMetadataLocalVarSignature)
                        {
                            var sigEntry = (ICliMetadataLocalVarSignature)entry.Signature;
                            this.locals = sigEntry;
                        }
                    }
                }
                long codePosition = reader.BaseStream.Position;
                bodyBuilder(reader.ReadBytes((int)this.codeSize));
                if ((reader.BaseStream.Position % 4) != 0)
                {
                    reader.BaseStream.Position += 4 - reader.BaseStream.Position % 4;
                }
                var ehTable = new byte[0];
                if ((flags & MethodHeaderFlags.ContainsMoreSections) == MethodHeaderFlags.ContainsMoreSections)
                {
readSection:
                    MethodHeaderSectionFlags sectionFlags = (MethodHeaderSectionFlags)reader.ReadByte();
                    var smallFormat = ((sectionFlags & MethodHeaderSectionFlags.FatFormat) != MethodHeaderSectionFlags.FatFormat);
                    int dataSize    = 0;
                    if (smallFormat)
                    {
                        dataSize = reader.ReadByte();
                        reader.ReadUInt16();
                    }
                    else
                    {
                        dataSize = (int)new BitVector(new byte[] { reader.ReadByte(), reader.ReadByte(), reader.ReadByte() }).GetUInt32Nibbits(0, 24);
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ExceptionHandlerTable) == MethodHeaderSectionFlags.ExceptionHandlerTable)
                    {
                        ehTable = ehTable.AddInlineArray(reader.ReadBytes(dataSize - 4));
                    }
                    else
                    {
                        reader.BaseStream.Position += dataSize - 4;
                    }
                    if ((sectionFlags & MethodHeaderSectionFlags.ContainsMoreSections) == MethodHeaderSectionFlags.ContainsMoreSections)
                    {
                        goto readSection;
                    }
                }
                if (ehTable.Length > 0)
                {
                    this.exceptionTable = new CliMetadataMethodExceptionTable(ehTable);
                }
                reader.BaseStream.Position = codePosition;
            }
        }