/// <summary>
/// Constructs the array of ILInstructions according to the IL byte code.
/// </summary>
/// <param name="module"></param>
private void ConstructInstructions(Module module)
{
byte[] il = this.il;
int position = 0;
instructions = new List<ILInstruction>();
while (position < il.Length)
{
ILInstruction instruction = new ILInstruction();
// get the operation code of the current instruction
OpCode code = OpCodes.Nop;
ushort value = il[position++];
if (value != 0xfe)
{
code = Globals.singleByteOpCodes[(int)value];
}
else
{
value = il[position++];
code = Globals.multiByteOpCodes[(int)value];
value = (ushort)(value | 0xfe00);
}
instruction.Code = code;
instruction.Offset = position - 1;
int metadataToken = 0;
// get the operand of the current operation
switch (code.OperandType)
{
case OperandType.InlineBrTarget:
metadataToken = ReadInt32(il, ref position);
metadataToken += position;
instruction.Operand = metadataToken;
break;
// patched from comments on CP -hwd
case OperandType.InlineField:
metadataToken = ReadInt32(il, ref position);
if (mi is ConstructorInfo)
{
instruction.Operand = module.ResolveField(metadataToken,
mi.DeclaringType.GetGenericArguments(), null);
}
else
{
instruction.Operand = module.ResolveField(metadataToken,
mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
}
break;
// patched from comments on CP -hwd
case OperandType.InlineMethod:
metadataToken = ReadInt32(il, ref position);
try
{
if (mi is ConstructorInfo)
{
instruction.Operand = module.ResolveMethod(metadataToken,
mi.DeclaringType.GetGenericArguments(), null);
}
else
{
instruction.Operand = module.ResolveMethod(metadataToken,
mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
}
}
catch
{
if (mi is ConstructorInfo)
{
instruction.Operand = module.ResolveMember(metadataToken,
mi.DeclaringType.GetGenericArguments(), null);
}
else
{
instruction.Operand = module.ResolveMember(metadataToken,
mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
}
}
break;
case OperandType.InlineSig:
metadataToken = ReadInt32(il, ref position);
instruction.Operand = module.ResolveSignature(metadataToken);
break;
// patched from comments on CP -hwd
case OperandType.InlineTok:
metadataToken = ReadInt32(il, ref position);
//try
//{
if (mi is ConstructorInfo)
{
instruction.Operand = module.ResolveType(metadataToken,
mi.DeclaringType.GetGenericArguments(), null);
}
else
{
instruction.Operand = module.ResolveType(metadataToken,
mi.DeclaringType.GetGenericArguments(), mi.GetGenericArguments());
}
//}
//catch
//{
// int i = 1;
//}
break;
// patched from comments on CP -hwd
case OperandType.InlineType:
metadataToken = ReadInt32(il, ref position);
if (this.mi is MethodInfo)
{
instruction.Operand = module.ResolveType(metadataToken,
this.mi.DeclaringType.GetGenericArguments(), this.mi.GetGenericArguments());
}
else if (mi is ConstructorInfo)
{
instruction.Operand = module.ResolveType(metadataToken,
this.mi.DeclaringType.GetGenericArguments(), null);
}
else
{
instruction.Operand = module.ResolveType(metadataToken);
}
break;
case OperandType.InlineI:
{
instruction.Operand = ReadInt32(il, ref position);
break;
}
case OperandType.InlineI8:
{
instruction.Operand = ReadInt64(il, ref position);
break;
}
case OperandType.InlineNone:
{
instruction.Operand = null;
break;
}
case OperandType.InlineR:
{
instruction.Operand = ReadDouble(il, ref position);
break;
}
case OperandType.InlineString:
{
metadataToken = ReadInt32(il, ref position);
instruction.Operand = module.ResolveString(metadataToken);
break;
}
case OperandType.InlineSwitch:
{
int count = ReadInt32(il, ref position);
int[] casesAddresses = new int[count];
for (int i = 0; i < count; i++)
{
casesAddresses[i] = ReadInt32(il, ref position);
}
int[] cases = new int[count];
for (int i = 0; i < count; i++)
{
cases[i] = position + casesAddresses[i];
}
break;
}
case OperandType.InlineVar:
{
instruction.Operand = ReadUInt16(il, ref position);
break;
}
case OperandType.ShortInlineBrTarget:
{
instruction.Operand = ReadSByte(il, ref position) + position;
break;
}
case OperandType.ShortInlineI:
{
instruction.Operand = ReadSByte(il, ref position);
break;
}
case OperandType.ShortInlineR:
{
instruction.Operand = ReadSingle(il, ref position);
break;
}
case OperandType.ShortInlineVar:
{
instruction.Operand = ReadByte(il, ref position);
break;
}
default:
{
throw new Exception("Unknown operand type.");
}
}
instructions.Add(instruction);
}
}