示例#1
0
        internal static FindResult CanExtendNamedArgument(Block block, ILVariable v, ILInstruction expressionBeingMoved)
        {
            Debug.Assert(block.Kind == BlockKind.CallWithNamedArgs);
            var firstArg = ((StLoc)block.Instructions[0]).Value;
            var r        = ILInlining.FindLoadInNext(firstArg, v, expressionBeingMoved, InliningOptions.IntroduceNamedArguments);

            if (r.Type == FindResultType.Found || r.Type == FindResultType.NamedArgument)
            {
                return(r);                // OK, inline into first instruction of block
            }
            var call = (CallInstruction)block.FinalInstruction;

            if (call.IsInstanceCall)
            {
                // For instance calls, block.Instructions[0] is the argument
                // for the 'this' pointer. We can only insert at position 1.
                if (r.Type == FindResultType.Stop)
                {
                    // error: can't move expressionBeingMoved after block.Instructions[0]
                    return(FindResult.Stop);
                }
                // Because we always ensure block.Instructions[0] is the 'this' argument,
                // it's possible that the place we actually need to inline into
                // is within block.Instructions[1]:
                if (block.Instructions.Count > 1)
                {
                    r = ILInlining.FindLoadInNext(block.Instructions[1], v, expressionBeingMoved, InliningOptions.IntroduceNamedArguments);
                    if (r.Type == FindResultType.Found || r.Type == FindResultType.NamedArgument)
                    {
                        return(r);                        // OK, inline into block.Instructions[1]
                    }
                }
            }
            foreach (var arg in call.Arguments)
            {
                if (arg.MatchLdLoc(v))
                {
                    return(FindResult.NamedArgument(arg, arg));
                }
            }
            return(FindResult.Stop);
        }
示例#2
0
 internal static FindResult CanIntroduceNamedArgument(CallInstruction call, ILInstruction child, ILVariable v, ILInstruction expressionBeingMoved)
 {
     Debug.Assert(child.Parent == call);
     if (call.IsInstanceCall && child.ChildIndex == 0)
     {
         return(FindResult.Stop);                // cannot use named arg to move expressionBeingMoved before this pointer
     }
     if (call.Method.IsOperator || call.Method.IsAccessor)
     {
         return(FindResult.Stop);                // cannot use named arg for operators or accessors
     }
     if (call.Method is VarArgInstanceMethod)
     {
         return(FindResult.Stop);                // CallBuilder doesn't support named args when using varargs
     }
     if (call.Method.IsConstructor)
     {
         IType type = call.Method.DeclaringType;
         if (type.Kind == TypeKind.Delegate || type.IsAnonymousType())
         {
             return(FindResult.Stop);
         }
     }
     if (call.Method.Parameters.Any(p => string.IsNullOrEmpty(p.Name)))
     {
         return(FindResult.Stop);                // cannot use named arguments
     }
     for (int i = child.ChildIndex; i < call.Arguments.Count; i++)
     {
         var r = ILInlining.FindLoadInNext(call.Arguments[i], v, expressionBeingMoved, InliningOptions.None);
         if (r.Type == FindResultType.Found)
         {
             return(FindResult.NamedArgument(r.LoadInst, call.Arguments[i]));
         }
     }
     return(FindResult.Stop);
 }