public void PeekWriteArrayType(int n, TypeRef expType) { var type = PeekType(n); var s = type.Style(RootEnv); if (s is NullTypeStyle) { // No-op. // If stack entry is generalized it must become an array type } else if (s is ArrayTypeStyle) { // If stack entry is generalized it must remain an array type expType = expType.ToRunTimeType(RootEnv, false); type = type.Arguments[0]; if (!expType.IsAssignableTo(RootEnv, type)) { throw new InvalidOperationException("array element type is not assignable from expected type"); } } else { // Parameter types not allowed throw new InvalidOperationException("stack entry is not an array type"); } }
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; } } }