Ejemplo n.º 1
0
        bool TryValidateSkipCount(LocalFunctionInfo info, out int skipCount)
        {
            skipCount = 0;
            var localFunction = info.Definition;

            if (localFunction.Method.TypeParameters.Count == 0)
            {
                return(true);
            }
            var parentMethod = ((ILFunction)localFunction.Parent).Method;
            var method       = localFunction.Method;

            skipCount = parentMethod.DeclaringType.TypeParameterCount - method.DeclaringType.TypeParameterCount;

            if (skipCount > 0)
            {
                return(false);
            }
            skipCount += parentMethod.TypeParameters.Count;
            if (skipCount < 0 || skipCount > method.TypeArguments.Count)
            {
                return(false);
            }

            if (skipCount > 0)
            {
#if DEBUG
                foreach (var useSite in info.UseSites)
                {
                    var callerMethod = useSite.Ancestors.OfType <ILFunction>().First().Method;
                    callerMethod = callerMethod.ReducedFrom ?? callerMethod;
                    IMethod m;
                    switch (useSite)
                    {
                    case NewObj newObj:
                        m = ((LdFtn)newObj.Arguments[1]).Method;
                        break;

                    case CallInstruction call:
                        m = call.Method;
                        break;

                    case LdFtn fnptr:
                        m = fnptr.Method;
                        break;

                    default:
                        throw new NotSupportedException();
                    }
                    var totalSkipCount    = skipCount + m.DeclaringType.TypeParameterCount;
                    var methodSkippedArgs = m.DeclaringType.TypeArguments.Concat(m.TypeArguments).Take(totalSkipCount);
                    Debug.Assert(methodSkippedArgs.SequenceEqual(callerMethod.DeclaringType.TypeArguments.Concat(callerMethod.TypeArguments).Take(totalSkipCount)));
                    Debug.Assert(methodSkippedArgs.All(p => p.Kind == TypeKind.TypeParameter));
                    Debug.Assert(methodSkippedArgs.Select(p => p.Name).SequenceEqual(m.DeclaringType.TypeParameters.Concat(m.TypeParameters).Take(totalSkipCount).Select(p => p.Name)));
                }
#endif
            }
            return(true);
        }
Ejemplo n.º 2
0
        bool TryValidateSkipCount(LocalFunctionInfo info, out int skipCount)
        {
            skipCount = 0;
            var localFunction = info.Definition;

            if (localFunction.Method.TypeParameters.Count == 0)
            {
                return(true);
            }
            var parentMethod = ((ILFunction)localFunction.Parent).Method;
            var method       = localFunction.Method;

            skipCount = parentMethod.DeclaringType.TypeParameterCount - method.DeclaringType.TypeParameterCount;

            if (skipCount > 0)
            {
                return(false);
            }
            skipCount += parentMethod.TypeParameters.Count;
            if (skipCount < 0 || skipCount > method.TypeArguments.Count)
            {
                return(false);
            }

            if (skipCount > 0)
            {
#if DEBUG
                foreach (var useSite in info.UseSites)
                {
                    var callerMethod = useSite.Ancestors.OfType <ILFunction>().First().Method;
                    callerMethod = callerMethod.ReducedFrom ?? callerMethod;
                    IMethod method0;
                    if (useSite.OpCode == OpCode.NewObj)
                    {
                        method0 = ((LdFtn)useSite.Arguments[1]).Method;
                    }
                    else
                    {
                        method0 = useSite.Method;
                    }
                    var totalSkipCount    = skipCount + method0.DeclaringType.TypeParameterCount;
                    var methodSkippedArgs = method0.DeclaringType.TypeArguments.Concat(method0.TypeArguments).Take(totalSkipCount);
                    Debug.Assert(methodSkippedArgs.SequenceEqual(callerMethod.DeclaringType.TypeArguments.Concat(callerMethod.TypeArguments).Take(totalSkipCount)));
                    Debug.Assert(methodSkippedArgs.All(p => p.Kind == TypeKind.TypeParameter));
                    Debug.Assert(methodSkippedArgs.Select(p => p.Name).SequenceEqual(method0.DeclaringType.TypeParameters.Concat(method0.TypeParameters).Take(totalSkipCount).Select(p => p.Name)));
                }
#endif
            }
            return(true);
        }
Ejemplo n.º 3
0
 private ILInstruction FindCompatibleArgument(LocalFunctionInfo info, IList <ILInstruction> arguments, bool ignoreStructure = false)
 {
     foreach (var arg in arguments)
     {
         if (arg is IInstructionWithVariableOperand ld2 && (ignoreStructure || info.Definition.IsDescendantOf(ld2.Variable.Function)))
         {
             return(arg);
         }
         var v = ResolveAncestorScopeReference(arg);
         if (v != null)
         {
             return(new LdLoc(v));
         }
     }
     return(null);
 }