private void GenerateTypeDecl(TypeDescriptor td, IndentedTextWriter tw) { if (td.IsConstrained && td.IsComplete) return; if (td.CILType.IsPrimitive) return; string tname = GetTypeDescriptorName(td); tw.Write("type " + tname + " is"); if (td.Rank > 0) { string ename = GetTypeDescriptorCompletedName(td.Element0Type); tw.WriteLine(" array(integer range <>) of " + ename + ";"); } else if (td.CILType.IsEnum) { tw.Write(" ("); string[] names = td.CILType.GetEnumNames(); bool first = true; foreach (string name in names) { if (first) first = false; else tw.Write(", "); tw.Write(MakeIDName(name)); } tw.WriteLine(");"); } else if (!td.CILType.IsPrimitive) { tw.WriteLine(); tw.Indent++; tw.WriteLine("record"); tw.Indent++; FieldInfo[] fields = td.CILType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { string fnamestr = MakeIDName(field.Name, field); TypeDescriptor ftype = td.GetFieldType(field); string ftypestr = GetTypeDescriptorCompletedName(ftype); tw.WriteLine(fnamestr + ": " + ftypestr + ";"); } tw.Indent--; tw.WriteLine("end record;"); tw.Indent--; } }
/// <summary> /// Computes a memory layout for a given type descriptor. /// </summary> /// <param name="td">type descriptor to layout</param> /// <param name="info">marshalling information</param> /// <returns>memory layout</returns> public static MemoryLayout Layout(TypeDescriptor td, IMarshalInfo info) { Type type = td.CILType; ISerializer ser = SLVSerializable.TryGetSerializer(type); if (ser != null) { object sample = td.GetSampleInstance(); return CreatePrimLayout(ser.Serialize(sample).Size, td, info); } if (ser == null && td.HasIntrinsicTypeOverride) throw new InvalidOperationException("Type " + type.Name + " has intrinsic type override but no serializer"); if (type.IsEnum) { return new EnumMemoryLayout(td, info); } if (type.IsArray) { td.AssertStatic(); TypeDescriptor elemTd = td.Element0Type; MemoryLayout elemLayout = Layout(elemTd, info); ulong subStride = elemLayout.SizeInBits; if (subStride == 0) { return new EmptyMemoryLayout(td) { Size = 0, SizeInBits = 0 }; } ulong[] strides = new ulong[type.GetArrayRank()]; ulong elemsPerWord = (ulong)info.WordSize / elemLayout.SizeInBits; ulong wordsPerElem = elemLayout.Size; if (elemsPerWord > 1) { if (info.UseArraySubWordAlignment) { if (info.UseArrayDimPow2Alignment) { elemsPerWord = MathExt.FloorPow2(elemsPerWord); subStride = info.WordSize / elemsPerWord; } } else { elemsPerWord = 1; } } ulong dimSize = (ulong)(int)td.TypeParams.Last(); ulong dimWords; if (elemsPerWord <= 1) { subStride = 0; if (info.UseArrayDimPow2Alignment) wordsPerElem = MathExt.CeilPow2(wordsPerElem); dimWords = wordsPerElem * dimSize; } else { wordsPerElem = 0; dimWords = (dimSize + elemsPerWord - 1) / elemsPerWord; } strides[strides.Length-1] = wordsPerElem; for (int i = strides.Length-2; i >= 0; i--) { if (info.UseArrayDimPow2Alignment) dimWords = MathExt.CeilPow2(dimWords); strides[i] = dimWords; dimSize = (ulong)(int)td.TypeParams[i]; dimWords *= dimSize; } return new ArrayMemoryLayout(td, info.WordSize, strides, subStride, (uint)elemsPerWord, (uint)wordsPerElem, elemLayout) { Size = dimWords, SizeInBits = dimWords * info.WordSize }; } if (type.IsValueType && !type.IsPrimitive) { StructMemoryLayout ml = new StructMemoryLayout(td); FieldInfo[] fields = type.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); ulong offset = 0; foreach (FieldInfo field in fields) { TypeDescriptor fieldTd = td.GetFieldType(field); MemoryLayout fieldLayout = Layout(fieldTd, info); FieldLocation fieldLoc = new FieldLocation(field, fieldLayout, offset); ml.AddLocation(fieldLoc); offset += fieldLayout.Size; } ml.Size = offset; ml.SizeInBits = offset * info.WordSize; return ml; } throw new InvalidOperationException("Unable to create data layout for type " + type.Name); }
private void GenerateTypeDecl(TypeDescriptor td, IndentedTextWriter tw) { if (td.IsConstrained && td.IsComplete) return; if (td.CILType.IsPrimitive) return; string tname = GetTypeDescriptorName(td); if (td.CILType.IsEnum) { tw.WriteLine("typedef enum " + tname + " {"); tw.Indent++; //tw.Write("enum " + tname + " { "); string[] names = td.CILType.GetEnumNames(); bool first = true; foreach (string name in names) { if (first) first = false; else tw.Write(", "); tw.Write(MakeIDName(name)); } tw.WriteLine("} " + ";"); //tw.Indent--; //tw.WriteLine("}"); } else if (!td.CILType.IsPrimitive) { tw.WriteLine(); //tw.Indent++; tw.WriteLine("typedef struct {"); tw.Indent++; FieldInfo[] fields = td.CILType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo field in fields) { string fnamestr = MakeIDName(field.Name, field); TypeDescriptor ftype = td.GetFieldType(field); string ftypestr = GetTypeDescriptorCompletedName(ftype); tw.WriteLine(ftypestr + " " + fnamestr + ";"); } //tw.Indent--; tw.WriteLine("} " + tname + ";"); tw.Indent--; } }