public TypeRef Glb(RootEnvironment rootEnv, TypeRef other, BoolRef changed) { if (IsAssignableTo(rootEnv, other)) { return(this); } else if (other.IsAssignableTo(rootEnv, this)) { changed.Set(); return(other); } else { // NOTE: As above if (rootEnv.Global.NullRef.IsAssignableTo(rootEnv, this) && rootEnv.Global.NullRef.IsAssignableTo(rootEnv, other)) { changed.Set(); return(rootEnv.Global.NullRef); } else { throw new InvalidOperationException("types have no glb"); } } }
public void Unify(RootEnvironment rootEnv, StackEntryState other, BoolRef changed) { var type = Type.Lub(rootEnv, other.Type, changed); var upperBound = default(TypeRef); if (UpperBound != null && other.UpperBound != null) { upperBound = UpperBound.Glb(rootEnv, other.UpperBound, changed); } else if (other.UpperBound != null) { upperBound = other.UpperBound; changed.Set(); } else { upperBound = UpperBound; } if (upperBound != null && !type.IsAssignableTo(rootEnv, upperBound)) { throw new InvalidOperationException("stack entries are not unifiable"); } var pointsTo = PointsTo.Lub(other.PointsTo, changed); UpperBound = upperBound; Type = type; PointsTo = pointsTo; }
public VariableEffects Lub(VariableEffects other, BoolRef changed) { var lubVars = new Map <Identifier, ReadWriteDomain>(); foreach (var kv in vars) { var rw = default(ReadWriteDomain); if (other.vars.TryGetValue(kv.Key, out rw)) { lubVars.Add(kv.Key, kv.Value.Lub(rw, changed)); } else { lubVars.Add(kv.Key, kv.Value); } } foreach (var kv in other.vars) { if (!vars.ContainsKey(kv.Key)) { lubVars.Add(kv.Key, kv.Value); changed.Set(); } } return(new VariableEffects(lubVars)); }
public void Unify(ArgsLocalsState other, BoolRef changed) { foreach (var kv in other.argLocalToPointsTo) { var pt = default(PointsTo); if (!kv.Value.IsBottom) { if (argLocalToPointsTo.TryGetValue(kv.Key, out pt)) { argLocalToPointsTo[kv.Key] = pt.Lub(kv.Value, changed); } else { changed.Set(); argLocalToPointsTo.Add(kv.Key, kv.Value); } } } argsAlive.UnionInPlace(other.argsAlive, changed); localsAlive.UnionInPlace(other.localsAlive, changed); }
public PointsTo Lub(PointsTo other, BoolRef changed) { var thisChanged = new BoolRef(); var args = Args.Lub(other.Args, thisChanged); var locals = Locals.Lub(other.Locals, thisChanged); var heap = Heap.Lub(other.Heap, thisChanged); if (args == null || locals == null || heap == null) { return(null); } else if (thisChanged.Value) { changed.Set(); return(new PointsTo(args, locals, heap)); } else { return(this); } }
public Effects Lub(Effects other, BoolRef changed) { var thisChanged = new BoolRef(); var vars = Vars.Lub(other.Vars, thisChanged); var heap = Heap.Lub(other.Heap, thisChanged); var mayThrow = MayThrow.Lub(other.MayThrow, thisChanged); if (vars == null || heap == null || mayThrow == null) { return(null); } if (thisChanged.Value) { changed.Set(); return(new Effects(vars, heap, mayThrow)); } else { return(this); } }
public Effects Lub(Effects other, BoolRef changed) { var thisChanged = new BoolRef(); var args = Args.Lub(other.Args, thisChanged); var locals = Locals.Lub(other.Locals, thisChanged); var heap = Heap.Lub(other.Heap, thisChanged); var mayThrow = MayThrow.Lub(other.MayThrow, thisChanged); if (args == null || locals == null || heap == null || mayThrow == null) { return(null); } else if (thisChanged.Value) { changed.Set(); return(new Effects(args, locals, heap, mayThrow)); } else { return(this); } }
public void SourceToTargetTransition(ArgsLocalsState other, BoolRef changed) { // Any pointers in source are pointers in target foreach (var kv in argLocalToPointsTo) { var pt = default(PointsTo); if (!kv.Value.IsBottom) { if (other.argLocalToPointsTo.TryGetValue(kv.Key, out pt)) { other.argLocalToPointsTo[kv.Key] = pt.Lub(kv.Value, changed); } else { changed.Set(); other.argLocalToPointsTo.Add(kv.Key, kv.Value); } } } // Anything alive in target is alive in source argsAlive.UnionInPlace(other.argsAlive, changed); localsAlive.UnionInPlace(other.localsAlive, changed); }
public void SetUpperBound(RootEnvironment rootEnv, TypeRef type, BoolRef changed) { var s = type.Style(rootEnv); if (s is ValueTypeStyle || s is PointerTypeStyle || s is CodePointerTypeStyle) { // These types are only assignable to themselves, so no need to remember // the upper bound, just check it if (!Type.IsAssignableTo(rootEnv, type)) { if (s is UnmanagedPointerTypeStyle) { throw new InvalidOperationException("unmanaged pointer"); } else { throw new InvalidOperationException("stack entry cannot be generalized"); } } } else { var upperBound = UpperBound == null ? type : UpperBound.Glb(rootEnv, type, changed); if (!Type.IsAssignableTo(rootEnv, upperBound)) { throw new InvalidOperationException("stack entry cannot be generalized"); } if (!upperBound.IsEquivalentTo(rootEnv, rootEnv.Global.ObjectRef)) { if (UpperBound == null) { changed.Set(); } UpperBound = upperBound; } } }