Browse Source

Add AggressiveScalarReplacementOfAggregates option

pull/2005/head
Siegfried Pammer 5 years ago
parent
commit
f1cbc7c8db
  1. 14
      ICSharpCode.Decompiler/DecompilerSettings.cs
  2. 3
      ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs
  3. 59
      ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs
  4. 9
      ILSpy/Properties/Resources.Designer.cs
  5. 3
      ILSpy/Properties/Resources.resx

14
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -1311,6 +1311,20 @@ namespace ICSharpCode.Decompiler @@ -1311,6 +1311,20 @@ namespace ICSharpCode.Decompiler
}
}
bool aggressiveScalarReplacementOfAggregates = false;
[Category("DecompilerSettings.Other")]
[Description("DecompilerSettings.AggressiveScalarReplacementOfAggregates")]
public bool AggressiveScalarReplacementOfAggregates {
get { return aggressiveScalarReplacementOfAggregates; }
set {
if (aggressiveScalarReplacementOfAggregates != value) {
aggressiveScalarReplacementOfAggregates = value;
OnPropertyChanged();
}
}
}
CSharpFormattingOptions csharpFormattingOptions;
[Browsable(false)]

3
ICSharpCode.Decompiler/IL/Instructions/ILVariableCollection.cs

@ -102,6 +102,9 @@ namespace ICSharpCode.Decompiler.IL @@ -102,6 +102,9 @@ namespace ICSharpCode.Decompiler.IL
{
for (int i = 0; i < list.Count;) {
var v = list[i];
// Note: we cannot remove display-class locals from the collection,
// even if they are unused - which is always the case, if TDCU succeeds,
// because they are necessary for PDB generation to produce correct results.
if (v.IsDead && v.Kind != VariableKind.DisplayClassLocal) {
RemoveAt(i);
} else {

59
ICSharpCode.Decompiler/IL/Transforms/TransformDisplayClassUsage.cs

@ -20,6 +20,9 @@ using System; @@ -20,6 +20,9 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection.Metadata;
using ICSharpCode.Decompiler.Disassembler;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.Util;
@ -197,8 +200,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -197,8 +200,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms
} else {
definition = null;
}
if (definition?.DeclaringTypeDefinition == null || definition.ParentModule.PEFile != context.PEFile)
if (definition == null)
return null;
if (!context.Settings.AggressiveScalarReplacementOfAggregates) {
if (definition.DeclaringTypeDefinition == null || definition.ParentModule.PEFile != context.PEFile)
return null;
if (!IsPotentialClosure(context, definition))
return null;
}
DisplayClass result;
switch (definition.Kind) {
case TypeKind.Class:
@ -206,8 +215,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -206,8 +215,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return null;
if (!(v.StoreInstructions[0] is StLoc stloc))
return null;
// TODO thoroughly validate ctor
if (!(stloc.Value is NewObj newObj && newObj.Method.Parameters.Count == 0))
if (!(stloc.Value is NewObj newObj && ValidateConstructor(newObj.Method)))
return null;
result = new DisplayClass(v, definition) {
CaptureScope = v.CaptureScope,
@ -256,6 +264,42 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -256,6 +264,42 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return result;
}
private bool ValidateConstructor(IMethod method)
{
if (method.Parameters.Count != 0)
return false;
var handle = (MethodDefinitionHandle)method.MetadataToken;
var module = (MetadataModule)method.ParentModule;
var file = module.PEFile;
if (handle.IsNil || file == null)
return false;
var def = file.Metadata.GetMethodDefinition(handle);
if (def.RelativeVirtualAddress == 0)
return false;
var body = file.Reader.GetMethodBody(def.RelativeVirtualAddress);
if (!body.LocalSignature.IsNil)
return false;
var reader = body.GetILReader();
if (reader.Length != 7)
return false;
// IL_0000: ldarg.0
// IL_0001: call instance void [mscorlib]System.Object::.ctor()
// IL_0006: ret
if (reader.DecodeOpCode() != ILOpCode.Ldarg_0)
return false;
if (reader.DecodeOpCode() != ILOpCode.Call)
return false;
var baseCtorHandle = MetadataTokenHelpers.EntityHandleOrNil(reader.ReadInt32());
if (baseCtorHandle.IsNil)
return false;
var objectCtor = module.ResolveMethod(baseCtorHandle, new TypeSystem.GenericContext());
if (!objectCtor.DeclaringType.IsKnownType(KnownTypeCode.Object))
return false;
if (objectCtor.Parameters.Count != 0)
return false;
return reader.DecodeOpCode() == ILOpCode.Ret;
}
VariableToDeclare AddVariable(DisplayClass result, ILInstruction init, out IField field)
{
if (!init.MatchStFld(out var target, out field, out var value))
@ -399,15 +443,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -399,15 +443,6 @@ namespace ICSharpCode.Decompiler.IL.Transforms
}
}
internal static bool IsSimpleDisplayClass(IType type)
{
if (!type.HasGeneratedName() || (!type.Name.Contains("DisplayClass") && !type.Name.Contains("AnonStorey")))
return false;
if (type.DirectBaseTypes.Any(t => !t.IsKnownType(KnownTypeCode.Object)))
return false;
return true;
}
internal static bool IsPotentialClosure(ILTransformContext context, NewObj inst)
{
var decompilationContext = new SimpleTypeResolveContext(context.Function.Ancestors.OfType<ILFunction>().Last().Method);

9
ILSpy/Properties/Resources.Designer.cs generated

@ -576,6 +576,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -576,6 +576,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Aggressively perform Scalar Replacement Of Aggregates (SROA).
/// </summary>
public static string DecompilerSettings_AggressiveScalarReplacementOfAggregates {
get {
return ResourceManager.GetString("DecompilerSettings.AggressiveScalarReplacementOfAggregates", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Allow extension &apos;Add&apos; methods in collection initializer expressions.
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -864,4 +864,7 @@ Do you want to continue?</value> @@ -864,4 +864,7 @@ Do you want to continue?</value>
<data name="CultureLabel" xml:space="preserve">
<value>Culture</value>
</data>
<data name="DecompilerSettings.AggressiveScalarReplacementOfAggregates" xml:space="preserve">
<value>Aggressively perform Scalar Replacement Of Aggregates (SROA)</value>
</data>
</root>
Loading…
Cancel
Save