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 bool HasParamsArray(RootEnvironment rootEnv) { if (ValueParameters.Count > 0) { var p = ValueParameters[ValueParameters.Count - 1]; // At this point we could build a type environment by skolmezing all free type parameters, // but that seems overkill for answering such a simple question if (p.Type is ParameterTypeRef) return false; return p.Type.Style(rootEnv) is ArrayTypeStyle && p.CustomAttributes.Any(attr => attr.Type.Equals(rootEnv.Global.ParamArrayAttributeRef)); } return false; }
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; } } }
private MachineState(RootEnvironment rootEnv, int nArgs, int nLocals, InnerMachineState innerState) { RootEnv = rootEnv; this.nArgs = nArgs; this.nLocals = nLocals; this.innerState = new LogicVar<InnerMachineState>(innerState); }
public bool IsEquivalentTo(RootEnvironment rootEnv, StackEntryState other) { return Type.IsEquivalentTo(rootEnv, other.Type) && PointsTo.Lte(other.PointsTo) && other.PointsTo.Lte(PointsTo); }
// New empty stack and bottom args and locals state public MachineState(RootEnvironment rootEnv, int nArgs, int nLocals) { RootEnv = rootEnv; this.nArgs = nArgs; this.nLocals = nLocals; innerState = new LogicVar<InnerMachineState>(new InnerMachineState(nArgs, nLocals)); }
public void Unify(RootEnvironment rootEnv, InnerMachineState other, BoolRef changed) { if (Stack.Count != other.Stack.Count) throw new InvalidOperationException("stacks must have the same depth"); for (var i = 0; i < Stack.Count; i++) Stack[i].Unify(rootEnv, other.Stack[i], changed); if (Ids != null || other.Ids != null) throw new InvalidOperationException("stack slot identifiers cannot be unified"); ArgsLocalsState.Unify(other.ArgsLocalsState, changed); }
public abstract InvalidInfo ImplementableMemberRef(MessageContext ctxt, RootEnvironment rootEnv, MemberRef memberRef);
public abstract InvalidInfo ImplementableTypeRef(MessageContext ctxt, RootEnvironment rootEnv, TypeRef typeRef);
public AssemblyEnvironment Enter(RootEnvironment rootEnv) { return rootEnv.AddAssembly(this); }