public override Instruction Read() { var initialPosition = Position; Instruction result; if (!instructions.TryGetValue(initialPosition, out result)) { instructions.Add(initialPosition, result = new Instruction()); } try { short opcode = reader.ReadByte(); if (opcode > 0xfe) { opcode = unchecked ((short)((opcode << 8) | reader.ReadByte())); } result.OpCode = AllOpCodes[opcode]; } catch (EndOfStreamException) { return(null); } switch (result.OpCode.OperandType) { case OperandType.InlineBrTarget: result.Operand = FindLabel(initialPosition + result.OpCode.Size + 4 + reader.ReadInt32()); break; case OperandType.ShortInlineBrTarget: result.Operand = FindLabel(initialPosition + result.OpCode.Size + 1 + reader.ReadSByte()); break; case OperandType.InlineField: result.Operand = module.ResolveField(reader.ReadInt32(), genericTypeArguments, genericMethodArguments); break; case OperandType.InlineMethod: result.Operand = module.ResolveMethod(reader.ReadInt32(), genericTypeArguments, genericMethodArguments); break; case OperandType.InlineType: result.Operand = module.ResolveType(reader.ReadInt32(), genericTypeArguments, genericMethodArguments); break; case OperandType.InlineString: result.Operand = module.ResolveString(reader.ReadInt32()); break; case OperandType.InlineSig: result.Operand = module.ResolveSignature(reader.ReadInt32()); break; case OperandType.InlineTok: result.Operand = module.ResolveMember(reader.ReadInt32(), genericTypeArguments, genericMethodArguments); break; case OperandType.InlineSwitch: var n = reader.ReadInt32(); var targets = new Instruction[n]; for (int i = 0; i < targets.Length; i++) { targets[i] = FindLabel(initialPosition + reader.ReadInt32()); } result.Operand = targets; break; case OperandType.InlineVar: result.Operand = reader.ReadInt16(); break; case OperandType.ShortInlineVar: case OperandType.ShortInlineI: result.Operand = reader.ReadSByte(); break; case OperandType.InlineI: result.Operand = reader.ReadInt32(); break; case OperandType.InlineI8: result.Operand = reader.ReadInt64(); break; case OperandType.InlineNone: break; case OperandType.InlineR: result.Operand = reader.ReadDouble(); break; case OperandType.ShortInlineR: result.Operand = reader.ReadSingle(); break; default: throw new NotSupportedException(); } Func <object, int> variableIndex; if (VariableIndexes.TryGetValue(result.OpCode, out variableIndex)) { result.Operand = Variables[variableIndex(result.Operand)]; } OpCode replacement; if (OpCodeReplaces.TryGetValue(result.OpCode, out replacement)) { result.OpCode = replacement; } return(result); }