Browse Source

Fix #1609: Decompilation of cached delegate-construction with unknown delegate type.

pull/1633/head
Siegfried Pammer 6 years ago
parent
commit
679623e4c3
  1. 2
      ICSharpCode.Decompiler/IL/Instructions.cs
  2. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  3. 2
      ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs
  4. 8
      ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

2
ICSharpCode.Decompiler/IL/Instructions.cs

@ -786,7 +786,7 @@ namespace ICSharpCode.Decompiler.IL
clone.CloneVariables(); clone.CloneVariables();
return clone; return clone;
} }
public override StackType ResultType { get { return StackType.O; } } public override StackType ResultType { get { return DelegateType?.GetStackType() ?? StackType.O; } }
public override void AcceptVisitor(ILVisitor visitor) public override void AcceptVisitor(ILVisitor visitor)
{ {
visitor.VisitILFunction(this); visitor.VisitILFunction(this);

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -51,7 +51,7 @@
CustomChildren(new [] { CustomChildren(new [] {
new ChildInfo("body"), new ChildInfo("body"),
new ChildInfo("localFunctions") { IsCollection = true, Type = "ILFunction" } new ChildInfo("localFunctions") { IsCollection = true, Type = "ILFunction" }
}), CustomConstructor, CustomWriteTo, CustomComputeFlags, CustomVariableName("function"), ResultType("O") }), CustomConstructor, CustomWriteTo, CustomComputeFlags, CustomVariableName("function"), ResultType("DelegateType?.GetStackType() ?? StackType.O")
), ),
new OpCode("BlockContainer", "A container of IL blocks.", new OpCode("BlockContainer", "A container of IL blocks.",
ResultType("this.ExpectedResultType"), CustomConstructor, CustomVariableName("container"), ResultType("this.ExpectedResultType"), CustomConstructor, CustomVariableName("container"),

2
ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs

@ -68,7 +68,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false; return false;
if (!storeInst.MatchStsFld(out IField field2, out ILInstruction value) || !field.Equals(field2) || !field.IsCompilerGeneratedOrIsInCompilerGeneratedClass()) if (!storeInst.MatchStsFld(out IField field2, out ILInstruction value) || !field.Equals(field2) || !field.IsCompilerGeneratedOrIsInCompilerGeneratedClass())
return false; return false;
if (!DelegateConstruction.IsDelegateConstruction(value as NewObj, true)) if (!DelegateConstruction.IsDelegateConstruction(value.UnwrapConv(ConversionKind.Invalid) as NewObj, true))
return false; return false;
var nextInstruction = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1); var nextInstruction = inst.Parent.Children.ElementAtOrDefault(inst.ChildIndex + 1);
if (nextInstruction == null) if (nextInstruction == null)

8
ICSharpCode.Decompiler/IL/Transforms/DelegateConstruction.cs

@ -62,11 +62,13 @@ namespace ICSharpCode.Decompiler.IL.Transforms
internal static bool IsDelegateConstruction(NewObj inst, bool allowTransformed = false) internal static bool IsDelegateConstruction(NewObj inst, bool allowTransformed = false)
{ {
if (inst == null || inst.Arguments.Count != 2 || inst.Method.DeclaringType.Kind != TypeKind.Delegate) if (inst == null || inst.Arguments.Count != 2)
return false; return false;
var opCode = inst.Arguments[1].OpCode; var opCode = inst.Arguments[1].OpCode;
if (!(opCode == OpCode.LdFtn || opCode == OpCode.LdVirtFtn || (allowTransformed && opCode == OpCode.ILFunction)))
return opCode == OpCode.LdFtn || opCode == OpCode.LdVirtFtn || (allowTransformed && opCode == OpCode.ILFunction); return false;
var typeKind = inst.Method.DeclaringType.Kind;
return typeKind == TypeKind.Delegate || typeKind == TypeKind.Unknown;
} }
static bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method) static bool IsAnonymousMethod(ITypeDefinition decompiledTypeDefinition, IMethod method)

Loading…
Cancel
Save