-
Notifications
You must be signed in to change notification settings - Fork 220
/
Copy pathLineNumberWriter.cs
140 lines (133 loc) · 3.84 KB
/
LineNumberWriter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ILRepacking
{
// copied from IKVM source
internal sealed class LineNumberWriter
{
private System.IO.MemoryStream stream;
private int prevILOffset;
private int prevLineNum;
private int count;
public LineNumberWriter(int estimatedCount)
{
stream = new System.IO.MemoryStream(estimatedCount * 2);
}
public void AddMapping(int ilOffset, int linenumber)
{
if (count == 0)
{
if (ilOffset == 0 && linenumber != 0)
{
prevLineNum = linenumber;
count++;
WritePackedInteger(linenumber - (64 + 50));
return;
}
else
{
prevLineNum = linenumber & ~3;
WritePackedInteger(((-prevLineNum / 4) - (64 + 50)));
}
}
bool pc_overflow;
bool lineno_overflow;
byte lead;
int deltaPC = ilOffset - prevILOffset;
if (deltaPC >= 0 && deltaPC < 31)
{
lead = (byte)deltaPC;
pc_overflow = false;
}
else
{
lead = (byte)31;
pc_overflow = true;
}
int deltaLineNo = linenumber - prevLineNum;
const int bias = 2;
if (deltaLineNo >= -bias && deltaLineNo < 7 - bias)
{
lead |= (byte)((deltaLineNo + bias) << 5);
lineno_overflow = false;
}
else
{
lead |= (byte)(7 << 5);
lineno_overflow = true;
}
stream.WriteByte(lead);
if (pc_overflow)
{
WritePackedInteger(deltaPC - (64 + 31));
}
if (lineno_overflow)
{
WritePackedInteger(deltaLineNo);
}
prevILOffset = ilOffset;
prevLineNum = linenumber;
count++;
}
public int Count
{
get
{
return count;
}
}
public int LineNo
{
get
{
return prevLineNum;
}
}
public byte[] ToArray()
{
return stream.ToArray();
}
/*
* packed integer format:
* ----------------------
*
* First byte:
* 00 - 7F Single byte integer (-64 - 63)
* 80 - BF Double byte integer (-8192 - 8191)
* C0 - DF Triple byte integer (-1048576 - 1048576)
* E0 - FE Reserved
* FF Five byte integer
*/
private void WritePackedInteger(int val)
{
if (val >= -64 && val < 64)
{
val += 64;
stream.WriteByte((byte)val);
}
else if (val >= -8192 && val < 8192)
{
val += 8192;
stream.WriteByte((byte)(0x80 + (val >> 8)));
stream.WriteByte((byte)val);
}
else if (val >= -1048576 && val < 1048576)
{
val += 1048576;
stream.WriteByte((byte)(0xC0 + (val >> 16)));
stream.WriteByte((byte)(val >> 8));
stream.WriteByte((byte)val);
}
else
{
stream.WriteByte(0xFF);
stream.WriteByte((byte)(val >> 24));
stream.WriteByte((byte)(val >> 16));
stream.WriteByte((byte)(val >> 8));
stream.WriteByte((byte)(val >> 0));
}
}
}
}