/// <summary> /// Returns the number of least significant bits in the representation of field.Type that should be ignored when reading or writing the field value at MemberHelper.GetFieldOffset(field). /// </summary> /// <param name="field">The bit field whose bit offset is to returned.</param> public static uint GetFieldBitOffset(IFieldDefinition field) //^ requires field.IsBitField; { ITypeDefinition typeDefinition = field.ContainingTypeDefinition; uint result = 0; ushort bitFieldAlignment = 0; uint bitOffset = 0; IEnumerable <ITypeDefinitionMember> members = typeDefinition.Members; if (typeDefinition.Layout == LayoutKind.Sequential) { List <IFieldDefinition> fields = new List <IFieldDefinition>(IteratorHelper.GetFilterEnumerable <ITypeDefinitionMember, IFieldDefinition>(members)); fields.Sort(delegate(IFieldDefinition f1, IFieldDefinition f2) { return(f1.SequenceNumber - f2.SequenceNumber); }); members = IteratorHelper.GetConversionEnumerable <IFieldDefinition, ITypeDefinitionMember>(fields); } foreach (ITypeDefinitionMember member in members) { IFieldDefinition /*?*/ f = member as IFieldDefinition; if (f == null || f.IsStatic) { continue; } ushort fieldAlignment = (ushort)(TypeHelper.TypeAlignment(f.Type.ResolvedType) * 8); if (f == field) { if (f.IsBitField) { if (bitOffset > 0 && bitOffset + f.BitLength > bitFieldAlignment) { bitOffset = 0; } return(bitOffset); } return(0); } uint fieldSize; if (f.IsBitField) { bitFieldAlignment = fieldAlignment; fieldSize = f.BitLength; if (bitOffset > 0 && bitOffset + fieldSize > fieldAlignment) { bitOffset = 0; } if (bitOffset == 0 || fieldSize == 0) { result = ((result + fieldAlignment - 1) / fieldAlignment) * fieldAlignment; bitOffset = 0; } bitOffset += fieldSize; } else { if (bitFieldAlignment > fieldAlignment) { fieldAlignment = bitFieldAlignment; } bitFieldAlignment = 0; bitOffset = 0; result = ((result + fieldAlignment - 1) / fieldAlignment) * fieldAlignment; fieldSize = TypeHelper.SizeOfType(f.Type.ResolvedType) * 8; } result += fieldSize; } //^ assume false; //TODO: eventually prove this. return(0); }
/// <summary> /// Returns the number of bytes that separate the start of an instance of the items's declaring type from the start of the field itself. /// </summary> /// <param name="item">The item (field or nested type) of interests, which must not be static. </param> /// <param name="containingTypeDefinition">The type containing the item.</param> /// <returns></returns> public static uint ComputeFieldOffset(ITypeDefinitionMember item, ITypeDefinition containingTypeDefinition) //^ requires !field.IsStatic; { uint result = 0; ushort bitFieldAlignment = 0; uint bitOffset = 0; IEnumerable <ITypeDefinitionMember> members = containingTypeDefinition.Members; if (containingTypeDefinition.Layout == LayoutKind.Sequential) { List <IFieldDefinition> fields = new List <IFieldDefinition>(IteratorHelper.GetFilterEnumerable <ITypeDefinitionMember, IFieldDefinition>(members)); fields.Sort(delegate(IFieldDefinition f1, IFieldDefinition f2) { return(f1.SequenceNumber - f2.SequenceNumber); }); members = IteratorHelper.GetConversionEnumerable <IFieldDefinition, ITypeDefinitionMember>(fields); } foreach (ITypeDefinitionMember member in members) { INestedTypeDefinition fieldAsTypeDef = member as INestedTypeDefinition; if (fieldAsTypeDef != null && fieldAsTypeDef == item) { ushort typeAlignment = (ushort)(TypeHelper.TypeAlignment(fieldAsTypeDef.ResolvedType) * 8); return((((result + typeAlignment - 1) / typeAlignment) * typeAlignment) / 8); } else { IFieldDefinition /*?*/ f = member as IFieldDefinition; if (f == null || f.IsStatic) { continue; } if (f.Type.ResolvedType == item) { continue; // in case we are calculating the offset of an anonymous type, skip the implicit field of that type } ushort fieldAlignment = (ushort)(TypeHelper.TypeAlignment(f.Type.ResolvedType) * 8); if (f == item) { if (f.IsBitField && bitOffset > 0 && bitOffset + f.BitLength <= bitFieldAlignment) { return((result - bitOffset) / 8); } if (bitFieldAlignment > fieldAlignment) { fieldAlignment = bitFieldAlignment; } return((((result + fieldAlignment - 1) / fieldAlignment) * fieldAlignment) / 8); } uint fieldSize; if (f.IsBitField) { bitFieldAlignment = fieldAlignment; fieldSize = f.BitLength; if (bitOffset > 0 && bitOffset + fieldSize > fieldAlignment) { bitOffset = 0; } if (bitOffset == 0 || fieldSize == 0) { result = ((result + fieldAlignment - 1) / fieldAlignment) * fieldAlignment; bitOffset = 0; } bitOffset += fieldSize; } else { if (bitFieldAlignment > fieldAlignment) { fieldAlignment = bitFieldAlignment; } bitFieldAlignment = 0; bitOffset = 0; result = ((result + fieldAlignment - 1) / fieldAlignment) * fieldAlignment; fieldSize = TypeHelper.SizeOfType(f.Type.ResolvedType) * 8; } result += fieldSize; } } return(0); }
/// <summary> /// Returns a sequence of descriptors that define where try blocks and their associated handlers can be found in the instruction sequence. /// </summary> public IEnumerable <IOperationExceptionInformation> GetOperationExceptionInformation() { return(IteratorHelper.GetConversionEnumerable <ExceptionHandler, IOperationExceptionInformation>(this.handlers)); }