public void EliminateAll(ISymValue arg) { SymbolicValue sv = Find(arg); this.AddEliminateAllUpdate(sv); // must be before RemoveAll, as it reads termMap this.termMap = this.termMap.RemoveAll(sv); }
/// <summary> /// Set v to a new value that is abstracted by av /// </summary> /// <param name="v"></param> /// <param name="av"></param> private void AssignAVal(Variable v, Lattice.AVal av) { ISymValue sv = this.egraph.FreshSymbol(); this.egraph[v] = sv; this.egraph[sv] = av; }
public AbstractValue this[ISymValue sym] { get { sym = Find(sym); AbstractValue v = (AbstractValue)this.absMap[sym]; if (v == null) { v = this.elementLattice.Top; } return(v); } set { SymbolicValue sv = Find(sym); AbstractValue old = this[sym]; if (old != value) { AddAValUpdate(sv); if (this.elementLattice.IsTop(value)) { this.absMap = this.absMap.Remove(sv); } else { this.absMap = this.absMap.Add(sv, value); } } } }
internal TypeNode LowerBoundOfObjectPointedToByFrame(Variable guardVariable) { ISymValue guard = this.egraph[guardVariable]; ISymValue guardedObject = this.egraph[FrameFor, guard]; Lattice.AVal invLevel = (Lattice.AVal) this.egraph[guardedObject]; return(invLevel.lowerBound); }
public void AssignFrameForExposable(ISymValue guard) { ISymValue guardedObject = this.egraph[FrameFor, guard]; ISymValue guardTypeObject = this.egraph[StaticTypeOf, guard]; Lattice.AVal guardsType = (Lattice.AVal) this.egraph[guardTypeObject]; this.egraph[guardedObject] = new Lattice.AVal(guardsType.lowerBound, guardsType.upperBound); }
public void AssignFrameForExposed(ISymValue guard) { ISymValue guardedObject = this.egraph[FrameFor, guard]; ISymValue dummy = this.egraph[StaticTypeOf, guard]; Lattice.AVal guardsType = (Lattice.AVal) this.egraph[dummy]; this.egraph[guardedObject] = new Lattice.AVal(guardsType.lowerBound.BaseType, guardsType.upperBound.BaseType); }
public void AssignEqIsExposed(Variable dest, Variable operand) { ISymValue opval = this.egraph[operand]; ISymValue sv = this.egraph.FreshSymbol(); this.egraph[dest] = sv; // ?? Ask Manuel: Should it be the sv' that dest maps to that sv should be mapped to here? this.egraph[EqIsExposedId, opval] = sv; }
public void AssignFunctionLink(Identifier func, Variable dest, Variable operand) { ISymValue opval = this.egraph[operand]; ISymValue sv = this.egraph.FreshSymbol(); this.egraph[dest] = sv; // ?? Ask Manuel: Should it be the sv' that dest maps to that sv should be mapped to here? this.egraph[func, opval] = sv; }
public void RefineBranchInformation(Variable cond, out ExposureState trueState, out ExposureState falseState) { ISymValue cv = this.egraph[cond]; trueState = new ExposureState(this); falseState = new ExposureState(this); AssumeTrue(cv, ref trueState); AssumeFalse(cv, ref falseState); }
public bool IsFrameExposable(Variable guardVariable) { ISymValue guard = this.egraph[guardVariable]; ISymValue guardedObject = this.egraph[FrameFor, guard]; ISymValue guardTypeObject = this.egraph[StaticTypeOf, guard]; Lattice.AVal guardsType = (Lattice.AVal) this.egraph[guardTypeObject]; Lattice.AVal guardedObjectsType = (Lattice.AVal) this.egraph[guardedObject]; return(guardsType.lowerBound == guardedObjectsType.lowerBound); }
public void AssignFrameForNotExposed(Variable guardVariable) { ISymValue guard = this.egraph[guardVariable]; ISymValue guardTypeObject = this.egraph[StaticTypeOf, guard]; Lattice.AVal guardsType = (Lattice.AVal) this.egraph[guardTypeObject]; ISymValue guardedObject = this.egraph[FrameFor, guard]; this.egraph[guardedObject] = guardsType; }
public System.Collections.Generic.IEnumerable <EGraphTerm> EqTerms(ISymValue sv) { foreach (EGraphTerm eterm in this.eqTermMap.Keys2(Find(sv))) { // test if it is valid if (this.TryLookup(eterm.Function, eterm.Args) == sv) { yield return(eterm); } } }
public void AssignFrameFor(Variable dest, Variable source, TypeNode t) { ISymValue guard = this.egraph.FreshSymbol(); ISymValue guardedObject = this.egraph[source]; this.egraph[dest] = guard; this.egraph[FrameFor, guard] = guardedObject; ISymValue fresh = this.egraph.FreshSymbol(); this.egraph[fresh] = new Lattice.AVal(t, t); this.egraph[StaticTypeOf, guard] = fresh; }
public void AssumeEqual(ISymValue v1, ISymValue v2) { WorkList wl = new WorkList(); SymbolicValue v1rep = Find(v1); SymbolicValue v2rep = Find(v2); PushEquality(wl, v1rep, v2rep); if (!wl.IsEmpty()) { // TODO: there's an opportunity for optimizing the number // of necessary updates that we need to record, since the induced // updates of the equality may end up as duplicates. AddEqualityUpdate(v1rep, v2rep); } DrainEqualityWorkList(wl); }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be false</param> private static void AssumeFalse(ISymValue cv, ref ExposureState state) { if (state == null) { return; } foreach (EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == ExposureState.EqIsExposedId) { // EqIsExposed(op) == false, therefore op is *not* exposed ISymValue op = t.Args[0]; // state.AssignFrameForNotExposed(op); ISymValue guardedObject = state.egraph[FrameFor, op]; state.egraph[guardedObject] = Lattice.AVal.Top; // BUGBUG?? If it isn't exposed at this frame, then what is it? } } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be non-null (true)</param> /// <param name="state">state if sv is non-null (true)</param> private static void AssumeTrue(ISymValue cv, ref ExposureState state) { if (state == null) { return; } foreach (EGraphTerm t in state.egraph.EqTerms(cv)) { ISymValue op = t.Args[0]; if (t.Function == ExposureState.EqIsExposedId) { // EqIsExposed(op) == true, therefore op *is* exposed state.AssignFrameForExposed(op); } else if (t.Function == ExposureState.EqIsExposableId) { state.AssignFrameForExposable(op); } } }
private void CopyStructValue(ISymValue destAddr, ISymValue srcAddr, Struct type) { if (destAddr == null) return; foreach (IUniqueKey key in this.egraph.Functions(srcAddr)) { Field field = key as Field; Member member = null; TypeNode membertype = null; if (field != null) { member = field; membertype = field.Type; } else { Property prop = key as Property; if (prop == null) continue; member = prop; membertype = prop.Type; } if (member == null) continue; ISymValue destFld = this.egraph[member, destAddr]; ISymValue srcFld = this.egraph[member, srcAddr]; Struct memberStruct = type as Struct; if (memberStruct != null && !memberStruct.IsPrimitive) { // nested struct copy CopyStructValue(destFld, srcFld, memberStruct); } else { // primitive|pointer copy this.egraph[ValueOf, destFld] = this.egraph[ValueOf, srcFld]; } } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be non-null (true)</param> /// <param name="state">state if sv is non-null (true)</param> private static void AssumeTrue(ISymValue cv, ref NonNullState state) { if (state == null) return; if (state.IsNull(cv)) { // infeasible state = null; return; } if (state.IsNonNull(cv)) return; state.egraph[cv] = Lattice.AVal.NonNull; foreach(EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == NonNullState.EqNullId) { ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.NeNullId) { ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.LogicalNegId) { ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.IsInstId) { ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } } }
public void AssignFrameForExposable(Variable guardVariable) { ISymValue guard = this.egraph[guardVariable]; this.AssignFrameForExposable(guard); }
ICollection IMergeInfo.Keys2(ISymValue key1) { return(this.Map.Keys2(key1)); }
private bool IsExposed(ISymValue sv) { return(((Lattice.AVal) this.egraph[sv]) == Lattice.AVal.IsExposed); }
private SymbolicValue Find(ISymValue v) { return(this.Find((SymbolicValue)v)); }
ISymValue IMergeInfo.this[ISymValue key1, ISymValue key2] { get { return (ISymValue)this.Map[key1, key2]; } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be non-null (true)</param> /// <param name="state">state if sv is non-null (true)</param> private static void AssumeTrue(ISymValue cv, ref ExposureState state) { if (state == null) return; foreach(EGraphTerm t in state.egraph.EqTerms(cv)){ ISymValue op = t.Args[0]; if (t.Function == ExposureState.EqIsExposedId){ // EqIsExposed(op) == true, therefore op *is* exposed state.AssignFrameForExposed(op); }else if (t.Function == ExposureState.EqIsExposableId){ state.AssignFrameForExposable(op); } } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be false</param> private static void AssumeFalse(ISymValue cv, ref ExposureState state) { if (state == null) return; foreach(EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == ExposureState.EqIsExposedId) { // EqIsExposed(op) == false, therefore op is *not* exposed ISymValue op = t.Args[0]; // state.AssignFrameForNotExposed(op); ISymValue guardedObject = state.egraph[FrameFor, op]; state.egraph[guardedObject] = Lattice.AVal.Top; // BUGBUG?? If it isn't exposed at this frame, then what is it? } } }
public void AssignFrameForExposable(ISymValue guard){ ISymValue guardedObject = this.egraph[FrameFor, guard]; ISymValue guardTypeObject = this.egraph[StaticTypeOf,guard]; Lattice.AVal guardsType = (Lattice.AVal)this.egraph[guardTypeObject]; this.egraph[guardedObject] = new Lattice.AVal(guardsType.lowerBound,guardsType.upperBound); }
public void AssignFrameForExposed(ISymValue guard){ ISymValue guardedObject = this.egraph[FrameFor, guard]; ISymValue dummy = this.egraph[StaticTypeOf,guard]; Lattice.AVal guardsType = (Lattice.AVal)this.egraph[dummy]; this.egraph[guardedObject] = new Lattice.AVal(guardsType.lowerBound.BaseType,guardsType.upperBound.BaseType); }
/// <summary> /// Adds assumption that sv is not exposed /// </summary> public void AssumeNotExposed(ISymValue sv) { this.egraph[sv] = Lattice.AVal.IsNotExposed; }
private bool IsExposed(ISymValue sv) { return ((Lattice.AVal)this.egraph[sv]) == Lattice.AVal.IsExposed; }
public bool IsCommon(ISymValue sv) { return(sv.UniqueId <= lastCommonVariable); }
ICollection IMergeInfo.Keys2(ISymValue key1) { return this.Map.Keys2(key1); }
public bool IsEqual(ISymValue v1, ISymValue v2) { return(Find(v1) == Find(v2)); }
internal Lattice.AVal GetAVal(Variable v) { ISymValue sv = this.egraph[v]; return((Lattice.AVal) this.egraph[sv]); }
/// <summary> /// Use only for non-struct values. /// </summary> private bool IsAssigned(ISymValue sv) { DefAssignLattice.AVal aval = (DefAssignLattice.AVal)this.egraph[sv]; if (aval.Assigned) return true; return false; }
ISymValue IMergeInfo.this[ISymValue key1, ISymValue key2] { get { return((ISymValue)this.Map[key1, key2]); } }
private bool IsAssignedField(ISymValue svderef, Field f) { f = CanonicalField(f); ISymValue svfield = this.egraph[f, svderef]; DefAssignLattice.AVal aval = (DefAssignLattice.AVal)this.egraph[svfield]; if (aval.Assigned) return true; Struct s = f.Type as Struct; if (s == null || s.IsPrimitive) return false; return IsAssigned(svfield, s) == null; }
// end existential delay private DefAssignLattice.AVal GetAVal(ISymValue sv) { return (DefAssignLattice.AVal)this.egraph[sv]; }
private ISymValue GetFieldAddress(NonNullChecker checker, ISymValue sourceobj, Field f, bool setFieldNullnessAccordingToType) { ISymValue loc = this.egraph[f, sourceobj]; if (!f.Type.IsValueType) { ISymValue val = this.egraph.TryLookup(ValueOf, loc); if (val == null) { // manifest and set abstract value according to type. // existential type: dont trust type if existential type is involved... we may do nothing // may assigning its own type. if (setFieldNullnessAccordingToType) { val = this.egraph[ValueOf, loc]; this.egraph[val] = FieldNullness(checker, f, this.typeSystem); } } } return loc; }
private void CopyValue(ISymValue destAddr, ISymValue srcAddr, TypeNode type) { Struct s = type as Struct; if (s != null && !type.IsPrimitive) { CopyStructValue(destAddr, srcAddr, s); } else { ISymValue svalue = this.egraph[ValueOf, srcAddr]; this.egraph[ValueOf, destAddr] = svalue; } }
private ISymValue GetPropertyAddress(ISymValue sourceobj, Property prop) { ISymValue loc = this.egraph[prop, sourceobj]; return loc; }
public System.Collections.Generic.IEnumerable<EGraphTerm> EqTerms(ISymValue sv) { foreach (EGraphTerm eterm in this.eqTermMap.Keys2(Find(sv))) { // test if it is valid if (this.TryLookup(eterm.Function, eterm.Args) == sv) { yield return eterm; } } }
/// <summary> /// Refines the given state according to the knowledge stored in the egraph about sv /// /// In addition, the state can be null when the knowledge is inconsistent. /// </summary> /// <param name="cv">symbolic value we assume to be null (false)</param> private static void AssumeFalse(ISymValue cv, ref NonNullState state) { if (state == null) return; if (state.IsNonNull(cv)) { // infeasible // but we still want to go on analyzing this branch. state = null; return; } if (state.IsNull(cv)) return; foreach(EGraphTerm t in state.egraph.EqTerms(cv)) { if (t.Function == NonNullState.EqNullId) { // EqNull(op) == false, therefore op != null ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.NeNullId) { // NeNull(op) == false, therefore op == null ISymValue op = t.Args[0]; AssumeFalse(op, ref state); } if (t.Function == NonNullState.LogicalNegId) { // Not(op) == false, therefore op == true ISymValue op = t.Args[0]; AssumeTrue(op, ref state); } if (t.Function == NonNullState.IsInstId) { // IsInst(op) == null, cannot deduce anything about op } } // needs to be after we check EqTerms, as they verify mapping is current. if (state != null) state.AssumeNull(cv); }
public bool IsCommon(ISymValue sv) { return (sv.UniqueId <= lastCommonVariable); }
private SymbolicValue Find(ISymValue v) { return this.Find((SymbolicValue)v); }
public ICollection Functions(ISymValue sv) { return(this.termMap.Keys2(Find(sv))); }
public AbstractValue this[ISymValue sym] { get { sym = Find(sym); AbstractValue v = (AbstractValue)this.absMap[sym]; if (v == null) { v = this.elementLattice.Top; } return v; } set { SymbolicValue sv = Find(sym); AbstractValue old = this[sym]; if (old != value) { AddAValUpdate(sv); if (this.elementLattice.IsTop(value)) { this.absMap = this.absMap.Remove(sv); } else { this.absMap = this.absMap.Add(sv, value); } } } }
private string GetPathMappingToLocation(ISymValue loc, out bool localVar) { Variable v = GetLocalMappingToLoc(loc); if (v != null) { localVar = true; return v.Name.Name; } localVar = false; // search for fields of possibly unassigned locals, i.e. This and out parameters. foreach (IUniqueKey c in egraph.Constants) { Parameter p = c as Parameter; if (p == null) continue; if (p.IsOut || (p is This && p.DeclaringMethod is InstanceInitializer)) { ISymValue lv = Value(p); if (this.IsAssigned(lv)) continue; // candidate foreach (IUniqueKey f in egraph.Functions(lv)) { Field fld = f as Field; if (fld == null) continue; ISymValue floc = egraph[f, lv]; if (floc == loc) { return p.Name.Name + "." + fld.Name.Name; } } } } return null; }
/// <summary> /// Returns null if all fields of the struct are fully assigned, otherwise the field that is not. /// </summary> private Field IsAssigned(ISymValue sv, Struct structType) { DefAssignLattice.AVal aval = (DefAssignLattice.AVal)this.egraph[sv]; if (aval.Assigned) return null; Debug.Assert(structType != null); // check if all fields are assigned. MemberList ml = this.analyzer.GetTypeView(structType).Members; if (ml == null) return null; for (int i = 0; i < ml.Count; i++) { Field f = ml[i] as Field; if (f == null) continue; if (f.IsLiteral || f.IsStatic) continue; if ( ! IsAssignedField(sv, f)) return f; } // all fields are assigned. remember that this.egraph[sv] = aval.SameButAssigned; return null; }
public bool IsEqual(ISymValue v1, ISymValue v2) { return (Find(v1) == Find(v2)); }
// end existential delay private void SetDelay(ISymValue sv, DefAssignLattice.Delay delay) { DefAssignLattice.AVal aval = (DefAssignLattice.AVal)this.egraph[sv]; this.egraph[sv] = aval.SameButWith(delay); }
public ICollection Functions(ISymValue sv) { return this.termMap.Keys2(Find(sv)); }
/// <summary> /// Must follow field edges of value types backwards as well /// </summary> public Variable GetLocalMappingToLoc(ISymValue loc) { WorkList refparams = new WorkList(); WorkList fields = new WorkList(); fields.Add(loc); while (! fields.IsEmpty()) { ISymValue sv = (ISymValue)fields.Pull(); foreach (EGraphTerm eterm in egraph.EqTerms(sv)) { if ( !(eterm.Function is StackVariable)) { Variable v = eterm.Function as Variable; if (v != null) { return v; } Field f = eterm.Function as Field; if (f != null && f.DeclaringType.IsValueType) { if (eterm.Args.Length>0) { fields.Add(eterm.Args[0]); } } if (eterm.Function == ValueOf && eterm.Args.Length>0) { // could be that we are looking at a ref parameter refparams.Add(eterm.Args[0]); } } } } while (! refparams.IsEmpty()) { ISymValue sv = (ISymValue)refparams.Pull(); foreach (EGraphTerm eterm in egraph.EqTerms(sv)) { if ( !(eterm.Function is StackVariable)) { Variable v = eterm.Function as Variable; if (v != null && (v.Type is Reference || v.Type is Pointer)) { return v; } } } } return null; }
/// <summary> /// Adds assumption that sv == null /// </summary> public void AssumeNull(ISymValue sv) { this.egraph.AssumeEqual(sv, this.Null); this.egraph[this.Null] = Lattice.AVal.Top; }