This commit is contained in:
jfrijters 2005-08-22 12:42:02 +00:00
Родитель 70758dc307
Коммит 8fbae44122
5 изменённых файлов: 142 добавлений и 29 удалений

Просмотреть файл

@ -440,18 +440,20 @@ public abstract class FileChannelImpl extends FileChannel
{
Stream local = stream;
stream = null;
// HACK don't close stdin because that throws a NotSupportedException (bug in System.IO.__ConsoleStream)
if(local != in.stream)
try
{
try
{
local.Close();
if(false) throw new cli.System.IO.IOException();
}
catch(cli.System.IO.IOException x)
{
throw new IOException(x.getMessage());
}
local.Close();
if(false) throw new cli.System.IO.IOException();
if(false) throw new cli.System.NotSupportedException();
}
catch(cli.System.NotSupportedException _)
{
// FXBUG ignore this, there's a bug in System.IO.__ConsoleStream,
// it throws this exception when you try to close it.
}
catch(cli.System.IO.IOException x)
{
throw new IOException(x.getMessage());
}
}
}

Просмотреть файл

@ -330,7 +330,7 @@ namespace IKVM.Internal
{
if(!IKVM.Internal.JVM.NoStackTraceInfo && linenums != null)
{
AttributeHelper.SetLineNumberTable(mb, linenums.ToArray());
AttributeHelper.SetLineNumberTable(mb, linenums);
}
}

Просмотреть файл

@ -133,7 +133,8 @@ namespace IKVM.Internal
private static ConstructorInfo implementsAttribute;
private static ConstructorInfo throwsAttribute;
private static ConstructorInfo sourceFileAttribute;
private static ConstructorInfo lineNumberTableAttribute;
private static ConstructorInfo lineNumberTableAttribute1;
private static ConstructorInfo lineNumberTableAttribute2;
private static object ParseValue(TypeWrapper tw, string val)
{
@ -772,19 +773,35 @@ namespace IKVM.Internal
typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(sourceFileAttribute, new object[] { filename }));
}
internal static void SetLineNumberTable(MethodBase mb, byte[] table)
internal static void SetLineNumberTable(MethodBase mb, IKVM.Attributes.LineNumberTableAttribute.LineNumberWriter writer)
{
if(lineNumberTableAttribute == null)
object arg;
ConstructorInfo con;
if(writer.Count == 1)
{
lineNumberTableAttribute = typeof(LineNumberTableAttribute).GetConstructor(new Type[] { typeof(byte[]) });
}
if(mb is ConstructorBuilder)
{
((ConstructorBuilder)mb).SetCustomAttribute(new CustomAttributeBuilder(lineNumberTableAttribute, new object[] { table }));
if(lineNumberTableAttribute2 == null)
{
lineNumberTableAttribute2 = typeof(LineNumberTableAttribute).GetConstructor(new Type[] { typeof(ushort) });
}
con = lineNumberTableAttribute2;
arg = (ushort)writer.LineNo;
}
else
{
((MethodBuilder)mb).SetCustomAttribute(new CustomAttributeBuilder(lineNumberTableAttribute, new object[] { table }));
if(lineNumberTableAttribute1 == null)
{
lineNumberTableAttribute1 = typeof(LineNumberTableAttribute).GetConstructor(new Type[] { typeof(byte[]) });
}
con = lineNumberTableAttribute1;
arg = writer.ToArray();
}
if(mb is ConstructorBuilder)
{
((ConstructorBuilder)mb).SetCustomAttribute(new CustomAttributeBuilder(con, new object[] { arg }));
}
else
{
((MethodBuilder)mb).SetCustomAttribute(new CustomAttributeBuilder(con, new object[] { arg }));
}
}
}

Просмотреть файл

@ -49,6 +49,13 @@ namespace IKVM.Attributes
{
private byte[] table;
public LineNumberTableAttribute(ushort lineno)
{
LineNumberWriter w = new LineNumberWriter(1);
w.AddMapping(0, lineno);
table = w.ToArray();
}
public LineNumberTableAttribute(byte[] table)
{
this.table = table;
@ -59,6 +66,7 @@ namespace IKVM.Attributes
private System.IO.MemoryStream stream;
private int prevILOffset;
private int prevLineNum;
private int count;
internal LineNumberWriter(int estimatedCount)
{
@ -67,10 +75,75 @@ namespace IKVM.Attributes
internal void AddMapping(int ilOffset, int linenumber)
{
WritePackedInteger(ilOffset - prevILOffset);
WritePackedInteger(linenumber - prevLineNum);
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++;
}
internal int Count
{
get
{
return count;
}
}
internal int LineNo
{
get
{
return prevLineNum;
}
}
internal byte[] ToArray()
@ -154,17 +227,38 @@ namespace IKVM.Attributes
public int GetLineNumber(int ilOffset)
{
int i = 0;
int prevILOffset = 0;
int prevLineNum = 0;
int line = -1;
for(int i = 0; i < table.Length;)
int prevLineNum = ReadPackedInteger(ref i) + (64 + 50);
int line;
if(prevLineNum > 0)
{
int currILOffset = ReadPackedInteger(ref i) + prevILOffset;
line = prevLineNum;
}
else
{
prevLineNum = 4 * -prevLineNum;
line = -1;
}
while(i < table.Length)
{
byte lead = table[i++];
int deltaPC = lead & 31;
int deltaLineNo = (lead >> 5) - 2;
if(deltaPC == 31)
{
deltaPC = ReadPackedInteger(ref i) + (64 + 31);
}
if(deltaLineNo == 5)
{
deltaLineNo = ReadPackedInteger(ref i);
}
int currILOffset = prevILOffset + deltaPC;
if(currILOffset > ilOffset)
{
return line;
}
line = ReadPackedInteger(ref i) + prevLineNum;
line = prevLineNum + deltaLineNo;
prevILOffset = currILOffset;
prevLineNum = line;
}

Просмотреть файл

@ -844,7 +844,7 @@ class Compiler
}
if(c.lineNumbers != null)
{
AttributeHelper.SetLineNumberTable(mw.GetMethod(), c.lineNumbers.ToArray());
AttributeHelper.SetLineNumberTable(mw.GetMethod(), c.lineNumbers);
}
// HACK because of the bogus Leave instruction that Reflection.Emit generates, this location
// sometimes appears reachable (it isn't), so we emit a bogus branch to keep the verifier happy.