예제 #1
0
        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();
            }
        }
예제 #2
0
        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);
            }
        }