static void ParseCode(int code_size, ParseContext context)
{
var code = context.Code;
var metadata = context.Metadata;
var visitor = context.Visitor;
var start = code.Position;
var end = start + code_size;
while (code.Position < end) {
var il_opcode = code.ReadByte ();
var opcode = il_opcode != 0xfe
? OpCodes.OneByteOpCode [il_opcode]
: OpCodes.TwoBytesOpCode [code.ReadByte ()];
switch (opcode.OperandType) {
case OperandType.InlineNone:
visitor.OnInlineNone (opcode);
break;
case OperandType.InlineSwitch:
var length = code.ReadInt32 ();
var branches = new int [length];
for (int i = 0; i < length; i++)
branches [i] = code.ReadInt32 ();
visitor.OnInlineSwitch (opcode, branches);
break;
case OperandType.ShortInlineBrTarget:
visitor.OnInlineBranch (opcode, code.ReadSByte ());
break;
case OperandType.InlineBrTarget:
visitor.OnInlineBranch (opcode, code.ReadInt32 ());
break;
case OperandType.ShortInlineI:
if (opcode == OpCodes.Ldc_I4_S)
visitor.OnInlineSByte (opcode, code.ReadSByte ());
else
visitor.OnInlineByte (opcode, code.ReadByte ());
break;
case OperandType.InlineI:
visitor.OnInlineInt32 (opcode, code.ReadInt32 ());
break;
case OperandType.InlineI8:
visitor.OnInlineInt64 (opcode, code.ReadInt64 ());
break;
case OperandType.ShortInlineR:
visitor.OnInlineSingle (opcode, code.ReadSingle ());
break;
case OperandType.InlineR:
visitor.OnInlineDouble (opcode, code.ReadDouble ());
break;
case OperandType.InlineSig:
visitor.OnInlineSignature (opcode, code.GetCallSite (code.ReadToken ()));
break;
case OperandType.InlineString:
visitor.OnInlineString (opcode, code.GetString (code.ReadToken ()));
break;
case OperandType.ShortInlineArg:
visitor.OnInlineArgument (opcode, code.GetParameter (code.ReadByte ()));
break;
case OperandType.InlineArg:
visitor.OnInlineArgument (opcode, code.GetParameter (code.ReadInt16 ()));
break;
case OperandType.ShortInlineVar:
visitor.OnInlineVariable (opcode, GetVariable (context, code.ReadByte ()));
break;
case OperandType.InlineVar:
visitor.OnInlineVariable (opcode, GetVariable (context, code.ReadInt16 ()));
break;
case OperandType.InlineTok:
case OperandType.InlineField:
case OperandType.InlineMethod:
case OperandType.InlineType:
var member = metadata.LookupToken (code.ReadToken ());
switch (member.MetadataToken.TokenType) {
case TokenType.TypeDef:
case TokenType.TypeRef:
case TokenType.TypeSpec:
visitor.OnInlineType (opcode, (TypeReference) member);
break;
case TokenType.Method:
case TokenType.MethodSpec:
visitor.OnInlineMethod (opcode, (MethodReference) member);
break;
case TokenType.Field:
visitor.OnInlineField (opcode, (FieldReference) member);
break;
case TokenType.MemberRef:
var field_ref = member as FieldReference;
if (field_ref != null) {
visitor.OnInlineField (opcode, field_ref);
break;
}
var method_ref = member as MethodReference;
if (method_ref != null) {
visitor.OnInlineMethod (opcode, method_ref);
break;
}
throw new InvalidOperationException ();
}
break;
}
}
}