Skip to content

Commit

Permalink
Merge pull request #448 from Washi1337/issue/447
Browse files Browse the repository at this point in the history
Handle TypeSpecification in GetImpliedMemoryLayout
  • Loading branch information
Washi1337 committed Jun 13, 2023
2 parents 1196789 + cc1e794 commit fbf148f
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 29 deletions.
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>()
}

}
}
}

0 comments on commit fbf148f

Please sign in to comment.