public Instruction Create(OpCode opCode)
 {
     try
     {
         var instruction = _il.Create(opCode);
         MethodLocals.MapMacroInstruction(Locals, instruction);
         return(instruction);
     }
     catch (ArgumentException)
     {
         throw ExceptionInvalidOperand(opCode);
     }
 }
    public Instruction CreateConst(OpCode opCode, object operand)
    {
        try
        {
            switch (opCode.OperandType)
            {
            case OperandType.InlineI:
                operand = Convert.ToInt32(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.InlineI8:
                operand = Convert.ToInt64(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.InlineR:
                operand = Convert.ToDouble(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.InlineVar:
            case OperandType.InlineArg:
                // It's an uint16 but Cecil expects int32
                operand = Convert.ToInt32(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.ShortInlineI:
                operand = opCode == OpCodes.Ldc_I4_S
                        ? Convert.ToSByte(operand, CultureInfo.InvariantCulture)
                        : Convert.ToByte(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.ShortInlineR:
                operand = Convert.ToSingle(operand, CultureInfo.InvariantCulture);
                break;

            case OperandType.ShortInlineVar:
            case OperandType.ShortInlineArg:
                operand = Convert.ToByte(operand, CultureInfo.InvariantCulture);
                break;
            }

            switch (operand)
            {
            case int value:
            {
                if (MethodLocals.MapIndexInstruction(Locals, ref opCode, value, out var localVar))
                {
                    return(Create(opCode, localVar));
                }

                return(_il.Create(opCode, value));
            }

            case byte value:
            {
                if (MethodLocals.MapIndexInstruction(Locals, ref opCode, value, out var localVar))
                {
                    return(Create(opCode, localVar));
                }

                return(_il.Create(opCode, value));
            }

            case sbyte value:
                return(_il.Create(opCode, value));

            case long value:
                return(_il.Create(opCode, value));

            case double value:
                return(_il.Create(opCode, value));

            case short value:
                return(_il.Create(opCode, value));

            case float value:
                return(_il.Create(opCode, value));

            case string value:
                return(_il.Create(opCode, value));

            default:
                throw new WeavingException($"Unexpected operand for instruction {opCode}: {operand}");
            }
        }
        catch (ArgumentException)
        {
            throw ExceptionInvalidOperand(opCode);
        }
    }