public void ReadByteCodes(MethodDef meth, uint rva)
{
if (rva == 0) return;
BaseStream.Seek(GetOffset(rva),SeekOrigin.Begin);
CILInstructions instrs = meth.CreateCodeBuffer();
uint formatByte = ReadByte();
uint format = formatByte & 0x3;
if (Diag.DiagOn) Console.WriteLine("code header format = " + Hex.Byte((int)formatByte));
uint size = 0;
if (format == CILInstructions.TinyFormat) {
size = formatByte >> 2;
if (Diag.DiagOn) Console.WriteLine("Tiny Format, code size = " + size);
instrs.SetAndResolveInstructions(DoByteCodes(size,meth));
} else if (format == CILInstructions.FatFormat) {
uint headerSize = ReadByte();
bool initLocals = (formatByte & CILInstructions.InitLocals) != 0;
bool moreSects = (formatByte & CILInstructions.MoreSects) != 0;
meth.SetMaxStack((int)ReadUInt16());
size = ReadUInt32();
if (Diag.DiagOn) Console.WriteLine("Fat Format, code size = " + size);
uint locVarSig = ReadUInt32();
CILInstruction[] instrList = this.DoByteCodes(size,meth);
while (moreSects) {
// find next 4 byte boundary
long currPos = BaseStream.Position;
if (currPos % 4 != 0) {
long pad = 4 - (currPos % 4);
for (int p = 0; p < pad; p++)
ReadByte();
}
uint flags = ReadByte();
//while (flags == 0) flags = ReadByte(); // maximum of 3 to get 4 byte boundary??
moreSects = (flags & CILInstructions.SectMoreSects) != 0;
bool fatSect = (flags & CILInstructions.SectFatFormat) != 0;
if ((flags & CILInstructions.EHTable) == 0)
throw new Exception("Section not an Exception Handler Table");
int sectLen = ReadByte() + (ReadByte() << 8) + (ReadByte() << 16);
int numClauses = sectLen - 4;
if (fatSect)
numClauses /= 24;
else
numClauses /= 12;
for (int i=0; i < numClauses; i++) {
EHClauseType eFlag;
if (fatSect) eFlag = (EHClauseType)ReadUInt32();
else eFlag = (EHClauseType)ReadUInt16();
uint tryOff = 0, tryLen = 0, hOff = 0, hLen = 0;
if (fatSect) {
tryOff = ReadUInt32();
tryLen = ReadUInt32();
hOff = ReadUInt32();
hLen = ReadUInt32();
} else {
tryOff = ReadUInt16();
tryLen = ReadByte();
hOff = ReadUInt16();
hLen = ReadByte();
}
EHClause ehClause = new EHClause(eFlag,tryOff,tryLen,hOff,hLen);
if (eFlag == EHClauseType.Exception)
ehClause.ClassToken(GetTokenElement(ReadUInt32()));
else
ehClause.FilterOffset(ReadUInt32());
instrs.AddEHClause(ehClause);
}
}
if (locVarSig != 0) {
LocalSig lSig = (LocalSig)GetTokenElement(locVarSig);
lSig.Resolve(this,meth);
meth.AddLocals(lSig.GetLocals(),initLocals);
}
instrs.SetAndResolveInstructions(instrList);
} else {
Console.WriteLine("byte code format error");
}
}