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()); }
private AbstractStackState <VariabilityInfo> HandleNewarr(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { return(pre .Pop() .Push(VariabilityInfo.CreateBySingleDef(EVariability.ExternVariable, ili.Index)) .UniqueSuccessor()); }
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); }
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()); }
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()); }
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()); }
/// <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); } }
/// <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); } }
/// <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); }
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()); }
/// <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); }
private AbstractStackState <VariabilityInfo> HandleRet(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { Type returnType; if (Method.IsFunction(out returnType)) { return(pre.Pop().UniqueSuccessor()); } else { return(pre.UniqueSuccessor()); } }
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); }
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()); }
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()); } }
/// <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; }
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()); }
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()); } }
private AbstractStackState <VariabilityInfo> HandleStloc(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, int index) { VariabilityInfo value = pre[0]; return(pre.Assign(index, value).Pop().UniqueSuccessor()); }
/// <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; }
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); }
private AbstractStackState <VariabilityInfo> HandleStarg(ILInstruction ili, AbstractStackState <VariabilityInfo> pre, int index) { return(pre.AssignArg(index, pre[0]).Pop().UniqueSuccessor()); }
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); }
private AbstractStackState <VariabilityInfo> PushC(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { return(pre.Push(VariabilityInfo.CreateBySingleDef(EVariability.Constant, ili.Index)).UniqueSuccessor()); }
private AbstractStackState <VariabilityInfo> Nop(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { return(pre.UniqueSuccessor()); }
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); }
/// <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);
private AbstractStackState <VariabilityInfo> HandleLdind(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { return(PushV(ili, pre.Pop())); }
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()); }
private AbstractStackState <VariabilityInfo> HandleDup(ILInstruction ili, AbstractStackState <VariabilityInfo> pre) { return(pre.Push(pre[0]).UniqueSuccessor()); }