Example #1
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            int firstArgument = (OpCode != OpCode.NewObj && !Method.IsStatic) ? 1 : 0;

            Debug.Assert(Method.Parameters.Count + firstArgument == Arguments.Count);
            Debug.Assert(Method.Parameters.Count + firstArgument == ArgumentToParameterMap.Length);
            if (firstArgument == 1)
            {
                Debug.Assert(Arguments[0].ResultType == ExpectedTypeForThisPointer(ConstrainedTo ?? Method.DeclaringType),
                             $"Stack type mismatch in 'this' argument in call to {Method.Name}()");
                Debug.Assert(ArgumentToParameterMap[0] == -1, "'this' argument must always be mapped at position 0");
            }
            int paramCount = Method.Parameters.Count;

            if (paramCount > 0)
            {
                BitSet bitSet = new BitSet(paramCount);
                for (int i = 0; i < paramCount; ++i)
                {
                    int mappedTo = ArgumentToParameterMap[firstArgument + i];
                    Debug.Assert(mappedTo >= 0 && mappedTo < paramCount, $"mapping out of [0..{paramCount}[, was: {mappedTo}");
                    Debug.Assert(!bitSet[mappedTo], $"argument {mappedTo} is already mapped to a different parameter");
                    bitSet.Set(mappedTo);
                    Debug.Assert(Arguments[firstArgument + i].ResultType == Method.Parameters[mappedTo].Type.GetStackType(),
                                 $"Stack type mismatch in parameter {mappedTo} (argument {firstArgument + i}) in call to {Method.Name}()");
                }
                Debug.Assert(bitSet.All(0, paramCount - 1), "Not all arguments are mapped to a parameter");
            }
        }
Example #2
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(Kind != ConversionKind.Invalid);
     Debug.Assert(Argument.ResultType == (IsLifted ? StackType.O : InputType));
     Debug.Assert(!(IsLifted && Kind == ConversionKind.StopGCTracking));
 }
Example #3
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(valueInst.ResultType == StackType.O);             // lhs is reference type or nullable type
     Debug.Assert(fallbackInst.ResultType == StackType.O || Kind == NullCoalescingKind.NullableWithValueFallback);
     Debug.Assert(ResultType == UnderlyingResultType || Kind == NullCoalescingKind.Nullable);
 }
Example #4
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(variable.Function !));
     Debug.Assert(phase <= ILPhase.InILReader || variable.Function !.Variables[variable.IndexInFunction] == variable);
     Debug.Assert(value.ResultType == variable.StackType);
 }
Example #5
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     // Debug.Assert(Kind != ConversionKind.Invalid); // invalid conversion can happen with invalid IL/missing references
     Debug.Assert(Argument.ResultType == (IsLifted ? StackType.O : InputType));
     Debug.Assert(!(IsLifted && Kind == ConversionKind.StopGCTracking));
 }
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(Parent is TryCatch);
     Debug.Assert(filter.ResultType == StackType.I4);
     Debug.Assert(this.IsDescendantOf(variable.Function));
 }
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            var patternVariables    = new HashSet <ILVariable>();
            var conversionVariables = new HashSet <ILVariable>();

            foreach (StLoc init in this.Init)
            {
                Debug.Assert(init.Variable.IsSingleDefinition && init.Variable.LoadCount == 1);
                Debug.Assert(init.Variable.LoadInstructions[0].IsDescendantOf(assignments));
            }

            ValidatePattern(pattern);

            foreach (var inst in this.conversions.Instructions)
            {
                if (!IsConversionStLoc(inst, out var variable, out var inputVariable))
                {
                    Debug.Fail("inst is not a conversion stloc!");
                }
                Debug.Assert(variable.IsSingleDefinition && variable.LoadCount == 1);
                Debug.Assert(variable.LoadInstructions[0].IsDescendantOf(assignments));
                Debug.Assert(patternVariables.Contains(inputVariable));
                conversionVariables.Add(variable);
            }
            Debug.Assert(this.conversions.FinalInstruction is Nop);

            foreach (var inst in assignments.Instructions)
            {
                if (!(IsAssignment(inst, typeSystem: null, out _, out var value) && value.MatchLdLoc(out var inputVariable)))
                {
                    throw new InvalidOperationException("inst is not an assignment!");
                }
                Debug.Assert(patternVariables.Contains(inputVariable) || conversionVariables.Contains(inputVariable));
            }
            Debug.Assert(this.assignments.FinalInstruction is Nop);

            void ValidatePattern(MatchInstruction inst)
            {
                Debug.Assert(inst.IsDeconstructCall || inst.IsDeconstructTuple);
                Debug.Assert(!inst.CheckNotNull && !inst.CheckType);
                Debug.Assert(!inst.HasDesignator);
                foreach (var subPattern in inst.SubPatterns.Cast <MatchInstruction>())
                {
                    if (subPattern.IsVar)
                    {
                        Debug.Assert(subPattern.Variable.IsSingleDefinition && subPattern.Variable.LoadCount <= 1);
                        if (subPattern.Variable.LoadCount == 1)
                        {
                            Debug.Assert(subPattern.Variable.LoadInstructions[0].IsDescendantOf(this));
                        }
                        patternVariables.Add(subPattern.Variable);
                    }
                    else
                    {
                        ValidatePattern(subPattern);
                    }
                }
            }
        }
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(EntryPoint == Blocks[0]);
     Debug.Assert(!IsConnected || EntryPoint.IncomingEdgeCount >= 1);
     Debug.Assert(Blocks.All(b => b.HasFlag(InstructionFlags.EndPointUnreachable)));
     Debug.Assert(Blocks.All(b => b.FinalInstruction.OpCode == OpCode.Nop));
 }
