File: Linker\ParameterHelpers.cs
Web Access
Project: src\src\tools\illink\src\linker\Mono.Linker.csproj (illink)
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
using System;
using ILLink.Shared.TypeSystemProxy;
using Mono.Cecil;
using Mono.Cecil.Cil;
 
namespace Mono.Linker
{
    public static class ParameterHelpers
    {
        public static ParameterIndex GetParameterIndex(MethodDefinition thisMethod, Instruction operation)
        {
            // Thank you Cecil, Operand being a ParameterDefinition instead of an integer,
            // (except for Ldarg_0 - Ldarg_3, where it's null) makes all of this really convenient...
            // NOT.
            Code code = operation.OpCode.Code;
            return code switch
            {
                Code.Ldarg_0
                or Code.Ldarg_1
                or Code.Ldarg_2
                or Code.Ldarg_3
                => GetLdargParamIndex(),
 
                Code.Starg
                or Code.Ldarg
                or Code.Starg_S
                or Code.Ldarg_S
                or Code.Ldarga
                or Code.Ldarga_S
                => GetParamSequence(),
 
                _ => throw new ArgumentException($"{nameof(GetParameterIndex)} expected an ldarg or starg instruction, got {operation.OpCode.Name}")
            };
 
            ParameterIndex GetLdargParamIndex()
            {
                return (ParameterIndex)(code - Code.Ldarg_0);
            }
            ParameterIndex GetParamSequence()
            {
                ParameterDefinition param = (ParameterDefinition)operation.Operand;
                return (ParameterIndex)param.Sequence;
            }
        }
    }
}