コード例 #1
0
ファイル: MethodHeader.cs プロジェクト: Zahovay/MOSA-Project
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        public MethodHeader(EndianAwareBinaryReader reader)
        {
            Clauses = new List<ExceptionHandlingClause>();

            // Read first byte
            Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    CodeSize = ((int)(Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)Flags);

                    if (MethodFlags.ValidHeader != (Flags & MethodFlags.HeaderSizeMask))
                        throw new CompilerException("Invalid method ");

                    MaxStack = reader.ReadUInt16();
                    CodeSize = reader.ReadInt32();
                    LocalVarSigTok = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new CompilerException("Invalid method header");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (Flags & MethodFlags.MoreSections))
                return;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), "Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    Clauses.Add(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;
        }
コード例 #2
0
ファイル: DecodingStage.cs プロジェクト: grover/MOSA-Project
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        private MethodHeader ReadMethodHeader(EndianAwareBinaryReader reader)
        {
            MethodHeader header = new MethodHeader();

            // Read first byte
            header.Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (header.Flags & MethodFlags.HeaderMask)
            {
                case MethodFlags.TinyFormat:
                    header.CodeSize = ((uint)(header.Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                    header.Flags &= MethodFlags.HeaderMask;
                    break;

                case MethodFlags.FatFormat:
                    // Read second byte of flags
                    header.Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)header.Flags);
                    if (MethodFlags.ValidHeader != (header.Flags & MethodFlags.HeaderSizeMask))
                        throw new InvalidDataException(@"Invalid method header.");
                    header.MaxStack = reader.ReadUInt16();
                    header.CodeSize = reader.ReadUInt32();
                    header.LocalsSignature = new Token(reader.ReadUInt32()); // ReadStandAloneSigRow
                    break;

                default:
                    throw new InvalidDataException(@"Invalid method header while trying to decode " + this.methodCompiler.Method.ToString() + ". (Flags = " + header.Flags.ToString("X") + ", Rva = " + this.methodCompiler.Method.Rva + ")");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (header.Flags & MethodFlags.MoreSections))
                return header;

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + header.CodeSize;
            if (0 != (dataSectPos & 3))
                dataSectPos += (4 - (dataSectPos % 4));
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int length;
                int blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), @"Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    methodCompiler.ExceptionClauseHeader.AddClause(clause);
                }
            }
            while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;

            return header;
        }
コード例 #3
0
        /// <summary>
        /// Reads the method header from the instruction stream.
        /// </summary>
        /// <param name="reader">The reader used to decode the instruction stream.</param>
        /// <returns></returns>
        public MethodHeader(EndianAwareBinaryReader reader)
        {
            Clauses = new List <ExceptionHandlingClause>();

            // Read first byte
            Flags = (MethodFlags)reader.ReadByte();

            // Check least significant 2 bits
            switch (Flags & MethodFlags.HeaderMask)
            {
            case MethodFlags.TinyFormat:
                CodeSize = ((int)(Flags & MethodFlags.TinyCodeSizeMask) >> 2);
                Flags   &= MethodFlags.HeaderMask;
                break;

            case MethodFlags.FatFormat:
                // Read second byte of flags
                Flags = (MethodFlags)(reader.ReadByte() << 8 | (byte)Flags);

                if (MethodFlags.ValidHeader != (Flags & MethodFlags.HeaderSizeMask))
                {
                    throw new CompilerException("Invalid method ");
                }

                MaxStack       = reader.ReadUInt16();
                CodeSize       = reader.ReadInt32();
                LocalVarSigTok = new Token(reader.ReadUInt32());                         // ReadStandAloneSigRow
                break;

            default:
                throw new CompilerException("Invalid method header");
            }

            // Are there sections following the code?
            if (MethodFlags.MoreSections != (Flags & MethodFlags.MoreSections))
            {
                return;
            }

            // Yes, seek to them and process those sections
            long codepos = reader.BaseStream.Position;

            // Seek to the end of the code...
            long dataSectPos = codepos + CodeSize;

            if (0 != (dataSectPos & 3))
            {
                dataSectPos += (4 - (dataSectPos % 4));
            }
            reader.BaseStream.Position = dataSectPos;

            // Read all headers, so the IL decoder knows how to handle these...
            byte flags;

            do
            {
                flags = reader.ReadByte();
                bool isFat = (0x40 == (flags & 0x40));
                int  length;
                int  blocks;
                if (isFat)
                {
                    byte a = reader.ReadByte();
                    byte b = reader.ReadByte();
                    byte c = reader.ReadByte();

                    length = (c << 24) | (b << 16) | a;
                    blocks = (length - 4) / 24;
                }
                else
                {
                    length = reader.ReadByte();
                    blocks = (length - 4) / 12;

                    /* Read & skip the padding. */
                    reader.ReadInt16();
                }

                Debug.Assert(0x01 == (flags & 0x3F), "Unsupported method data section.");

                // Read the clause
                for (int i = 0; i < blocks; i++)
                {
                    ExceptionHandlingClause clause = new ExceptionHandlingClause();
                    clause.Read(reader, isFat);
                    Clauses.Add(clause);
                }
            }while (0x80 == (flags & 0x80));

            reader.BaseStream.Position = codepos;
        }