Mono.CompilerServices.SymbolWriter.LineNumberTable.Write C# (CSharp) Method

Write() private method

private Write ( MonoSymbolFile file, MyBinaryWriter bw ) : void
file MonoSymbolFile
bw MyBinaryWriter
return void
        internal void Write(MonoSymbolFile file, MyBinaryWriter bw)
        {
            int start = (int) bw.BaseStream.Position;

            bool last_is_hidden = false;
            int last_line = 1, last_offset = 0, last_file = 1;
            for (int i = 0; i < LineNumbers.Length; i++) {
                int line_inc = LineNumbers [i].Row - last_line;
                int offset_inc = LineNumbers [i].Offset - last_offset;

                if (SuppressDuplicates && (i+1 < LineNumbers.Length)) {
                    if (LineNumbers [i+1].Equals (LineNumbers [i]))
                        continue;
                }

                if (LineNumbers [i].File != last_file) {
                    bw.Write (DW_LNS_set_file);
                    bw.WriteLeb128 (LineNumbers [i].File);
                    last_file = LineNumbers [i].File;
                }

                if (LineNumbers [i].IsHidden != last_is_hidden) {
                    bw.Write ((byte) 0);
                    bw.Write ((byte) 1);
                    bw.Write (DW_LNE_MONO_negate_is_hidden);
                    last_is_hidden = LineNumbers [i].IsHidden;
                }

            #if DEBUGGER_SOURCE
                if (LineNumbers [i].SourceRange != null) {
                    bw.Write ((byte) 0);
                    long tmp_offset = bw.BaseStream.Position;
                    bw.Write ((byte) 0);
                    bw.Write (DW_LNE_MONO_set_source_range);

                    /*
                     * Use a private extended opcode to encode source ranges.
                     *
                     * Instead of only having one integer "line number", we now have a struct
                     * containing 'StartLine', 'EndLine', 'StartColumn' and 'EndColumn'.
                     */

                    SourceRangeEntry range = (SourceRangeEntry) LineNumbers [i].SourceRange;
                    /*
                     * We use some optimization here: since the start and end lines are usually
                     * close together, we use relative values, so we can encode it as a single-byte
                     * even for large source files.
                     */
                    bw.WriteLeb128 (range.StartLine - last_line);
                    bw.WriteLeb128 (range.EndLine - range.StartLine);
                    bw.WriteLeb128 (range.StartColumn);
                    bw.WriteLeb128 (range.EndColumn);

                    long tmp_size = bw.BaseStream.Position - tmp_offset - 1;
                    long tmp_end = bw.BaseStream.Position;
                    bw.BaseStream.Position = tmp_offset;
                    bw.Write ((byte) tmp_size);
                    bw.BaseStream.Position = tmp_end;
                }
            #endif

                if (offset_inc >= MaxAddressIncrement) {
                    if (offset_inc < 2 * MaxAddressIncrement) {
                        bw.Write (DW_LNS_const_add_pc);
                        offset_inc -= MaxAddressIncrement;
                    } else {
                        bw.Write (DW_LNS_advance_pc);
                        bw.WriteLeb128 (offset_inc);
                        offset_inc = 0;
                    }
                }

                if ((line_inc < LineBase) || (line_inc >= LineBase + LineRange)) {
                    bw.Write (DW_LNS_advance_line);
                    bw.WriteLeb128 (line_inc);
                    if (offset_inc != 0) {
                        bw.Write (DW_LNS_advance_pc);
                        bw.WriteLeb128 (offset_inc);
                    }
                    bw.Write (DW_LNS_copy);
                } else {
                    byte opcode;
                    opcode = (byte) (line_inc - LineBase + (LineRange * offset_inc) +
                             OpcodeBase);
                    bw.Write (opcode);
                }

                last_line = LineNumbers [i].Row;
                last_offset = LineNumbers [i].Offset;
            }

            bw.Write ((byte) 0);
            bw.Write ((byte) 1);
            bw.Write (DW_LNE_end_sequence);

            file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start;
        }

Usage Example

Example #1
0
        internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw)
        {
            if (index <= 0)
            {
                throw new InvalidOperationException();
            }

            LocalVariableTableOffset = (int)bw.BaseStream.Position;
            int num_locals = locals != null ? locals.Length : 0;

            bw.WriteLeb128(num_locals);
            for (int i = 0; i < num_locals; i++)
            {
                locals [i].Write(file, bw);
            }
            file.LocalCount += num_locals;

            CodeBlockTableOffset = (int)bw.BaseStream.Position;
            int num_code_blocks = code_blocks != null ? code_blocks.Length : 0;

            bw.WriteLeb128(num_code_blocks);
            for (int i = 0; i < num_code_blocks; i++)
            {
                code_blocks [i].Write(bw);
            }

            ScopeVariableTableOffset = (int)bw.BaseStream.Position;
            int num_scope_vars = scope_vars != null ? scope_vars.Length : 0;

            bw.WriteLeb128(num_scope_vars);
            for (int i = 0; i < num_scope_vars; i++)
            {
                scope_vars [i].Write(bw);
            }

            if (real_name != null)
            {
                RealNameOffset = (int)bw.BaseStream.Position;
                bw.Write(real_name);
            }

            LineNumberTableOffset = (int)bw.BaseStream.Position;
            lnt.Write(file, bw);

            DataOffset = (int)bw.BaseStream.Position;

            bw.WriteLeb128(CompileUnitIndex);
            bw.WriteLeb128(LocalVariableTableOffset);
            bw.WriteLeb128(NamespaceID);

            bw.WriteLeb128(CodeBlockTableOffset);
            bw.WriteLeb128(ScopeVariableTableOffset);

            bw.WriteLeb128(RealNameOffset);
            bw.WriteLeb128((int)flags);
        }