Example #9
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(condition.ResultType == StackType.I4);
     Debug.Assert(trueInst.ResultType == falseInst.ResultType ||
                  trueInst.HasDirectFlag(InstructionFlags.EndPointUnreachable) ||
                  falseInst.HasDirectFlag(InstructionFlags.EndPointUnreachable));
 }
Example #10
0
 internal override void CheckInvariant(ILPhase phase)
 {
     for (int i = 0; i < Variables.Count; i++)
     {
         Debug.Assert(Variables[i].Function == this);
         Debug.Assert(Variables[i].IndexInFunction == i);
     }
     base.CheckInvariant(phase);
 }
Example #11
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     for (int i = 0; i < Instructions.Count - 1; i++)
     {
         // only the last instruction may have an unreachable endpoint
         Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
     }
 }
Example #12
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     if (phase > ILPhase.InILReader)
     {
         Debug.Assert(targetBlock.Parent is BlockContainer);
         Debug.Assert(this.IsDescendantOf(targetBlock.Parent));
         Debug.Assert(targetBlock.Parent.Children[targetBlock.ChildIndex] == targetBlock);
     }
 }
Example #13
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            LongSet sets = LongSet.Empty;

            foreach (var section in Sections)
            {
                Debug.Assert(!section.Labels.IsEmpty);
                Debug.Assert(!section.Labels.Overlaps(sets));
                sets = sets.UnionWith(section.Labels);
            }
        }
Example #14
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     for (int i = 0; i < Instructions.Count - 1; i++)
     {
         // only the last instruction may have an unreachable endpoint
         Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
     }
     if (this.Type == BlockType.ControlFlow)
     {
         Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
     }
 }
Example #15
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     if (LiftingKind == ComparisonLiftingKind.None)
     {
         Debug.Assert(Left.ResultType == InputType);
         Debug.Assert(Right.ResultType == InputType);
     }
     else
     {
         Debug.Assert(Left.ResultType == InputType || Left.ResultType == StackType.O);
         Debug.Assert(Right.ResultType == InputType || Right.ResultType == StackType.O);
     }
 }
Example #16
0
 internal virtual void CheckInvariant(ILPhase phase)
 {
     foreach (var child in Children)
     {
         Debug.Assert(child.Parent == this);
         Debug.Assert(this.GetChild(child.ChildIndex) == child);
         // if child flags are invalid, parent flags must be too
         // exception: nested ILFunctions (lambdas)
         Debug.Assert(this is ILFunction || child.flags != invalidFlags || this.flags == invalidFlags);
         Debug.Assert(child.IsConnected == this.IsConnected);
         child.CheckInvariant(phase);
     }
     Debug.Assert((this.DirectFlags & ~this.Flags) == 0, "All DirectFlags must also appear in this.Flags");
 }
Example #17
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            int firstArgument = (OpCode != OpCode.NewObj && !Method.IsStatic) ? 1 : 0;

            Debug.Assert(Method.Parameters.Count + firstArgument == Arguments.Count);
            if (firstArgument == 1)
            {
                Debug.Assert(Arguments[0].ResultType == ExpectedTypeForThisPointer(ConstrainedTo ?? Method.DeclaringType),
                             $"Stack type mismatch in 'this' argument in call to {Method.Name}()");
            }
            for (int i = 0; i < Method.Parameters.Count; ++i)
            {
                Debug.Assert(Arguments[firstArgument + i].ResultType == Method.Parameters[i].Type.GetStackType(),
                             $"Stack type mismatch in parameter {i} in call to {Method.Name}()");
            }
        }
