/// <summary>
        /// Verifies and inserts a instruction into the collection that references a metadata member by its token.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="token">The token of the referenced member.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a metadata member.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// Occurs when the provided token is not valid in a CIL stream.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, MetadataToken token)
        {
            switch (code.OperandType)
            {
            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
            case CilOperandType.InlineString:
                break;

            default:
                throw new InvalidCilInstructionException(code);
            }

            switch (token.Table)
            {
            case TableIndex.TypeRef:
            case TableIndex.TypeDef:
            case TableIndex.TypeSpec:
            case TableIndex.Field:
            case TableIndex.Method:
            case TableIndex.MethodSpec:
            case TableIndex.MemberRef:
            case TableIndex.StandAloneSig:
            case (TableIndex)0x70:
                break;

            default:
                throw new InvalidCilInstructionException(code);
            }

            return(InsertAndReturn(index, code, token));
        }
        private CilInstruction InsertAndReturn(int index, CilOpCode code, object operand = null)
        {
            var instruction = new CilInstruction(code, operand);

            Insert(index, instruction);
            return(instruction);
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that references a standalone signature.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="signature">The referenced signature.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a standalone signature.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, StandAloneSignature signature)
        {
            if (code.OperandType != CilOperandType.InlineSig)
            {
                throw new InvalidCilInstructionException(code);
            }

            return(InsertAndReturn(index, code, signature));
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that references a float64 constant.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="constant">The constant to push.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a float64 constant.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, double constant)
        {
            if (code.OperandType != CilOperandType.InlineR)
            {
                throw new InvalidCilInstructionException(code);
            }

            return(InsertAndReturn(index, code, constant));
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that pushes an integer constant.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="constant">The constant to push.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing an integer constant.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, int constant)
        {
            object operand = code.OperandType switch
            {
                CilOperandType.InlineI => constant,
                CilOperandType.ShortInlineI => (sbyte)constant,
                _ => throw new InvalidCilInstructionException(code)
            };

            return(InsertAndReturn(index, code, operand));
        }
        /// <summary>
        /// Verifies and inserts a switch instruction into the collection.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The switch opcode.</param>
        /// <param name="labels">The labels referenced by the switch instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not a branch opcode.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="labels"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, IEnumerable <ICilLabel> labels)
        {
            if (code.OperandType != CilOperandType.InlineSwitch)
            {
                throw new InvalidCilInstructionException(code);
            }
            if (labels is null)
            {
                throw new ArgumentNullException(nameof(labels));
            }

            return(InsertAndReturn(index, code, labels.ToList()));
        }
        /// <summary>
        /// Verifies and inserts a branch instruction into the collection.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The branch opcode.</param>
        /// <param name="label">The label referenced by the branch instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not a branch opcode.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="label"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, ICilLabel label)
        {
            if (code.OperandType != CilOperandType.InlineBrTarget && code.OperandType != CilOperandType.ShortInlineBrTarget)
            {
                throw new InvalidCilInstructionException(code);
            }
            if (label is null)
            {
                throw new ArgumentNullException(nameof(label));
            }

            return(InsertAndReturn(index, code, label));
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that references a parameter.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="parameter">The referenced parameter.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a parameter.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="parameter"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, Parameter parameter)
        {
            if (code.OperandType != CilOperandType.InlineArgument && code.OperandType != CilOperandType.ShortInlineArgument)
            {
                throw new InvalidCilInstructionException(code);
            }

            if (parameter is null)
            {
                throw new ArgumentNullException(nameof(parameter));
            }

            return(InsertAndReturn(index, code, parameter));
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that references a local variable.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="variable">The referenced variable.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a variable.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="variable"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, CilLocalVariable variable)
        {
            if (code.OperandType != CilOperandType.InlineVar && code.OperandType != CilOperandType.ShortInlineVar)
            {
                throw new InvalidCilInstructionException(code);
            }

            if (variable is null)
            {
                throw new ArgumentNullException(nameof(variable));
            }

            return(InsertAndReturn(index, code, variable));
        }
        /// <summary>
        /// Verifies and inserts an instruction into the collection that references a type.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The type opcode.</param>
        /// <param name="type">The type referenced by the instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not a type opcode.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="type"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, ITypeDefOrRef type)
        {
            if (code.OperandType != CilOperandType.InlineType && code.OperandType != CilOperandType.InlineTok)
            {
                throw new InvalidCilInstructionException(code);
            }

            if (type is null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            return(InsertAndReturn(index, code, type));
        }
        /// <summary>
        /// Verifies and inserts a instruction into the collection that pushes a string constant.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The opcode.</param>
        /// <param name="constant">The constant to push.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not an opcode referencing a string constant.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="constant"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, string constant)
        {
            if (code.OperandType != CilOperandType.InlineString)
            {
                throw new InvalidCilInstructionException(code);
            }

            if (constant is null)
            {
                throw new ArgumentNullException(nameof(constant));
            }

            return(InsertAndReturn(index, code, constant));
        }
        /// <summary>
        /// Verifies and inserts an instruction into the collection that references a method.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The method opcode.</param>
        /// <param name="method">The method referenced by the instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not a method opcode.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="method"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, IMethodDescriptor method)
        {
            if (code.OperandType != CilOperandType.InlineMethod && code.OperandType != CilOperandType.InlineTok)
            {
                throw new InvalidCilInstructionException(code);
            }

            if (method is null)
            {
                throw new ArgumentNullException(nameof(method));
            }

            return(InsertAndReturn(index, code, method));
        }
        /// <summary>
        /// Verifies and inserts an instruction into the collection that references a member.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The member opcode.</param>
        /// <param name="member">The member referenced by the instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation does not match with the provided member reference.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="member"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, MemberReference member)
        {
            if (member is null)
            {
                throw new ArgumentNullException(nameof(member));
            }

            switch (code.OperandType)
            {
            case CilOperandType.InlineField when member.IsField:
            case CilOperandType.InlineMethod when member.IsMethod:
            case CilOperandType.InlineTok:
                break;

            default:
                throw new InvalidCilInstructionException(code);
            }

            return(InsertAndReturn(index, code, member));
        }
        /// <summary>
        /// Verifies and inserts an instruction into the collection that references a metadata member.
        /// </summary>
        /// <param name="index">The zero-based index at which the instruction should be inserted at.</param>
        /// <param name="code">The method opcode.</param>
        /// <param name="member">The member referenced by the instruction.</param>
        /// <returns>The created instruction.</returns>
        /// <exception cref="InvalidCilInstructionException">
        /// Occurs when the provided operation is not a member opcode.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// Occurs when <paramref name="member"/> is null.
        /// </exception>
        public CilInstruction Insert(int index, CilOpCode code, IMetadataMember member)
        {
            switch (code.OperandType)
            {
            case CilOperandType.InlineField:
            case CilOperandType.InlineMethod:
            case CilOperandType.InlineSig:
            case CilOperandType.InlineTok:
            case CilOperandType.InlineType:
                break;

            default:
                throw new InvalidCilInstructionException(code);
            }

            if (member is null)
            {
                throw new ArgumentNullException(nameof(member));
            }

            return(InsertAndReturn(index, code, member));
        }
 public CilInstruction Add(CilOpCode code, long constant) => Insert(Count, code, constant);
 public CilInstruction Add(CilOpCode code, IEnumerable <ICilLabel> labels) => Insert(Count, code, labels);
 public CilInstruction Add(CilOpCode code, params ICilLabel[] labels) =>
 Insert(Count, code, (IEnumerable <ICilLabel>)labels);
 public CilInstruction Add(CilOpCode code, ICilLabel label) => Insert(Count, code, label);
 public CilInstruction Add(CilOpCode code, MetadataToken token) => Insert(Count, code, token);
 public CilInstruction Add(CilOpCode code, StandAloneSignature signature) => Insert(Count, code, signature);
 public CilInstruction Add(CilOpCode code, IMetadataMember member) => Insert(Count, code, member);
Exemplo n.º 22
0
 public SimpleOpCodeRecompiler(CilOpCode newOpCode, params ILCode[] opCodes)
     : this(new[] { CilInstruction.Create(newOpCode) }, opCodes.AsEnumerable())
 {
 }
Exemplo n.º 23
0
 public CilInstructionExpression(CilOpCode opCode, object operand, IEnumerable <CilExpression> arguments)
     : this(new[] { new CilInstruction(0, opCode, operand) }, arguments)
 {
 }
Exemplo n.º 24
0
 public CilInstructionExpression(CilOpCode opCode, object operand)
     : this(opCode, operand, Enumerable.Empty <CilExpression>())
 {
 }
Exemplo n.º 25
0
 public CilInstructionExpression(CilOpCode opCode)
     : this(opCode, null, Enumerable.Empty <CilExpression>())
 {
 }
 public CilInstruction Add(CilOpCode code, ITypeDefOrRef type) => Insert(Count, code, type);
Exemplo n.º 27
0
 public CilInstructionExpression(CilOpCode opCode, object operand, params CilExpression[] arguments)
     : this(opCode, operand, arguments.AsEnumerable())
 {
 }
 public CilInstruction Add(CilOpCode code, IMethodDescriptor method) => Insert(Count, code, method);
 /// <summary>
 /// Creates a new instance of the <see cref="InvalidCilInstructionException"/> class.
 /// </summary>
 /// <param name="code">The operation code that was attempted to create an instruction with.</param>
 public InvalidCilInstructionException(CilOpCode code)
     : base(code.OperandType == CilOperandType.InlineNone
         ? $"Operation code {code.Mnemonic} cannot have an operand."
         : $"Operation code {code.Mnemonic} requires an {code.OperandType} operand.")
 {
 }
 public CilInstruction Add(CilOpCode code, MemberReference member) => Insert(Count, code, member);