Esempio n. 1
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);
        }
Esempio n. 2
0
        /// <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);
        }