diff options
author | dotnet-bot <dotnet-bot@microsoft.com> | 2017-09-19 00:09:12 +0300 |
---|---|---|
committer | dotnet-bot <dotnet-bot@microsoft.com> | 2017-09-19 00:09:12 +0300 |
commit | 792a29f98a0100948bdcaa38cff9094d6fe5436b (patch) | |
tree | a1af36b0f05ac3a183bab28bcdead9053167ec4b /src/ILCompiler.Compiler | |
parent | 1847508ddfaa0c89a21f3d5be26bcafb71c3ba6a (diff) |
ProjectX: Add real element type and element count to preinitialized data for array fields
For static array fields, the real element type which can be a descendent of the declaring type must be added to the preinitilizeded data. The element count should also be there.
[tfs-changeset: 1674701]
Diffstat (limited to 'src/ILCompiler.Compiler')
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs | 2 | ||||
-rw-r--r-- | src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs | 82 |
2 files changed, 51 insertions, 33 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs index 5d8c57257..8a5025102 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/FrozenArrayNode.cs @@ -45,7 +45,7 @@ namespace ILCompiler.DependencyAnalysis private IEETypeNode GetEETypeNode(NodeFactory factory) { - var fieldType = _preInitFieldInfo.Field.FieldType; + var fieldType = _preInitFieldInfo.Type; var node = factory.ConstructedTypeSymbol(fieldType); Debug.Assert(!node.RepresentsIndirectionCell); // Array are always local return node; diff --git a/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs b/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs index 51b19c2fc..46b7b98e8 100644 --- a/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs +++ b/src/ILCompiler.Compiler/src/Compiler/PreInitFieldInfo.cs @@ -96,11 +96,21 @@ namespace ILCompiler public FieldDesc Field { get; } /// <summary> + /// The type of the real field data. This could be a subtype of the field type. + /// </summary> + public TypeDesc Type { get; } + + /// <summary> /// Points to the underlying contents of the data. /// </summary> public byte[] Data { get; } /// <summary> + /// Start offset of the real contents in the data. + /// </summary> + public int Offset { get; } + + /// <summary> /// Number of elements, if this is a frozen array. /// </summary> public int Length { get; } @@ -111,10 +121,12 @@ namespace ILCompiler /// </summary> private List<PreInitFixupInfo> FixupInfos; - public PreInitFieldInfo(FieldDesc field, byte[] data, int length, List<PreInitFixupInfo> fixups) + public PreInitFieldInfo(FieldDesc field, TypeDesc type, byte[] data, int offset, int length, List<PreInitFixupInfo> fixups) { Field = field; + Type = type; Data = data; + Offset = offset; Length = length; FixupInfos = fixups; @@ -124,7 +136,7 @@ namespace ILCompiler public void WriteData(ref ObjectDataBuilder builder, NodeFactory factory) { - int offset = 0; + int offset = Offset; if (FixupInfos != null) { @@ -145,7 +157,7 @@ namespace ILCompiler FixupInfos[i].WriteData(ref builder, factory); // move pointer past the fixup - offset = builder.CountBytes - startOffset; + offset = Offset + builder.CountBytes - startOffset; } } @@ -227,39 +239,15 @@ namespace ILCompiler throw new NotSupportedException(); var rvaData = ecmaDataField.GetFieldRvaData(); - var fieldType = field.FieldType; - int elementCount; - if (fieldType.IsValueType || fieldType.IsPointer) - { - elementCount = -1; - } - else if (field.FieldType.IsSzArray) - { - var arrType = (ArrayType)field.FieldType; - - int elementSize = arrType.ElementType.GetElementSize().AsInt; - if (rvaData.Length % elementSize != 0) - { - if (rvaData.Length != 1) - { - // rvaData = 1 can be a special case where it has 0 size but type system will treat it as size 1 - throw new BadImageFormatException(); - } - } - - elementCount = rvaData.Length / elementSize; - } - else - { - throw new NotSupportedException(); - } + int realDataOffset; + TypeDesc realDataType = null; // // Construct fixups // - List<PreInitFixupInfo> fixups = null; + List<PreInitFixupInfo> fixups = null; var typeFixupAttrs = ecmaDataField.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "TypeHandleFixupAttribute"); foreach (var typeFixupAttr in typeFixupAttrs) @@ -284,7 +272,15 @@ namespace ILCompiler fixups = fixups ?? new List<PreInitFixupInfo>(); - fixups.Add(new PreInitTypeFixupInfo(offset, fixupType)); + if (offset == 0 && fieldType.IsSzArray) + { + // For array field, offset 0 is the element type handle followed by the element count + realDataType = fixupType; + } + else + { + fixups.Add(new PreInitTypeFixupInfo(offset, fixupType)); + } } var methodFixupAttrs = ecmaDataField.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "MethodAddrFixupAttribute"); @@ -337,8 +333,30 @@ namespace ILCompiler fixups.Add(new PreInitFieldFixupInfo(offset, fixupField)); } + + if (fieldType.IsValueType || fieldType.IsPointer) + { + elementCount = -1; + realDataOffset = 0; + realDataType = fieldType; + } + else if (fieldType.IsSzArray) + { + // Offset 0 is the element type handle fixup followed by the element count + if (realDataType == null) + throw new BadImageFormatException(); + + int ptrSize = fieldType.Context.Target.PointerSize; + elementCount = rvaData[ptrSize] | rvaData[ptrSize + 1] << 8 | rvaData[ptrSize + 2] << 16 | rvaData[ptrSize + 3] << 24; + realDataOffset = ptrSize * 2; + realDataType = realDataType.MakeArrayType(); + } + else + { + throw new NotSupportedException(); + } - return new PreInitFieldInfo(field, rvaData, elementCount, fixups); + return new PreInitFieldInfo(field, realDataType, rvaData, realDataOffset, elementCount, fixups); } public static int FieldDescCompare(PreInitFieldInfo fieldInfo1, PreInitFieldInfo fieldInfo2) |