/// <summary> /// /// </summary> /// <param name="clause"></param> private void AddClauseLabels(EhClause clause) { AddClauseLabel(clause, clause.TryOffset); AddClauseLabel(clause, clause.TryEnd); AddClauseLabel(clause, clause.HandlerOffset); AddClauseLabel(clause, clause.HandlerEnd); }
/// <summary> /// Reads the method header from the instruction stream. /// </summary> /// <param name="reader">The reader used to decode the instruction stream.</param> /// <param name="header">The method header structure to populate.</param> private void ReadMethodHeader(BinaryReader reader, ref MethodHeader header) { // 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)) { // 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[] buffer = new byte[4]; reader.Read(buffer, 0, 3); length = LittleEndianBitConverter.GetInt32(buffer, 0); 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++) { EhClause clause = new EhClause(); clause.Read(reader, isFat); //this.methodCompiler.Method.ExceptionClauseHeader.AddClause(clause); // FIXME: Create proper basic Blocks for each item in the clause } }while (0x80 == (flags & 0x80)); //methodCompiler.Method.ExceptionClauseHeader.Sort(); reader.BaseStream.Position = codepos; } }
/// <summary> /// Reads the method header from the instruction stream. /// </summary> /// <param name="reader">The reader used to decode the instruction stream.</param> /// <param name="header">The method header structure to populate.</param> private void ReadMethodHeader(BinaryReader reader, ref MethodHeader header) { header.flags = (MethodFlags)reader.ReadByte(); switch (header.flags & MethodFlags.HeaderMask) { case MethodFlags.TinyFormat: header.codeSize = ((uint)(header.flags & MethodFlags.TinyCodeSizeMask) >> 2); header.flags &= MethodFlags.HeaderMask; break; case MethodFlags.FatFormat: 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 = (TokenTypes)reader.ReadUInt32(); break; default: throw new InvalidDataException(@"Invalid method header."); } // Are there sections following the code? if (MethodFlags.MoreSections == (header.flags & MethodFlags.MoreSections)) { // 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[] buffer = new byte[4]; reader.Read(buffer, 0, 3); length = LittleEndianBitConverter.GetInt32(buffer, 0); 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++) { EhClause clause = new EhClause(); clause.Read(reader, isFat); this.methodCompiler.Method.ExceptionClauseHeader.AddClause(clause); // FIXME: Create proper basic Blocks for each item in the clause } } while (0x80 == (flags & 0x80)); methodCompiler.Method.ExceptionClauseHeader.Sort(); reader.BaseStream.Position = codepos; } }
/// <summary> /// /// </summary> /// <param name="clause"></param> public void AddClause(EhClause clause) { this.Clauses.Add(clause); }
/// <summary> /// /// </summary> /// <param name="clause"></param> /// <param name="label"></param> private void AddClauseLabel(EhClause clause, int label) { this.labelMapping[label] = clause; }