예제 #1
0
        private static FieldMemoryInfo[] GetFieldsMemoryInfo(ParsedStruct pdStruct, IDictionary <string, TypeMemoryInfo> typesMemInfo)
        {
            var fieldsMemInfo = new FieldMemoryInfo[pdStruct.Fields.Length];

            for (var i = 0; i < fieldsMemInfo.Length; i++)
            {
                var pdField = pdStruct.Fields[i];
                if (!typesMemInfo.TryGetValue(pdField.Type, out var memInfo))
                {
                    throw new Exception($"Unknown field type `{pdField.Type}` defined in the struct `{pdStruct.Name}`");
                }

                fieldsMemInfo[i] = new FieldMemoryInfo(i, memInfo);
            }

            Array.Sort(fieldsMemInfo, (fieldA, fieldB) => {
                var(fieldIndexA, memInfoA) = fieldA;
                var(fieldIndexB, memInfoB) = fieldB;

                if (memInfoA.Alignment != memInfoB.Alignment)
                {
                    return(memInfoB.Alignment.CompareTo(memInfoA.Alignment));
                }

                return(fieldIndexA.CompareTo(fieldIndexB));
            });

            return(fieldsMemInfo);
        }
예제 #2
0
        private static CodeGenStruct HandleStruct(ParsedStruct pdStruct, IDictionary <string, TypeMemoryInfo> typesMemInfo)
        {
            if (pdStruct.Fields.Length == 0)
            {
                throw new Exception($"Struct `{pdStruct.Name}` is zero-sized");
            }

            var fieldsMemInfo = GetFieldsMemoryInfo(pdStruct, typesMemInfo);

            var offset = 0;
            var fields = new CodeGenField[pdStruct.Fields.Length];

            for (var i = 0; i < fields.Length; i++)
            {
                var(pdFieldIndex, memInfo) = fieldsMemInfo[i];
                var pdField = pdStruct.Fields[pdFieldIndex];

                var defaultValue = memInfo.DefaultValueInfo.WithCustomDefaultValueIfPossible(pdField.DefaultValue);
                fields[i] = new CodeGenField(pdField.Type, pdField.Name, defaultValue, offset);

                offset += memInfo.Size;
            }

            var unalignedSize = fieldsMemInfo.Sum(fmi => fmi.TypeMemoryInfo.Size);
            var alignment     = fieldsMemInfo.Max(fmi => fmi.TypeMemoryInfo.Alignment);

            var reminder = unalignedSize % alignment;
            var padding  = reminder == 0 ? 0 : alignment - reminder;
            var size     = unalignedSize + padding;

            var structDefaultValue = DefaultValueInfo.CallWriteDefaultMethod();

            typesMemInfo.Add(pdStruct.Name, new TypeMemoryInfo(size, alignment, structDefaultValue));

            return(new CodeGenStruct(pdStruct.Name, size, alignment, padding, fields));
        }