private static object ResolveOperand(CilMethodBody methodBody, CilInstruction instruction, ICilOperandResolver resolver) { switch (instruction.OpCode.OperandType) { case CilOperandType.InlineBrTarget: case CilOperandType.ShortInlineBrTarget: return new CilInstructionLabel( methodBody.Instructions.GetByOffset(((ICilLabel) instruction.Operand).Offset)); case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: return resolver.ResolveMember((MetadataToken) instruction.Operand); case CilOperandType.InlineString: return resolver.ResolveString((MetadataToken) instruction.Operand); case CilOperandType.InlineSwitch: var result = new List<ICilLabel>(); var labels = (IEnumerable<ICilLabel>) instruction.Operand; foreach (var label in labels) { var target = methodBody.Instructions.GetByOffset(label.Offset); result.Add(target == null ? label : new CilInstructionLabel(target)); } return result; case CilOperandType.InlineVar: case CilOperandType.ShortInlineVar: return resolver.ResolveLocalVariable(Convert.ToInt32(instruction.Operand)); case CilOperandType.InlineArgument: case CilOperandType.ShortInlineArgument: return resolver.ResolveParameter(Convert.ToInt32(instruction.Operand)); case CilOperandType.InlineI: case CilOperandType.InlineI8: case CilOperandType.InlineNone: case CilOperandType.InlineR: case CilOperandType.ShortInlineI: case CilOperandType.ShortInlineR: return instruction.Operand; case CilOperandType.InlinePhi: throw new NotSupportedException(); default: throw new ArgumentOutOfRangeException(); } }
private object ReadOperand(CilOperandType operandType) { switch (operandType) { case CilOperandType.InlineNone: return(null); case CilOperandType.ShortInlineI: return(_reader.ReadSByte()); case CilOperandType.ShortInlineBrTarget: return(new CilOffsetLabel(_reader.ReadSByte() + (int)(_reader.Offset - _reader.StartOffset))); case CilOperandType.ShortInlineVar: byte shortLocalIndex = _reader.ReadByte(); return(_operandResolver?.ResolveLocalVariable(shortLocalIndex) ?? shortLocalIndex); case CilOperandType.ShortInlineArgument: byte shortArgIndex = _reader.ReadByte(); return(_operandResolver?.ResolveParameter(shortArgIndex) ?? shortArgIndex); case CilOperandType.InlineVar: ushort longLocalIndex = _reader.ReadUInt16(); return(_operandResolver?.ResolveLocalVariable(longLocalIndex) ?? longLocalIndex); case CilOperandType.InlineArgument: ushort longArgIndex = _reader.ReadUInt16(); return(_operandResolver?.ResolveParameter(longArgIndex) ?? longArgIndex); case CilOperandType.InlineI: return(_reader.ReadInt32()); case CilOperandType.InlineBrTarget: return(new CilOffsetLabel(_reader.ReadInt32() + (int)(_reader.Offset - _reader.StartOffset))); case CilOperandType.ShortInlineR: return(_reader.ReadSingle()); case CilOperandType.InlineI8: return(_reader.ReadInt64()); case CilOperandType.InlineR: return(_reader.ReadDouble()); case CilOperandType.InlineString: var stringToken = new MetadataToken(_reader.ReadUInt32()); return(_operandResolver?.ResolveString(stringToken) ?? stringToken); case CilOperandType.InlineField: case CilOperandType.InlineMethod: case CilOperandType.InlineSig: case CilOperandType.InlineTok: case CilOperandType.InlineType: var memberToken = new MetadataToken(_reader.ReadUInt32()); return(_operandResolver?.ResolveMember(memberToken) ?? memberToken); case CilOperandType.InlinePhi: throw new NotSupportedException(); case CilOperandType.InlineSwitch: return(ReadSwitchTable()); default: throw new ArgumentOutOfRangeException(nameof(operandType), operandType, null); } }