예제 #1
0
 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");
         }
     }
 }
예제 #2
0
        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;
        }
예제 #3
0
        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));
        }
예제 #4
0
 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);
 }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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);
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
 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);
 }
예제 #9
0
        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;
                }
            }
        }