Skip to content

Commit

Permalink
BUGFIX: Define methods before references to allow for method def memb…
Browse files Browse the repository at this point in the history
…erref parents.
  • Loading branch information
Washi1337 committed Feb 11, 2023
1 parent b17c191 commit caeef35
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
18 changes: 11 additions & 7 deletions src/AsmResolver.DotNet/Builder/DotNetDirectoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,15 @@ public virtual DotNetDirectoryBuildResult CreateDotNetDirectory(

// All types defs and refs are added to the buffer at this point. We can therefore safely start adding
// TypeSpecs if they need to be preserved:
ImportTypeSpecsAndMemberRefsIfSpecified(module, buffer);
ImportTypeSpecsIfSpecified(module, buffer);

// Define all members in the added types.
buffer.DefineFields(discoveryResult.Fields);
// We need to define method definitions before member references, since member references can have method
// definitions in their parent.
buffer.DefineMethods(discoveryResult.Methods);
ImportMemberRefsIfSpecified(module, buffer);

// Define all remaining members in the added types.
buffer.DefineFields(discoveryResult.Fields);
buffer.DefineProperties(discoveryResult.Properties);
buffer.DefineEvents(discoveryResult.Events);
buffer.DefineParameters(discoveryResult.Parameters);
Expand Down Expand Up @@ -240,17 +244,17 @@ private void ImportBasicTablesIfSpecified(ModuleDefinition module, DotNetDirecto
}
}

private void ImportTypeSpecsAndMemberRefsIfSpecified(ModuleDefinition module, DotNetDirectoryBuffer buffer)
private void ImportTypeSpecsIfSpecified(ModuleDefinition module, DotNetDirectoryBuffer buffer)
{
if (module.DotNetDirectory is null)
return;

if ((MetadataBuilderFlags & MetadataBuilderFlags.PreserveTypeSpecificationIndices) != 0)
{
ImportTables<TypeSpecification>(module, TableIndex.TypeSpec,
s => buffer.AddTypeSpecification(s, true));
}
}

private void ImportMemberRefsIfSpecified(ModuleDefinition module, DotNetDirectoryBuffer buffer)
{
if ((MetadataBuilderFlags & MetadataBuilderFlags.PreserveMemberReferenceIndices) != 0)
{
ImportTables<MemberReference>(module, TableIndex.MemberRef,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,5 +99,26 @@ public void PreserveDuplicatedTypeRefs()
newReferences.Select(r => r.MetadataToken).ToHashSet());
}

[Fact]
public void PreserveMethodDefinitionParents()
{
var module = ModuleDefinition.FromBytes(Properties.Resources.ArgListTest);
var reference = (MemberReference) module.ManagedEntryPointMethod!.CilMethodBody!
.Instructions.First(i => i.OpCode.Code == CilCode.Call)
.Operand!;


var newModule = RebuildAndReloadModule(module,
MetadataBuilderFlags.PreserveMemberReferenceIndices
| MetadataBuilderFlags.PreserveMethodDefinitionIndices);
var newReference = (MemberReference) newModule.ManagedEntryPointMethod!.CilMethodBody!
.Instructions.First(i => i.OpCode.Code == CilCode.Call)
.Operand!;

Assert.IsAssignableFrom<MethodDefinition>(reference.Parent);
Assert.IsAssignableFrom<MethodDefinition>(newReference.Parent);
Assert.Equal(reference.Parent.Name, newReference.Parent.Name);
}

}
}

0 comments on commit caeef35

Please sign in to comment.