Browse Source

When a constructor starts with a NOP instruction, the primary constructor check is skipped to allow some unit tests to pass.

pull/3598/head
sonyps5201314 2 months ago
parent
commit
2a887cc5fd
  1. 22
      ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

22
ICSharpCode.Decompiler/CSharp/RecordDecompiler.cs

@ -249,10 +249,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -249,10 +249,11 @@ namespace ICSharpCode.Decompiler.CSharp
var unspecializedMethod = instanceCtors[i];
var method = unspecializedMethod.Specialize(subst);
Block body = null;
bool? bodyHasLeadingNop = false;
if (mustFindChainingWithThis_Or_IsPrimaryConstructor)
{
body = DecompileBody(method);
body = DecompileBody(method, ref bodyHasLeadingNop);
if (body != null)
{
var first = body.Instructions.FirstOrDefault();
@ -286,7 +287,7 @@ namespace ICSharpCode.Decompiler.CSharp @@ -286,7 +287,7 @@ namespace ICSharpCode.Decompiler.CSharp
}
}
if (!CheckForInitPrimaryConstructor(method, unspecializedMethod, body))
if (bodyHasLeadingNop == true || !CheckForInitPrimaryConstructor(method, unspecializedMethod, body))
{
primaryConstructor = null;
primaryCtorParameterToAutoPropertyOrBackingField.Clear();
@ -313,7 +314,12 @@ namespace ICSharpCode.Decompiler.CSharp @@ -313,7 +314,12 @@ namespace ICSharpCode.Decompiler.CSharp
return false;
if (body == null)
body = DecompileBody(method);
{
bool? bodyHasLeadingNop = false;
body = DecompileBody(method, ref bodyHasLeadingNop);
if (bodyHasLeadingNop == true)
return false;
}
if (body == null)
return false;
@ -1290,6 +1296,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1290,6 +1296,11 @@ namespace ICSharpCode.Decompiler.CSharp
}
Block DecompileBody(IMethod method)
{
bool? bodyHasLeadingNop = null;
return DecompileBody(method, ref bodyHasLeadingNop);
}
Block DecompileBody(IMethod method, ref bool? bodyHasLeadingNop)
{
if (method == null || method.MetadataToken.IsNil)
return null;
@ -1306,6 +1317,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -1306,6 +1317,11 @@ namespace ICSharpCode.Decompiler.CSharp
var body = typeSystem.MainModule.MetadataFile.GetMethodBody(methodDef.RelativeVirtualAddress);
var ilReader = new ILReader(typeSystem.MainModule);
var il = ilReader.ReadIL(methodDefHandle, body, genericContext, ILFunctionKind.TopLevelFunction, cancellationToken);
if (bodyHasLeadingNop != null)
{
var preBody = il.Body is BlockContainer bc ? bc.EntryPoint ?? il.Body as Block : null;
bodyHasLeadingNop = preBody != null ? preBody.Instructions.FirstOrDefault() is Nop : false;
}
var settings = new DecompilerSettings(LanguageVersion.CSharp1);
var transforms = CSharpDecompiler.GetILTransforms();
// Remove the last couple transforms -- we don't need variable names etc. here

Loading…
Cancel
Save