private CILInstruction[] DoByteCodes(uint len, MethodDef thisMeth)
{
uint pos = 0;
ArrayList instrList = new ArrayList();
//int instrIx = 0;
while (pos < len) {
uint offset = pos;
uint opCode = ReadByte();
pos++;
IType iType = IType.op;
if (opCode == 0xFE) {
uint ix = ReadByte();
pos++;
opCode = (opCode << 8) + ix;
iType = FileImage.longInstrMap[ix];
} else
iType = FileImage.instrMap[opCode];
if (Diag.DiagOn) Console.WriteLine("Got instruction type " + iType);
CILInstruction nextInstr = null;
if (iType == IType.specialOp) {
pos += 4;
if (Diag.DiagOn) Console.WriteLine("Got instruction " + Hex.Byte((int)opCode));
switch (opCode) {
case ((int)SpecialOp.ldc_i8) :
nextInstr = new LongInstr((SpecialOp)opCode,ReadInt64());
pos += 4; break;
case ((int)SpecialOp.ldc_r4) :
nextInstr = new FloatInstr((SpecialOp)opCode,ReadSingle());
break;
case ((int)SpecialOp.ldc_r8) :
nextInstr = new DoubleInstr((SpecialOp)opCode,ReadDouble());
pos += 4; break;
case ((int)SpecialOp.calli) :
nextInstr = new SigInstr((SpecialOp)opCode,(CalliSig)GetTokenElement(ReadUInt32()));
break;
case ((int)SpecialOp.Switch) : // switch
uint count = ReadUInt32();
int[] offsets = new int[count];
for (uint i=0; i < count; i++)
offsets[i] = ReadInt32();
pos += (4 * count);
nextInstr = new SwitchInstr(offsets);
break;
case ((int)SpecialOp.ldstr) : // ldstr
uint strIx = ReadUInt32();
strIx = strIx & FileImage.ElementMask;
nextInstr = new StringInstr((SpecialOp)opCode,userstring.GetUserString(strIx));
break;
case ((int)MethodOp.ldtoken) :
MetaDataElement elem = GetTokenElement(ReadUInt32());
if (elem is Method)
nextInstr = new MethInstr((MethodOp)opCode,(Method)elem);
else if (elem is Field)
nextInstr = new FieldInstr((FieldOp)opCode,(Field)elem);
else
nextInstr =new TypeInstr((TypeOp)opCode,(Type)elem);
break;
}
} else if (iType == IType.branchOp) {
if (Diag.DiagOn) Console.WriteLine("Got instruction " + Hex.Byte((int)opCode));
if ((opCode < 0x38) || (opCode == 0xDE)) { // br or leave.s
nextInstr = new BranchInstr(opCode,ReadSByte());
pos++;
} else {
nextInstr = new BranchInstr(opCode,ReadInt32());
pos += 4;
}
} else {
if (Diag.DiagOn) Console.Write(Hex.Byte((int)opCode));
switch (iType) {
case (IType.op) :
if (Diag.DiagOn) Console.WriteLine("Got instruction " + (Op)opCode);
nextInstr = new Instr((Op)opCode); break;
case (IType.methOp) :
if (Diag.DiagOn) Console.WriteLine("Got instruction " + (MethodOp)opCode);
nextInstr = new MethInstr((MethodOp)opCode,(Method)GetTokenElement(ReadUInt32()));
pos += 4;
break;
case (IType.typeOp) :
if (Diag.DiagOn) Console.WriteLine("Got instruction " + (TypeOp)opCode);
uint ttok = ReadUInt32();
Type typeToken = (Type)GetTokenElement(ttok);
if (typeToken is GenericParTypeSpec)
typeToken = ((GenericParTypeSpec)typeToken).GetGenericParam(thisMeth);
nextInstr = new TypeInstr((TypeOp)opCode,typeToken);
pos += 4;
break;
case (IType.fieldOp) :
if (Diag.DiagOn) Console.WriteLine("Got instruction " + (FieldOp)opCode);
nextInstr = new FieldInstr((FieldOp)opCode,(Field)GetTokenElement(ReadUInt32()));
pos += 4;
break;
case (IType.int8Op) :
nextInstr = new IntInstr((IntOp)opCode,ReadSByte());
pos++;
break;
case (IType.uint8Op) :
nextInstr = new UIntInstr((IntOp)opCode,ReadByte());
pos++;
break;
case (IType.uint16Op) :
nextInstr =new UIntInstr((IntOp)opCode,ReadUInt16());
pos++;
break;
case (IType.int32Op) :
nextInstr =new IntInstr((IntOp)opCode,ReadInt32());
pos += 4;
break;
}
}
if (nextInstr != null) nextInstr.Resolve();
instrList.Add(nextInstr);
}
CILInstruction[] instrs = new CILInstruction[instrList.Count];
for (int i=0; i < instrs.Length; i++) {
instrs[i] = (CILInstruction)instrList[i];
}
return instrs;
}