// 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 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"); } } }
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 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 override TypeRef ToRunTimeType(RootEnvironment rootEnv, bool forStack) { var s = Style(rootEnv); if (s is PointerTypeStyle || s is ArrayTypeStyle || s is BoxTypeStyle) { return(new NamedTypeRef(Annotations, name, arguments.Select(t => t.ToRunTimeType(rootEnv, false)).ToSeq())); } var ns = s as NumberTypeStyle; if (ns != null) { return(new NamedTypeRef (rootEnv.Global.NumberFlavorToQualifiedTypeName[RuntimeFlavor(ns.Flavor, forStack)])); } if (s is EnumTypeStyle) { var typeEnv = Enter(rootEnv); var enumDef = (EnumTypeDef)typeEnv.Type; return(enumDef.Implementation.ToRunTimeType(rootEnv, forStack)); } return(this); }
public override TypeConstructorEnvironment EnterConstructor(RootEnvironment rootEnv) { var assembly = default(AssemblyDef); var type = default(TypeDef); rootEnv.PrimResolveSkolem(Index, out assembly, out type); return(rootEnv.AddAssembly(assembly).AddType(type)); }
public TypeRef ToCodePointer(RootEnvironment rootEnv) { var methEnv = EnterMethod(rootEnv); var valueParameters = methEnv.SubstituteTypes(ValueParameters); var result = Result == null ? null : methEnv.SubstituteType(Result); return(TypeRef.CodePointerFrom(rootEnv.Global, valueParameters, result)); }
public override MemberRef Generalize(RootEnvironment rootEnv) { var methodTypeArguments = default(Seq <TypeRef>); if (MethodTypeArguments.Count > 0) { methodTypeArguments = MethodTypeArguments.Select(t => t.Generalize(rootEnv)).ToSeq(); } return(new MethodRef(Annotations, DefiningType.Generalize(rootEnv), signature, methodTypeArguments)); }
public PolymorphicMethodEnvironment Enter(RootEnvironment rootEnv) { var typeEnv = DefiningType.Enter(rootEnv); var methodDef = typeEnv.Type.ResolveMethod(signature); if (methodDef == null) { throw new InvalidOperationException("unable to resolve polymorphic method reference"); } return(typeEnv.AddMethod(methodDef)); }
public TypeConstructorEnvironment Enter(RootEnvironment rootEnv) { var assemblyDef = default(AssemblyDef); var typeDef = default(TypeDef); if (!PrimTryResolve(rootEnv.Global, out assemblyDef, out typeDef)) { throw new InvalidOperationException("unable to resolve qualified type name"); } return(rootEnv.AddAssembly(assemblyDef).AddType(typeDef)); }
public FieldEnvironment Enter(RootEnvironment rootEnv) { var typeEnv = DefiningType.Enter(rootEnv); var fieldDef = typeEnv.Type.ResolveField(signature); if (fieldDef == null) { throw new InvalidOperationException("unable to resolve field reference"); } return(typeEnv.AddField(fieldDef)); }
public PropertyEnvironment Enter(RootEnvironment rootEnv) { var typeEnv = DefiningType.Enter(rootEnv); var propDef = typeEnv.Type.ResolveProperty(signature); if (propDef == null) { throw new InvalidOperationException("unable to resolve property reference"); } return(typeEnv.AddProperty(propDef)); }
public EventEnvironment Enter(RootEnvironment rootEnv) { var typeEnv = DefiningType.Enter(rootEnv); var eventDef = typeEnv.Type.ResolveEvent(signature); if (eventDef == null) { throw new InvalidOperationException("unable to resolve event reference"); } return(typeEnv.AddEvent(eventDef)); }
// // Subtyping // internal bool PrimIsAssignableTo(RootEnvironment groundEnv, TypeRef otherGround) { var thisTypeEnv = Enter(groundEnv); var otherTypeEnv = otherGround.Enter(groundEnv); return(thisTypeEnv.Type.PrimInstanceIsAssignableTo (groundEnv, thisTypeEnv.Assembly, Arguments, otherTypeEnv.Assembly, otherTypeEnv.Type, otherGround.Arguments)); }
public bool IsAssignableTo(RootEnvironment rootEnv, TypeRef other) { var thisTypeEnv = Enter(rootEnv); var otherTypeEnv = other.Enter(rootEnv); return(thisTypeEnv.Type.PrimInstanceIsAssignableTo (rootEnv.ToGround(), thisTypeEnv.Assembly, thisTypeEnv.TypeBoundArguments, otherTypeEnv.Assembly, otherTypeEnv.Type, otherTypeEnv.TypeBoundArguments)); }
public MethodEnvironment EnterMethod(RootEnvironment rootEnv) { var typeEnv = DefiningType.Enter(rootEnv); var methodDef = typeEnv.Type.ResolveMethod(signature); if (methodDef == null) { throw new InvalidOperationException("unable to resolve method reference"); } var groundArguments = rootEnv.SubstituteTypes(MethodTypeArguments); return(typeEnv.AddMethod(methodDef).AddMethodBoundArguments(groundArguments)); }
public override TypeStyle Style(RootEnvironment rootEnv) { var assembly = default(AssemblyDef); var type = default(TypeDef); if (name.PrimTryResolve(rootEnv.Global, out assembly, out type)) { return(type.Style); } else { throw new InvalidOperationException("unable to resolve type"); } }
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 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); }
// Redirect to method which introduced slot public MethodRef ToOverriddenMethod(RootEnvironment rootEnv) { var polyMethEnv = Enter(rootEnv); if (polyMethEnv.Method.IsOverriding) { var polyRef = polyMethEnv.SubstituteMember(polyMethEnv.Type.OverriddenMethod(signature)); return(new MethodRef (polyRef.DefiningType, polyRef.Name, polyRef.IsStatic, MethodTypeArguments, polyRef.ValueParameters, polyRef.Result)); } else { return(this); } }
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; } } }
public TypeRef Lub(RootEnvironment rootEnv, TypeRef other) { if (IsAssignableTo(rootEnv, other)) { return(other); } else if (other.IsAssignableTo(rootEnv, this)) { return(this); } else { // NOTE: According to the CLR spec we should try to find a least common interface. // However, we'll try Object, which may not be the least but is at least safe. if (IsAssignableTo(rootEnv, rootEnv.Global.ObjectRef) && other.IsAssignableTo(rootEnv, rootEnv.Global.ObjectRef)) { return(rootEnv.Global.ObjectRef); } else { throw new InvalidOperationException("types have no lub"); } } }
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 TypeRef Glb(RootEnvironment rootEnv, TypeRef other) { if (IsAssignableTo(rootEnv, other)) { return(this); } else if (other.IsAssignableTo(rootEnv, this)) { return(other); } else { // NOTE: Try null: may not be greatest but is safe. if (rootEnv.Global.NullRef.IsAssignableTo(rootEnv, this) && rootEnv.Global.NullRef.IsAssignableTo(rootEnv, other)) { return(rootEnv.Global.NullRef); } else { throw new InvalidOperationException("types have no glb"); } } }
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 override MemberRef Generalize(RootEnvironment rootEnv) { return(new EventRef(Annotations, DefiningType.Generalize(rootEnv), signature)); }
internal override InvalidInfo CheckValid(ValidityContext vctxt, MessageContext ctxt, RootEnvironment rootEnv) { var v = base.CheckValid(vctxt, ctxt, rootEnv); if (v != null) { return(v); } var typeEnv = DefiningType.Enter(rootEnv); var eventDef = typeEnv.Type.ResolveMember(signature); if (eventDef == null) { throw new InvalidOperationException("unable to resolve event"); } v = signature.CheckValid(vctxt, ctxt, typeEnv); if (v != null) { return(v); } return(vctxt.ImplementableMemberRef(ctxt, rootEnv, this)); }
public bool IsEquivalentTo(RootEnvironment rootEnv, StackEntryState other) { return Type.IsEquivalentTo(rootEnv, other.Type) && PointsTo.Lte(other.PointsTo) && other.PointsTo.Lte(PointsTo); }
public abstract InvalidInfo ImplementableTypeRef(MessageContext ctxt, RootEnvironment rootEnv, TypeRef typeRef);
public abstract InvalidInfo ImplementableMemberRef(MessageContext ctxt, RootEnvironment rootEnv, MemberRef memberRef);
public AssemblyEnvironment Enter(RootEnvironment rootEnv) { return rootEnv.AddAssembly(this); }
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); }
internal override InvalidInfo CheckValid(ValidityContext vctxt, MessageContext ctxt, RootEnvironment rootEnv) { var v = base.CheckValid(vctxt, ctxt, rootEnv); if (v != null) { return(v); } if (MethodTypeArguments.Count != MethodTypeArity) { vctxt.Log (new InvalidMemberRef (ctxt, this, String.Format ("Polymorphic method has {0} type parameters but is applied to {1} type arguments", MethodTypeArity, MethodTypeArguments.Count))); return(new InvalidInfo(MessageContextBuilders.Member(vctxt.Global, this))); } v = MethodTypeArguments.Select(t => t.CheckValid(vctxt, ctxt, rootEnv)).FirstOrDefault(v2 => v2 != null); if (v != null) { return(v); } var groundMethodTypeArguments = rootEnv.SubstituteTypes(MethodTypeArguments); var typeEnv = DefiningType.Enter(rootEnv); var methodDef = typeEnv.Type.ResolveMethod(signature); if (methodDef == null) { throw new InvalidOperationException("unable to resolve method"); } var methEnv = typeEnv.AddMethod(methodDef).AddMethodBoundArguments(groundMethodTypeArguments); return(signature.CheckValid(vctxt, ctxt, methEnv)); }
public bool IsEquivalentTo(RootEnvironment rootEnv, StackEntryState other) { return(Type.IsEquivalentTo(rootEnv, other.Type) && PointsTo.Lte(other.PointsTo) && other.PointsTo.Lte(PointsTo)); }
private MachineState(RootEnvironment rootEnv, int nArgs, int nLocals, InnerMachineState innerState) { RootEnv = rootEnv; this.nArgs = nArgs; this.nLocals = nLocals; this.innerState = new LogicVar<InnerMachineState>(innerState); }
// 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 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; } } }
internal override InvalidInfo CheckValid(ValidityContext vctxt, MessageContext ctxt, RootEnvironment rootEnv) { var v = base.CheckValid(vctxt, ctxt, rootEnv); if (v != null) { return(v); } var typeEnv = DefiningType.Enter(rootEnv); var methodDef = typeEnv.Type.ResolveMethod(signature); if (methodDef == null) { vctxt.Log(new InvalidMemberRef(ctxt, this, "No such method in defining type")); return(new InvalidInfo(MessageContextBuilders.Member(vctxt.Global, this))); } var methEnv = typeEnv.AddMethod(methodDef).AddSelfMethodBoundArguments(); v = signature.CheckValid(vctxt, ctxt, methEnv); if (v != null) { return(v); } return(vctxt.ImplementableMemberRef(ctxt, rootEnv, this)); }