Example #18
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            for (int i = 0; i < Instructions.Count - 1; i++)
            {
                // only the last instruction may have an unreachable endpoint
                Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
            }
            switch (this.Kind)
            {
            case BlockKind.ControlFlow:
                Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
                break;

            case BlockKind.CallInlineAssign:
                Debug.Assert(MatchInlineAssignBlock(out _, out _));
                break;
            }
        }
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            bool    expectNullSection = this.IsLifted;
            LongSet sets = LongSet.Empty;

            foreach (var section in Sections)
            {
                if (section.HasNullLabel)
                {
                    Debug.Assert(expectNullSection, "Duplicate 'case null' or 'case null' in non-lifted switch.");
                    expectNullSection = false;
                }
                Debug.Assert(!section.Labels.IsEmpty || section.HasNullLabel);
                Debug.Assert(!section.Labels.Overlaps(sets));
                sets = sets.UnionWith(section.Labels);
            }
            Debug.Assert(sets.SetEquals(LongSet.Universe), "switch does not handle all possible cases");
            Debug.Assert(!expectNullSection, "Lifted switch is missing 'case null'");
        }
Example #20
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            switch (field.DeclaringType.IsReferenceType)
            {
            case true:
                Debug.Assert(target.ResultType == StackType.O,
                             "Class fields can only be accessed with an object on the stack");
                break;

            case false:
                Debug.Assert(target.ResultType == StackType.I || target.ResultType == StackType.Ref,
                             "Struct fields can only be accessed with a pointer on the stack");
                break;

            case null:
                // field of unresolved type
                Debug.Assert(target.ResultType == StackType.O || target.ResultType == StackType.I || target.ResultType == StackType.Ref);
                break;
            }
        }
Example #21
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            for (int i = 0; i < Instructions.Count - 1; i++)
            {
                // only the last instruction may have an unreachable endpoint
                Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
            }
            switch (this.Kind)
            {
            case BlockKind.ControlFlow:
                Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
                break;

            case BlockKind.CallInlineAssign:
                Debug.Assert(MatchInlineAssignBlock(out _, out _));
                break;

            case BlockKind.CallWithNamedArgs:
                Debug.Assert(finalInstruction is CallInstruction);
                foreach (var inst in Instructions)
                {
                    var stloc = inst as StLoc;
                    Debug.Assert(stloc != null, "Instructions in CallWithNamedArgs must be assignments");
                    Debug.Assert(stloc.Variable.Kind == VariableKind.NamedArgument);
                    Debug.Assert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1);
                    Debug.Assert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction);
                }
                var call = (CallInstruction)finalInstruction;
                if (call.IsInstanceCall)
                {
                    // special case: with instance calls, Instructions[0] must be for the this parameter
                    ILVariable v = ((StLoc)Instructions[0]).Variable;
                    Debug.Assert(call.Arguments[0].MatchLdLoc(v));
                }
                break;
            }
        }
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(IsLifted == (ResultType == StackType.O));
     Debug.Assert(IsLifted || ResultType == UnderlyingResultType);
 }
Example #23
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(condition.ResultType == StackType.I4);
 }
Example #24
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(Left.ResultType == StackType.I4 || Left.ResultType == StackType.O);
 }
Example #25
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer));
     Debug.Assert(phase <= ILPhase.InILReader || phase == ILPhase.InAsyncAwait || value.ResultType == targetContainer.ResultType);
 }
Example #26
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(Arguments.Count == ParameterTypes.Length + (IsInstance ? 1 : 0));
 }
Example #27
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(phase <= ILPhase.InILReader || this.IsDescendantOf(targetContainer));
 }
Example #28
0
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     Debug.Assert(valueInst.ResultType == StackType.O || valueInst.ResultType == fallbackInst.ResultType);
 }
