예제 #1
0
        private AbstractStackState <VariabilityInfo> HandleLdloc(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, int index)
        {
            Contract.Requires <ArgumentNullException>(pre != null);
            Contract.Requires <ArgumentException>(index >= 0);

            return(pre.Push(pre.GetLocal(index)).UniqueSuccessor());
        }
예제 #2
0
 private AbstractStackState <VariabilityInfo> HandleNewarr(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
 {
     return(pre
            .Pop()
            .Push(VariabilityInfo.CreateBySingleDef(EVariability.ExternVariable, ili.Index))
            .UniqueSuccessor());
 }
예제 #3
0
        protected override bool Merge(
            AbstractStackState <VariabilityInfo> a,
            AbstractStackState <VariabilityInfo> b,
            out AbstractStackState <VariabilityInfo> m)
        {
            List <VariabilityInfo> stack = new List <VariabilityInfo>();
            bool changed = Merge(i => a[i], i => b[i], stack, a.Depth);
            List <VariabilityInfo> locals = new List <VariabilityInfo>();

            if (Merge(i => a.GetLocal(i), i => b.GetLocal(i), locals, a.NumLocals))
            {
                changed = true;
            }
            List <VariabilityInfo> args = new List <VariabilityInfo>();

            if (Merge(i => a.GetArgument(i), i => b.GetArgument(i), args, a.NumArguments))
            {
                changed = true;
            }
            if (a.HasUniqueSuccessor() != b.HasUniqueSuccessor())
            {
                changed = true;
            }
            m = new IndependentStackState(stack, locals, args,
                                          a.HasUniqueSuccessor() && b.HasUniqueSuccessor());
            return(changed);
        }
예제 #4
0
        private AbstractStackState <VariabilityInfo> HandleStind(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            VariabilityInfo value   = pre[0];
            VariabilityInfo address = pre[1];

            return(UpdateStackState(ili, value, pre).Pop().Pop().UniqueSuccessor());
        }
예제 #5
0
        private AbstractStackState <VariabilityInfo> HandleBinOp(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            VariabilityInfo a = pre[0];
            VariabilityInfo b = pre[1];
            VariabilityInfo r = VariabilityInfo.MergeByNewDef(a, b, ili.Index);

            return(pre.Pop().Pop().Push(r).UniqueSuccessor());
        }
예제 #6
0
        private AbstractStackState <VariabilityInfo> HandleCpobj(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            VariabilityInfo source = pre[0];
            VariabilityInfo dest   = pre[1];
            AbstractStackState <VariabilityInfo> next = UpdateStackState(ili, source, pre);

            next = next.Pop().Pop();
            return(next.UniqueSuccessor());
        }
예제 #7
0
 /// <summary>
 /// Constructs a stack state indicating a non-unique successor, based on an existing state
 /// </summary>
 /// <param name="state">a stack state</param>
 /// <returns>the desired stack state</returns>
 public static AbstractStackState <VariabilityInfo> AmbiguousSuccessor(this AbstractStackState <VariabilityInfo> state)
 {
     if (HasUniqueSuccessor(state))
     {
         return(new ModifyUniqueSuccessorStackState(state, false));
     }
     else
     {
         return(state);
     }
 }
예제 #8
0
 /// <summary>
 /// Constructs a stack state indicating a unique successor, based on an existing stat6e
 /// </summary>
 /// <param name="state">a stack state</param>
 /// <returns>the desired stack state</returns>
 public static AbstractStackState <VariabilityInfo> UniqueSuccessor(this AbstractStackState <VariabilityInfo> state)
 {
     if (!HasUniqueSuccessor(state))
     {
         return(new ModifyUniqueSuccessorStackState(state, true));
     }
     else
     {
         return(state);
     }
 }
예제 #9
0
        /// <summary>
        /// Propagates a stack state by computing the effects of executing a specific instruction.
        /// </summary>
        /// <param name="ili"></param>
        /// <param name="pre"></param>
        /// <returns></returns>
        protected virtual AbstractStackState <TElem> Propagate(ILInstruction ili, AbstractStackState <TElem> pre)
        {
            int preDepth = pre.Depth;
            AbstractStackState <TElem> post = _pmap[ili.Code](ili, pre);
            int postDepth = post.Depth;
            int npush, npop;

            StackInfluenceAnalysis.GetStackBilance(ili, Method, out npop, out npush);
            Debug.Assert(postDepth - preDepth == npush - npop);
            return(post);
        }
예제 #10
0
        private AbstractStackState <VariabilityInfo> HandleLdsfld(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            FieldInfo    field      = (FieldInfo)ili.Operand;
            FieldFacts   fieldFacts = FactUniverse.Instance.GetFacts(field);
            EVariability fieldVar   = fieldFacts.IsWritten || fieldFacts.IsSubMutated ?
                                      EVariability.ExternVariable : EVariability.Constant;
            VariabilityInfo newVar = VariabilityInfo.CreateBySingleDef(fieldVar, ili.Index);

            return(pre
                   .Push(newVar)
                   .UniqueSuccessor());
        }
예제 #11
0
        /// <summary>
        /// Tells whether a given stack state has a unique successor
        /// </summary>
        /// <param name="state">stack state</param>
        /// <returns>whether stack state has a unique successor</returns>
        public static bool HasUniqueSuccessor(this AbstractStackState <VariabilityInfo> state)
        {
            IUniqueSuccessorInfo vstate = state as IUniqueSuccessorInfo;

            while (vstate == null)
            {
                DependentStackState <VariabilityInfo> dstate = (DependentStackState <VariabilityInfo>)state;
                state  = dstate.Pre;
                vstate = state as IUniqueSuccessorInfo;
            }
            return(vstate.HasUniqueSuccessor);
        }
예제 #12
0
        private AbstractStackState <VariabilityInfo> HandleRet(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            Type returnType;

            if (Method.IsFunction(out returnType))
            {
                return(pre.Pop().UniqueSuccessor());
            }
            else
            {
                return(pre.UniqueSuccessor());
            }
        }
예제 #13
0
        protected override bool Merge(AbstractStackState <TElem> a, AbstractStackState <TElem> b, out AbstractStackState <TElem> m)
        {
            Contract.Requires(a != null);
            Contract.Requires(b != null);
            Contract.Requires(a.Depth == b.Depth);
            Contract.Requires(a.NumLocals == b.NumLocals);
            Contract.Requires(a.NumArguments == b.NumArguments);
            Contract.Ensures(Contract.ValueAtReturn(out m) != null);

            m = null; //so that Code Contracts can be deactivated completely, otherwise the Compiler complains that m is unassigned on return

            return(false);
        }
예제 #14
0
        private AbstractStackState <VariabilityInfo> HandleNewobj(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            ConstructorInfo ctor = (ConstructorInfo)ili.Operand;

            ParameterInfo[] args = ctor.GetParameters();
            AbstractStackState <VariabilityInfo> next = pre;

            for (int i = 0; i < args.Length; i++)
            {
                next = next.Pop();
            }
            return(next
                   .Push(VariabilityInfo.CreateBySingleDef(EVariability.ExternVariable, ili.Index))
                   .UniqueSuccessor());
        }
예제 #15
0
        private AbstractStackState <VariabilityInfo> HandleStfld(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            var field = (FieldInfo)ili.Operand;
            int index = Array.IndexOf(_localizedFields, field);

            if (index < 0)
            {
                return(Pop2(ili, pre));
            }
            else
            {
                VariabilityInfo value = pre[0];
                return(pre.Assign(index + _localizedFieldsBaseIndex, value).Pop().Pop().UniqueSuccessor());
            }
        }
예제 #16
0
        /// <summary>
        /// Executes the analysis.
        /// </summary>
        public virtual void Run()
        {
            Contract.Requires(!AnalysisDone);
            Contract.Ensures(AnalysisDone);

            MethodFacts myFacts = FactUniverse.Instance.GetFacts(Method);

            CFG = myFacts.CFG;

            _stackStates = new AbstractStackState <TElem> [CFG.Instructions.Count];
            AbstractStackState <TElem> initial = CreateInitialStackState();
            Queue <Tuple <AbstractStackState <TElem>, ILInstruction> > q = new Queue <Tuple <AbstractStackState <TElem>, ILInstruction> >();

            q.Enqueue(Tuple.Create(initial, CFG.Instructions[0]));
            int marshal = CFG.Instructions.Count - 1;

            while (q.Count > 0)
            {
                Tuple <AbstractStackState <TElem>, ILInstruction> cur = q.Dequeue();
                AbstractStackState <TElem> preState = cur.Item1;
                ILInstruction ili = cur.Item2;
                AbstractStackState <TElem> nextState = Propagate(ili, preState);
                ILInstruction[]            succs     = CFG.GetSuccessorsOf(ili);
                if (_stackStates[ili.Index] == null)
                {
                    _stackStates[ili.Index] = nextState;
                }
                else
                {
                    bool changed = Merge(_stackStates[ili.Index], nextState, out _stackStates[ili.Index]);
                    if (!changed)
                    {
                        continue;
                    }
                }
                foreach (ILInstruction nextILI in succs)
                {
                    if (nextILI.Index < marshal) // skip pseudo ret at the end
                    {
                        q.Enqueue(Tuple.Create(_stackStates[ili.Index], nextILI));
                    }
                }
            }

            AnalysisDone = true;
        }
예제 #17
0
        private AbstractStackState <VariabilityInfo> HandleCall(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, bool isCalli)
        {
            MethodBase   callee  = (MethodBase)ili.Operand;
            bool         hasThis = callee.CallingConvention.HasFlag(CallingConventions.HasThis);
            EVariability callVar = EVariability.Constant;

            ParameterInfo[] args        = callee.GetParameters();
            MethodFacts     myFacts     = FactUniverse.Instance.GetFacts(Method);
            MethodFacts     calleeFacts = FactUniverse.Instance.GetFacts(callee);
            AbstractStackState <VariabilityInfo> next = pre;

            if (hasThis)
            {
                callVar = VariabilityOperations.Stronger(callVar, pre[0].Variability);
                next    = pre.Pop();
            }
            for (int i = 0; i < args.Length; i++)
            {
                callVar = VariabilityOperations.Stronger(callVar, next[0].Variability);
                next    = next.Pop();
            }
            if (!calleeFacts.IsSideEffectFree)
            {
                callVar = EVariability.ExternVariable;
            }
            if (calleeFacts.IsStaticEvaluation)
            {
                callVar = EVariability.Constant;
            }
            if (isCalli)
            {
                next = pre.Pop();
            }
            VariabilityInfo callVarI = VariabilityInfo.CreateBySingleDef(callVar, ili.Index);

            next = UpdateStackState(ili, callVarI, next);
            Type returnType;

            if (callee.IsFunction(out returnType))
            {
                next = next.Push(callVarI);
            }
            return(next.UniqueSuccessor());
        }
예제 #18
0
        private AbstractStackState <VariabilityInfo> HandleLdfld(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            FieldInfo field = (FieldInfo)ili.Operand;
            int       index = Array.IndexOf(_localizedFields, field);

            if (index >= 0)
            {
                return(HandleLdloc(null, pre.Pop(), _localizedFieldsBaseIndex + index));
            }
            else
            {
                FieldFacts   fieldFacts = FactUniverse.Instance.GetFacts(field);
                EVariability fieldVar   = fieldFacts.IsWritten || fieldFacts.IsSubMutated ?
                                          EVariability.ExternVariable : EVariability.Constant;
                VariabilityInfo newVar = VariabilityInfo.CreateBySingleDef(fieldVar, ili.Index);
                return(pre
                       .Pop()
                       .Push(newVar)
                       .UniqueSuccessor());
            }
        }
예제 #19
0
        private AbstractStackState <VariabilityInfo> HandleStloc(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, int index)
        {
            VariabilityInfo value = pre[0];

            return(pre.Assign(index, value).Pop().UniqueSuccessor());
        }
예제 #20
0
 /// <summary>
 /// Constructs a new stack state based on an existing state
 /// </summary>
 /// <param name="pre">existing state</param>
 /// <param name="isUnique">whether that state has a unique successor</param>
 public ModifyUniqueSuccessorStackState(AbstractStackState <VariabilityInfo> pre, bool isUnique) :
     base(pre)
 {
     HasUniqueSuccessor = isUnique;
 }
예제 #21
0
        private AbstractStackState <VariabilityInfo> HandleBinBranch(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            VariabilityInfo a    = pre[0];
            VariabilityInfo b    = pre[1];
            var             next = pre.Pop().Pop();

            if (VariabilityOperations.Stronger(a.Variability, b.Variability) == EVariability.Constant)
            {
                next = next.UniqueSuccessor();
            }
            else
            {
                next = next.AmbiguousSuccessor();
            }
            return(next);
        }
예제 #22
0
 private AbstractStackState <VariabilityInfo> HandleStarg(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, int index)
 {
     return(pre.AssignArg(index, pre[0]).Pop().UniqueSuccessor());
 }
예제 #23
0
        private AbstractStackState <VariabilityInfo> HandleUnBranch(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
        {
            VariabilityInfo c    = pre[0];
            var             next = pre.Pop();

            if (c.Variability == EVariability.Constant)
            {
                next = next.UniqueSuccessor();
            }
            else
            {
                next = next.AmbiguousSuccessor();
            }
            return(next);
        }
예제 #24
0
 private AbstractStackState <VariabilityInfo> PushC(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
 {
     return(pre.Push(VariabilityInfo.CreateBySingleDef(EVariability.Constant, ili.Index)).UniqueSuccessor());
 }
예제 #25
0
 private AbstractStackState <VariabilityInfo> Nop(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
 {
     return(pre.UniqueSuccessor());
 }
예제 #26
0
        private AbstractStackState <VariabilityInfo> UpdateStackState(ILInstruction ili, VariabilityInfo newVar, AbstractStackState <VariabilityInfo> cur)
        {
            MethodFacts myFacts = FactUniverse.Instance.GetFacts(Method);

            foreach (LocalMutation lm in myFacts.GetLocalMutations(ili.Index))
            {
                IModifiesStackState mss = lm as IModifiesStackState;
                if (mss != null)
                {
                    cur = mss.ModifyStackState(cur, newVar, VariabilityInfo.MergeDefs);
                }
            }
            return(cur);
        }
예제 #27
0
 /// <summary>
 /// Merges two stack states.
 /// </summary>
 /// <remarks>Merging stack states is necessary wherever program flow joins.</remarks>
 /// <param name="a">a stack state</param>
 /// <param name="b">another stack state</param>
 /// <param name="m">the merged stack state</param>
 /// <returns>false iff m and a are equivalent in a problem-specific sense.</returns>
 protected abstract bool Merge(
     AbstractStackState <TElem> a,
     AbstractStackState <TElem> b,
     out AbstractStackState <TElem> m);
예제 #28
0
 private AbstractStackState <VariabilityInfo> HandleLdind(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
 {
     return(PushV(ili, pre.Pop()));
 }
예제 #29
0
        private AbstractStackState <VariabilityInfo> HandleLdArg(ILInstruction ili, int narg, AbstractStackState <VariabilityInfo> pre)
        {
            MethodFacts  myFacts = FactUniverse.Instance.GetFacts(Method);
            EVariability varia;

            if (Method.CallingConvention.HasFlag(CallingConventions.HasThis))
            {
                if (narg == 0)
                {
                    varia = EVariability.Constant;
                }
                else
                {
                    varia = _callPattern.Pattern[narg - 1];
                }
            }
            else
            {
                varia = _callPattern.Pattern[narg];
            }
            return(pre.Push(VariabilityInfo.CreateBySingleDef(varia, ili.Index)).UniqueSuccessor());
        }
예제 #30
0
 private AbstractStackState <VariabilityInfo> HandleDup(ILInstruction ili, AbstractStackState <VariabilityInfo> pre)
 {
     return(pre.Push(pre[0]).UniqueSuccessor());
 }