Skip to content
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

Handle TypeSpecification in GetImpliedMemoryLayout #448

Merged
merged 1 commit into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/AsmResolver.DotNet/Memory/TypeMemoryLayoutDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,16 @@ public TypeMemoryLayout VisitTypeDefOrRef(ITypeDefOrRef type)
{
TableIndex.TypeRef => VisitTypeReference((TypeReference) type),
TableIndex.TypeDef => VisitTypeDefinition((TypeDefinition) type),
TableIndex.TypeSpec => VisitTypeSpecification((TypeSpecification) type),
_ => throw new ArgumentException("Invalid type.")
};
}

private TypeMemoryLayout VisitTypeSpecification(TypeSpecification type)
{
return type.Signature!.AcceptVisitor(this);
}

private TypeMemoryLayout VisitTypeReference(TypeReference type) =>
VisitTypeDefinition(type.Resolve() ?? throw new ArgumentException(
$"Could not resolve type {type.SafeToString()}."));
Expand Down
45 changes: 26 additions & 19 deletions test/AsmResolver.DotNet.Tests/Memory/SequentialStructLayoutTest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using AsmResolver.DotNet.Memory;
using AsmResolver.PE.DotNet.Metadata.Tables.Rows;
Expand Down Expand Up @@ -51,62 +52,68 @@ public void ReferenceTypedCorLibTypeShouldReturnElementSize(ElementType elementT
[Fact]
public void MultipleFieldsSequentialStructDefaultPack() =>
VerifySize<SequentialTestStructs.MultipleFieldsSequentialStructDefaultPack>();

[Fact]
public void MultipleFieldsSequentialStructPack1() =>
VerifySize<SequentialTestStructs.MultipleFieldsSequentialStructPack1>();

[Fact]
public void LargeAndSmallFieldSequentialDefaultPack() =>
VerifySize<SequentialTestStructs.LargeAndSmallFieldSequentialDefaultPack>();

[Fact]
public void NestedStruct1() => VerifySize<SequentialTestStructs.NestedStruct1>();

[Fact]
public void NestedStruct2() => VerifySize<SequentialTestStructs.NestedStruct2>();

[Fact]
public void NestedStructWithEnclosingPack1() => VerifySize<SequentialTestStructs.NestedStructWithEnclosingPack1>();

[Fact]
public void NestedStructWithNestedPack1() => VerifySize<SequentialTestStructs.NestedStructWithNestedPack1>();

[Fact]
public void NestedStructInNestedStruct() => VerifySize<SequentialTestStructs.NestedStructInNestedStruct>();

[Fact]
public void ThreeLevelsNestingSequentialStructDefaultPack() =>
public void ThreeLevelsNestingSequentialStructDefaultPack() =>
VerifySize<SequentialTestStructs.ThreeLevelsNestingSequentialStructDefaultPack>();

[Fact]
public void ThreeLevelsNestingSequentialStructPack1() =>
public void ThreeLevelsNestingSequentialStructPack1() =>
VerifySize<SequentialTestStructs.ThreeLevelsNestingSequentialWithNestedStructPack1>();

[Fact]
public void ExplicitlySizedEmptyStruct() => VerifySize<SequentialTestStructs.ExplicitlySizedEmptyStruct>();

[Fact]
public void ExplicitlySizedSingleField() => VerifySize<SequentialTestStructs.ExplicitlySizedSingleField>();

[Fact]
public void ExplicitlySizedSmallerExplicitSizeThanActualSize() =>
VerifySize<SequentialTestStructs.ExplicitlySizedSmallerExplicitSizeThanActualSize>();

[Fact]
public void StructWithPrimitiveFieldSmallerThanPack() =>
VerifySize<SequentialTestStructs.StructWithPrimitiveFieldSmallerThanPack>();

[Fact]
public void StructWithStructFieldSmallerThanPack() =>
VerifySize<SequentialTestStructs.StructWithStructFieldSmallerThanPack>();

[Fact]
public void PackLargerThanLargestField() =>
VerifySize<SequentialTestStructs.PackLargerThanLargestField>();

[Fact]
public void PackLargerThanLargestFieldWithImplicitAlignment() =>
VerifySize<SequentialTestStructs.PackLargerThanLargestFieldWithImplicitAlignment>();

[Fact]
public void GenericStruct() => VerifySize<SequentialTestStructs.GenericStruct<int, byte>>();

[Fact]
public void GenericNestedStruct() => VerifySize<SequentialTestStructs.GenericStruct<int, byte>.NestedStruct>();
}
}
}
23 changes: 19 additions & 4 deletions test/AsmResolver.DotNet.Tests/Memory/SequentialTestStructs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public static class SequentialTestStructs
[StructLayout(LayoutKind.Sequential)]
public struct EmptyStruct
{

}

[StructLayout(LayoutKind.Sequential)]
Expand Down Expand Up @@ -134,7 +134,7 @@ public struct FixedSizeStruct133
public struct PackLargerThanLargestField
{
public FixedSizeStruct133 Field1;

public FixedSizeStruct133 Field2;
}

Expand All @@ -148,8 +148,23 @@ public struct FixedSizeStruct133WithField
public struct PackLargerThanLargestFieldWithImplicitAlignment
{
public FixedSizeStruct133WithField Field1;

public FixedSizeStruct133WithField Field2;
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct GenericStruct<T1, T2>
{
public T1 Field1;
public T2 Field2;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct NestedStruct
{
public T1 Field1;
public T2 Field2;
}
}

}
}
}
10 changes: 4 additions & 6 deletions test/AsmResolver.DotNet.Tests/Memory/StructLayoutTestBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Runtime.CompilerServices;
using AsmResolver.DotNet.Memory;
using Xunit;
Expand All @@ -17,11 +18,8 @@ protected ModuleDefinition Module
get;
}

protected TypeDefinition FindTestType(Type type)
{
return (TypeDefinition) Module.LookupMember(type.MetadataToken);
}

private ITypeDescriptor FindTestType(Type type) => Module.DefaultImporter.ImportType(type);

protected void VerifySize<T>()
{
var type = FindTestType(typeof(T));
Expand All @@ -30,4 +28,4 @@ protected void VerifySize<T>()
}

}
}
}