-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Fix handling of multidimensional arrays in type system and dotnet-pgo #51764
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ | |
using System.Reflection.PortableExecutable; | ||
using Internal.TypeSystem; | ||
|
||
namespace Microsoft.Diagnostics.Tools.Pgo | ||
namespace Internal.TypeSystem | ||
{ | ||
class TypeSystemMetadataEmitter | ||
{ | ||
|
@@ -134,10 +134,8 @@ public EntityHandle GetTypeRef(TypeDesc type) | |
|
||
EntityHandle typeHandle; | ||
|
||
if (type.IsTypeDefinition) | ||
if (type.IsTypeDefinition && type is MetadataType metadataType) | ||
{ | ||
MetadataType metadataType = (MetadataType)type; | ||
|
||
// Make a typeref | ||
StringHandle typeName = _metadataBuilder.GetOrAddString(metadataType.Name); | ||
StringHandle typeNamespace = metadataType.Namespace != null ? _metadataBuilder.GetOrAddString(metadataType.Namespace) : default(StringHandle); | ||
|
@@ -293,9 +291,8 @@ private void EncodeType(BlobBuilder blobBuilder, TypeDesc type, EmbeddedSignatur | |
var arrayType = (ArrayType)type; | ||
blobBuilder.WriteByte((byte)SignatureTypeCode.Array); | ||
EncodeType(blobBuilder, type.GetParameterType(), signatureDataEmitter); | ||
var shapeEncoder = new ArrayShapeEncoder(blobBuilder); | ||
// TODO Add support for non-standard array shapes | ||
shapeEncoder.Shape(arrayType.Rank, default(ImmutableArray<int>), default(ImmutableArray<int>)); | ||
|
||
signatureDataEmitter.EmitArrayShapeAtCurrentIndexStack(blobBuilder, arrayType.Rank); | ||
} | ||
else if (type.IsPointer) | ||
{ | ||
|
@@ -386,6 +383,51 @@ public void Push() | |
} | ||
} | ||
|
||
public void EmitArrayShapeAtCurrentIndexStack(BlobBuilder signatureBuilder, int rank) | ||
{ | ||
var shapeEncoder = new ArrayShapeEncoder(signatureBuilder); | ||
|
||
bool emittedWithShape = false; | ||
|
||
if (!Complete) | ||
{ | ||
if (_embeddedDataIndex < _embeddedData.Length) | ||
{ | ||
if (_embeddedData[_embeddedDataIndex].kind == EmbeddedSignatureDataKind.ArrayShape) | ||
{ | ||
string indexData = string.Join(".", _indexStack); | ||
|
||
var arrayShapePossibility = _embeddedData[_embeddedDataIndex].index.Split('|'); | ||
if (arrayShapePossibility[0] == indexData) | ||
{ | ||
string[] boundsStr = arrayShapePossibility[1].Split(',', StringSplitOptions.RemoveEmptyEntries); | ||
string[] loBoundsStr = arrayShapePossibility[2].Split(',', StringSplitOptions.RemoveEmptyEntries); | ||
int[] bounds = new int[boundsStr.Length]; | ||
int[] loBounds = new int[loBoundsStr.Length]; | ||
|
||
for (int i = 0; i < boundsStr.Length; i++) | ||
{ | ||
bounds[i] = Int32.Parse(boundsStr[i]); | ||
} | ||
for (int i = 0; i < loBoundsStr.Length; i++) | ||
{ | ||
loBounds[i] = Int32.Parse(loBoundsStr[i]); | ||
} | ||
|
||
shapeEncoder.Shape(rank, ImmutableArray.Create(bounds), ImmutableArray.Create(loBounds)); | ||
_embeddedDataIndex++; | ||
return; | ||
} | ||
} | ||
} | ||
} | ||
|
||
if (!emittedWithShape) | ||
{ | ||
shapeEncoder.Shape(rank, ImmutableArray<int>.Empty, ImmutableArray<int>.Empty); | ||
} | ||
} | ||
|
||
public void EmitAtCurrentIndexStack(BlobBuilder signatureBuilder) | ||
{ | ||
if (!Complete) | ||
|
@@ -413,6 +455,9 @@ public void EmitAtCurrentIndexStack(BlobBuilder signatureBuilder) | |
} | ||
break; | ||
|
||
case EmbeddedSignatureDataKind.ArrayShape: | ||
return; | ||
|
||
default: | ||
throw new NotImplementedException(); | ||
} | ||
|
@@ -472,7 +517,6 @@ void EncodeMethodSignature(BlobBuilder signatureBuilder, MethodSignature sig, Em | |
|
||
signatureEncoder.MethodSignature(sigCallingConvention, genericParameterCount, isInstanceMethod); | ||
signatureBuilder.WriteCompressedInteger(sig.Length); | ||
// TODO Process custom modifiers in some way | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for my education - does deletion of this comment mean that this has been fixed independently or that we no longer care about custom modifiers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already wrote the code to handle custom modifiers a year or so ago, but never actually cleaned up this comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In particular that's what the embedded signature data stuff was written for originally. I will say that it is completely and totally incomprehensible as Michal has noted before, but it does work. And with handling of array shapes we hopefully won't ever have to touch it again. |
||
EncodeType(signatureBuilder, sig.ReturnType, signatureDataEmitter); | ||
for (int i = 0; i < sig.Length; i++) | ||
EncodeType(signatureBuilder, sig[i], signatureDataEmitter); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit - would it be useful to add assertions checking the bounds / lower bounds length against the array rank?