public static int GetExactSize(this TypeSig type) { if (type.ElementType == ElementType.ValueType) { var typeDefOrRef = type.TryGetTypeDefOrRef(); var typeDef = typeDefOrRef.ResolveTypeDef(); if (typeDef != null) { var typeSize = 0; if (typeDef.IsEnum) { typeSize = TypeList.GetExactSize(typeDef.GetEnumUnderlyingType().GetStackValueKind()); } else { foreach (var field in typeDef.Fields) { if (field.FieldOffset.HasValue) { Debug.Assert(typeSize == field.FieldOffset.Value); } field.FieldOffset = (uint)typeSize; typeSize += GetExactSize(field.FieldType); } } return(typeSize); } else { throw new Exception("Could not resolve type def"); } } else { if (type.ElementType == ElementType.Class) { var typeDefOrRef = type.TryGetTypeDefOrRef(); var typeDef = typeDefOrRef.ResolveTypeDef(); if (typeDef != null) { typeDef.ClassSize = 0; foreach (var field in typeDef.Fields) { field.FieldOffset = typeDef.ClassSize; typeDef.ClassSize += (uint)GetExactSize(field.FieldType); } } } return(TypeList.GetExactSize(type.GetStackValueKind())); } }
static private int FixupCallStructReturn(TypeSig returnType, List <StackEntry> arguments, IILImporterProxy importer, bool hasThis) { // Create temp var lclNum = importer.GrabTemp(returnType.GetStackValueKind(), returnType.GetExactSize()); var returnBufferPtr = new LocalVariableAddressEntry(lclNum); // Ensure return buffer parameter goes after the this parameter if present var returnBufferArgPos = hasThis ? 1 : 0; arguments.Insert(returnBufferArgPos, returnBufferPtr); return(lclNum); }