void Write(MyBinaryWriter bw, Guid guid) { // Magic number and file version. bw.Write(OffsetTable.Magic); bw.Write(MajorVersion); bw.Write(MinorVersion); bw.Write(guid.ToByteArray()); // // Offsets of file sections; we must write this after we're done // writing the whole file, so we just reserve the space for it here. // long offset_table_offset = bw.BaseStream.Position; ot.Write(bw, MajorVersion, MinorVersion); // // Sort the methods according to their tokens and update their index. // methods.Sort(); for (int i = 0; i < methods.Count; i++) { methods [i].Index = i + 1; } // // Write data sections. // ot.DataSectionOffset = (int)bw.BaseStream.Position; foreach (SourceFileEntry source in sources) { source.WriteData(bw); } foreach (CompileUnitEntry comp_unit in comp_units) { comp_unit.WriteData(bw); } foreach (MethodEntry method in methods) { method.WriteData(this, bw); } ot.DataSectionSize = (int)bw.BaseStream.Position - ot.DataSectionOffset; // // Write the method index table. // ot.MethodTableOffset = (int)bw.BaseStream.Position; for (int i = 0; i < methods.Count; i++) { MethodEntry entry = methods [i]; entry.Write(bw); } ot.MethodTableSize = (int)bw.BaseStream.Position - ot.MethodTableOffset; // // Write source table. // ot.SourceTableOffset = (int)bw.BaseStream.Position; for (int i = 0; i < sources.Count; i++) { SourceFileEntry source = sources [i]; source.Write(bw); } ot.SourceTableSize = (int)bw.BaseStream.Position - ot.SourceTableOffset; // // Write compilation unit table. // ot.CompileUnitTableOffset = (int)bw.BaseStream.Position; for (int i = 0; i < comp_units.Count; i++) { CompileUnitEntry unit = comp_units [i]; unit.Write(bw); } ot.CompileUnitTableSize = (int)bw.BaseStream.Position - ot.CompileUnitTableOffset; // // Write anonymous scope table. // ot.AnonymousScopeCount = anonymous_scopes != null ? anonymous_scopes.Count : 0; ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position; if (anonymous_scopes != null) { foreach (AnonymousScopeEntry scope in anonymous_scopes.Values) { scope.Write(bw); } } ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - ot.AnonymousScopeTableOffset; // // Fixup offset table. // ot.TypeCount = last_type_index; ot.MethodCount = methods.Count; ot.SourceCount = sources.Count; ot.CompileUnitCount = comp_units.Count; // // Write offset table. // ot.TotalFileSize = (int)bw.BaseStream.Position; bw.Seek((int)offset_table_offset, SeekOrigin.Begin); ot.Write(bw, MajorVersion, MinorVersion); bw.Seek(0, SeekOrigin.End); #if false Console.WriteLine("TOTAL: {0} line numbes, {1} bytes, extended {2} bytes, " + "{3} methods.", NumLineNumbers, LineNumberSize, ExtendedLineNumberSize, methods.Count); #endif }
public void DefineMethod(MonoSymbolFile file, int token) { var blocks = Blocks; if (blocks.Length > 0) { // // When index is provided by user it can be inserted in // any order but mdb format does not store its value. It // uses stored order as the index instead. // var sorted = new List <CodeBlockEntry> (blocks.Length); int max_index = 0; for (int i = 0; i < blocks.Length; ++i) { max_index = System.Math.Max(max_index, blocks [i].Index); } for (int i = 0; i < max_index; ++i) { var scope_index = i + 1; // // Common fast path // if (i < blocks.Length && blocks [i].Index == scope_index) { sorted.Add(blocks [i]); continue; } bool found = false; for (int ii = 0; ii < blocks.Length; ++ii) { if (blocks [ii].Index == scope_index) { sorted.Add(blocks [ii]); found = true; break; } } if (found) { continue; } // // Ideally this should never happen but with current design we can // generate scope index for unreachable code before reachable code // sorted.Add(new CodeBlockEntry(scope_index, -1, CodeBlockEntry.Type.CompilerGenerated, 0)); } blocks = sorted.ToArray(); //for (int i = 0; i < blocks.Length; ++i) { // if (blocks [i].Index - 1 != i) // throw new ArgumentException ("CodeBlocks cannot be converted to mdb format"); //} } var entry = new MethodEntry( file, _comp_unit.Entry, token, ScopeVariables, Locals, method_lines.ToArray(), blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id); file.AddMethod(entry); }
public void AddMethod(MethodEntry entry) { methods.Add(entry); }