Example #29
0
        internal override void CheckInvariant(ILPhase phase)
        {
            base.CheckInvariant(phase);
            for (int i = 0; i < Instructions.Count - 1; i++)
            {
                // only the last instruction may have an unreachable endpoint
                Debug.Assert(!Instructions[i].HasFlag(InstructionFlags.EndPointUnreachable));
            }
            switch (this.Kind)
            {
            case BlockKind.ControlFlow:
                Debug.Assert(finalInstruction.OpCode == OpCode.Nop);
                break;

            case BlockKind.CallInlineAssign:
                Debug.Assert(MatchInlineAssignBlock(out _, out _));
                break;

            case BlockKind.CallWithNamedArgs:
                Debug.Assert(finalInstruction is CallInstruction);
                foreach (var inst in Instructions)
                {
                    var stloc = inst as StLoc;
                    DebugAssert(stloc != null, "Instructions in CallWithNamedArgs must be assignments");
                    DebugAssert(stloc.Variable.Kind == VariableKind.NamedArgument);
                    DebugAssert(stloc.Variable.IsSingleDefinition && stloc.Variable.LoadCount == 1);
                    DebugAssert(stloc.Variable.LoadInstructions.Single().Parent == finalInstruction);
                }
                var call = (CallInstruction)finalInstruction;
                if (call.IsInstanceCall)
                {
                    // special case: with instance calls, Instructions[0] must be for the this parameter
                    ILVariable v = ((StLoc)Instructions[0]).Variable;
                    Debug.Assert(call.Arguments[0].MatchLdLoc(v));
                }
                break;

            case BlockKind.ArrayInitializer:
                var final = finalInstruction as LdLoc;
                Debug.Assert(final != null && final.Variable.IsSingleDefinition && final.Variable.Kind == VariableKind.InitializerTarget);
                IType?type = null;
                Debug.Assert(Instructions[0].MatchStLoc(final !.Variable, out var init) && init.MatchNewArr(out type));
                for (int i = 1; i < Instructions.Count; i++)
                {
                    DebugAssert(Instructions[i].MatchStObj(out ILInstruction? target, out _, out var t) && type != null && type.Equals(t));
                    DebugAssert(target.MatchLdElema(out t, out ILInstruction? array) && type.Equals(t));
                    DebugAssert(array.MatchLdLoc(out ILVariable? v) && v == final.Variable);
                }
                break;

            case BlockKind.CollectionInitializer:
            case BlockKind.ObjectInitializer:
                var final2 = finalInstruction as LdLoc;
                Debug.Assert(final2 != null);
                var initVar2 = final2 !.Variable;
                Debug.Assert(initVar2.StoreCount == 1 && initVar2.Kind == VariableKind.InitializerTarget);
                IType?type2     = null;
                bool  condition = Instructions[0].MatchStLoc(final2.Variable, out var init2);
                Debug.Assert(condition);
                Debug.Assert(init2 is NewObj ||
                             init2 is DefaultValue ||
                             (init2 is CallInstruction c && c.Method.FullNameIs("System.Activator", "CreateInstance") && c.Method.TypeArguments.Count == 1) ||
                             (init2 is Block named && named.Kind == BlockKind.CallWithNamedArgs));
                switch (init2)
                {
                case NewObj newObj:
                    type2 = newObj.Method.DeclaringType;
                    break;

                case DefaultValue defaultValue:
                    type2 = defaultValue.Type;
                    break;

                case Block callWithNamedArgs when callWithNamedArgs.Kind == BlockKind.CallWithNamedArgs:
                    type2 = ((CallInstruction)callWithNamedArgs.FinalInstruction).Method.ReturnType;
                    break;

                case CallInstruction ci2 when TransformCollectionAndObjectInitializers.IsRecordCloneMethodCall(ci2):
                    type2 = ci2.Method.DeclaringType;

                    break;

                case Call c2 when c2.Method.FullNameIs("System.Activator", "CreateInstance") && c2.Method.TypeArguments.Count == 1:
                    type2 = c2.Method.TypeArguments[0];

                    break;

                default:
                    Debug.Assert(false);
                    break;
                }
                for (int i = 1; i < Instructions.Count; i++)
                {
                    Debug.Assert(Instructions[i] is StLoc || AccessPathElement.GetAccessPath(Instructions[i], type2).Kind != AccessPathKind.Invalid);
                }
                break;

            case BlockKind.DeconstructionConversions:
                Debug.Assert(this.SlotInfo == DeconstructInstruction.ConversionsSlot);
                break;

            case BlockKind.DeconstructionAssignments:
                Debug.Assert(this.SlotInfo == DeconstructInstruction.AssignmentsSlot);
                break;
            }
        }
 internal override void CheckInvariant(ILPhase phase)
 {
     base.CheckInvariant(phase);
     CheckValidTarget();
 }