예제 #1
0
        public CompileUnitEntry DefineCompilationUnit(SourceFileEntry source)
        {
            CompileUnitEntry entry = new CompileUnitEntry(file, source);

            comp_units.Add(entry);
            return(entry);
        }
예제 #2
0
        internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index)
        {
            this.SymbolFile = file;
            this.index      = index;

            Token                 = reader.ReadInt32();
            DataOffset            = reader.ReadInt32();
            LineNumberTableOffset = reader.ReadInt32();

            long old_pos = reader.BaseStream.Position;

            reader.BaseStream.Position = DataOffset;

            CompileUnitIndex         = reader.ReadLeb128();
            LocalVariableTableOffset = reader.ReadLeb128();
            NamespaceID = reader.ReadLeb128();

            CodeBlockTableOffset     = reader.ReadLeb128();
            ScopeVariableTableOffset = reader.ReadLeb128();

            RealNameOffset = reader.ReadLeb128();

            flags = (Flags)reader.ReadLeb128();

            reader.BaseStream.Position = old_pos;

            CompileUnit = file.GetCompileUnit(CompileUnitIndex);
        }
예제 #3
0
        public CompileUnitEntry GetCompileUnit(int index)
        {
            if ((index < 1) || (index > ot.CompileUnitCount))
            {
                throw new ArgumentException();
            }
            if (reader == null)
            {
                throw new InvalidOperationException();
            }

            lock (this) {
                CompileUnitEntry unit;
                if (compile_unit_hash.TryGetValue(index, out unit))
                {
                    return(unit);
                }

                long old_pos = reader.BaseStream.Position;

                reader.BaseStream.Position = ot.CompileUnitTableOffset +
                                             CompileUnitEntry.Size * (index - 1);
                unit = new CompileUnitEntry(this, reader);
                compile_unit_hash.Add(index, unit);

                reader.BaseStream.Position = old_pos;
                return(unit);
            }
        }
예제 #4
0
        public int DefineNamespace(string name, CompileUnitEntry unit,
                                   string[] using_clauses, int parent)
        {
            if ((unit == null) || (using_clauses == null))
            {
                throw new NullReferenceException();
            }

            return(unit.DefineNamespace(name, using_clauses, parent));
        }
예제 #5
0
        public ISymbolDocumentWriter DefineDocument(
            string url,
            Guid language,
            Guid languageVendor,
            Guid documentType)
        {
            SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl)documents [url];

            if (doc == null)
            {
                SourceFileEntry  entry     = msw.DefineDocument(url);
                CompileUnitEntry comp_unit = msw.DefineCompilationUnit(entry);
                doc             = new SymbolDocumentWriterImpl(comp_unit);
                documents [url] = doc;
            }
            return(doc);
        }
예제 #6
0
        public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token,
                                        ScopeVariable[] scope_vars, LocalVariableEntry[] locals,
                                        LineNumberEntry[] lines, CodeBlockEntry[] code_blocks,
                                        string real_name, MethodEntry.Flags flags,
                                        int namespace_id)
        {
            if (reader != null)
            {
                throw new InvalidOperationException();
            }

            MethodEntry method = new MethodEntry(
                this, comp_unit, token, scope_vars, locals, lines, code_blocks,
                real_name, flags, namespace_id);

            AddMethod(method);
            return(method);
        }
예제 #7
0
        internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit,
                             int token, ScopeVariable[] scope_vars,
                             LocalVariableEntry[] locals, LineNumberEntry[] lines,
                             CodeBlockEntry[] code_blocks, string real_name,
                             Flags flags, int namespace_id)
        {
            this.SymbolFile  = file;
            this.real_name   = real_name;
            this.locals      = locals;
            this.code_blocks = code_blocks;
            this.scope_vars  = scope_vars;
            this.flags       = flags;

            index = -1;

            Token            = token;
            CompileUnitIndex = comp_unit.Index;
            CompileUnit      = comp_unit;
            NamespaceID      = namespace_id;

            CheckLineNumberTable(lines);
            lnt = new LineNumberTable(file, lines);
            file.NumLineNumbers += lines.Length;

            int num_locals = locals != null ? locals.Length : 0;

            if (num_locals <= 32)
            {
                // Most of the time, the O(n^2) factor is actually
                // less than the cost of allocating the hash table,
                // 32 is a rough number obtained through some testing.

                for (int i = 0; i < num_locals; i++)
                {
                    string nm = locals [i].Name;

                    for (int j = i + 1; j < num_locals; j++)
                    {
                        if (locals [j].Name == nm)
                        {
                            flags |= Flags.LocalNamesAmbiguous;
                            goto locals_check_done;
                        }
                    }
                }
locals_check_done:
                ;
            }
            else
            {
                var local_names = new Dictionary <string, LocalVariableEntry> ();
                foreach (LocalVariableEntry local in locals)
                {
                    if (local_names.ContainsKey(local.Name))
                    {
                        flags |= Flags.LocalNamesAmbiguous;
                        break;
                    }
                    local_names.Add(local.Name, local);
                }
            }
        }
예제 #8
0
 public SymbolDocumentWriterImpl(CompileUnitEntry comp_unit)
 {
     this.comp_unit = comp_unit;
 }
예제 #9
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
        }
예제 #10
0
 public int AddCompileUnit(CompileUnitEntry entry)
 {
     comp_units.Add(entry);
     return(comp_units.Count);
 }