Example #1
0
        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);
        }
Example #3
0
 public void AddMethod(MethodEntry entry)
 {
     methods.Add(entry);
 }