Skip to content

Commit

Permalink
Fix creation of pointer arrays (#79433)
Browse files Browse the repository at this point in the history
Creation of pointer arrays is on a similar plan to multi-dim arrays - we create them from a template type, but the template is slightly wrong. Previously, EETypeCreator would massage the bits into the correct shape, but now we mostly just copy the bits from the template. Use a more precise template for pointer arrays.

Without this, the base size and element type of pointer arrays was slightly wrong.

I'm also deleting the duplicated "use a special template for this one" logic.
  • Loading branch information
MichalStrehovsky authored Dec 9, 2022
1 parent d76ddf3 commit 8199d0a
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -658,14 +658,6 @@ public static RuntimeTypeHandle CreateEEType(TypeDesc type, TypeBuilderState sta

pTemplateEEType = templateTypeHandle.ToEETypePtr();
}
else if (type.IsMdArray || (type.IsSzArray && ((ArrayType)type).ElementType.IsPointer))
{
// Multidimensional arrays and szarrays of pointers don't implement generic interfaces and
// we don't need to do much for them in terms of type building. We can pretty much just take
// the MethodTable for any of those, massage the bits that matter (GCDesc, element type,
// component size,...) to be of the right shape and we're done.
pTemplateEEType = typeof(object[,]).TypeHandle.ToEETypePtr();
}
else
{
Debug.Assert(state.TemplateType != null && !state.TemplateType.RuntimeTypeHandle.IsNull());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ public TypeDesc TemplateType
{
if (!_templateComputed)
{
// Multidimensional arrays and szarrays of pointers don't implement generic interfaces and are special cases. They use
// Multidimensional arrays don't implement generic interfaces and are special cases. They use
// typeof(object[,]) as their template.
if (TypeBeingBuilt.IsMdArray || (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType.IsPointer))
if (TypeBeingBuilt.IsMdArray)
{
_templateType = TypeBeingBuilt.Context.ResolveRuntimeTypeHandle(typeof(object[,]).TypeHandle);
_templateTypeLoaderNativeLayout = false;
Expand All @@ -67,6 +67,17 @@ public TypeDesc TemplateType
return _templateType;
}

// Arrays of pointers don't implement generic interfaces and are special cases. They use
// typeof(char*[]) as their template.
if (TypeBeingBuilt.IsSzArray && ((ArrayType)TypeBeingBuilt).ElementType.IsPointer)
{
_templateType = TypeBeingBuilt.Context.ResolveRuntimeTypeHandle(typeof(char*[]).TypeHandle);
_templateTypeLoaderNativeLayout = false;
_nativeLayoutComputed = _nativeLayoutTokenComputed = _templateComputed = true;

return _templateType;
}

// Locate the template type and native layout info
_templateType = TemplateLocator.TryGetTypeTemplate(TypeBeingBuilt, ref _nativeLayoutInfo);
Debug.Assert(_templateType == null || !_templateType.RuntimeTypeHandle.IsNull());
Expand Down

0 comments on commit 8199d0a

Please sign in to comment.