Browse Source

[Decompiler] gpt-slop copy

pull/4126/head
Marcus Mikelic 1 week ago committed by Siegfried Pammer
parent
commit
0ab608f981
  1. 5
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  2. 11
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs
  3. 9
      ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs
  4. 123
      ICSharpCode.Decompiler/IL/Instructions.cs
  5. 3
      ICSharpCode.Decompiler/IL/Instructions.tt
  6. 27
      ICSharpCode.Decompiler/IL/Transforms/CachedDelegateInitialization.cs
  7. 2
      global.json

5
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -558,6 +558,11 @@ namespace ICSharpCode.Decompiler.CSharp @@ -558,6 +558,11 @@ namespace ICSharpCode.Decompiler.CSharp
return new CallBuilder(this, typeSystem, settings).Build(inst, context.TypeHint);
}
protected internal override TranslatedExpression VisitCachedDelegate(CachedDelegate inst, TranslationContext context)
{
return Translate(inst.Argument, context.TypeHint).WithILInstruction(inst);
}
protected internal override TranslatedExpression VisitLdVirtDelegate(LdVirtDelegate inst, TranslationContext context)
{
return new CallBuilder(this, typeSystem, settings).Build(inst);

11
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -27,6 +27,7 @@ using ICSharpCode.Decompiler.CSharp.Transforms; @@ -27,6 +27,7 @@ using ICSharpCode.Decompiler.CSharp.Transforms;
using ICSharpCode.Decompiler.IL;
using ICSharpCode.Decompiler.Semantics;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.Decompiler.TypeSystem.Implementation;
using ICSharpCode.Decompiler.Util;
#nullable enable
@ -270,6 +271,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -270,6 +271,16 @@ namespace ICSharpCode.Decompiler.CSharp
else if (Expression is ObjectCreateExpression oce && conversion.Conversion.IsMethodGroupConversion
&& oce.Arguments.Count == 1 && expressionBuilder.settings.UseImplicitMethodGroupConversion)
{
// C# 11 caches static method groups. Keep explicit construction when the IL creates a fresh delegate.
if (conversion.Conversion.Method.IsStatic
&& conversion.Conversion.Method is not LocalFunctionMethod { IsStaticLocalFunction: false }
&& conversion.Conversion.Method.Parameters.Count == type.GetDelegateInvokeMethod()?.Parameters.Count
&& expressionBuilder.settings.GetMinimumRequiredVersion() >= LanguageVersion.CSharp11_0
&& expressionBuilder.currentFunction.Kind != ILFunctionKind.ExpressionTree
&& !ILInstructions.Any(i => i is CachedDelegate))
{
return this;
}
return this.UnwrapChild(oce.Arguments.Single());
}
break;

9
ICSharpCode.Decompiler/FlowAnalysis/DataFlowVisitor.cs

@ -754,6 +754,15 @@ namespace ICSharpCode.Decompiler.FlowAnalysis @@ -754,6 +754,15 @@ namespace ICSharpCode.Decompiler.FlowAnalysis
HandleBinaryWithOptionalEvaluation(inst, inst.ValueInst, inst.FallbackInst);
}
protected internal override void VisitCachedDelegate(CachedDelegate inst)
{
DebugStartPoint(inst);
State cachedState = state.Clone();
inst.Argument.AcceptVisitor(this);
state.JoinWith(cachedState);
DebugEndPoint(inst);
}
protected internal override void VisitDynamicLogicOperatorInstruction(DynamicLogicOperatorInstruction inst)
{
HandleBinaryWithOptionalEvaluation(inst, inst.Left, inst.Right);

123
ICSharpCode.Decompiler/IL/Instructions.cs

@ -177,6 +177,8 @@ namespace ICSharpCode.Decompiler.IL @@ -177,6 +177,8 @@ namespace ICSharpCode.Decompiler.IL
UnboxAny,
/// <summary>Creates an object instance and calls the constructor.</summary>
NewObj,
/// <summary>Reuses a cached delegate, evaluating the argument only when the cache is empty.</summary>
CachedDelegate,
/// <summary>Creates an array instance.</summary>
NewArr,
/// <summary>Returns the default value for a type.</summary>
@ -4580,6 +4582,103 @@ namespace ICSharpCode.Decompiler.IL @@ -4580,6 +4582,103 @@ namespace ICSharpCode.Decompiler.IL
}
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Reuses a cached delegate, evaluating the argument only when the cache is empty.</summary>
public sealed partial class CachedDelegate : ILInstruction
{
public CachedDelegate(ILInstruction argument) : base(OpCode.CachedDelegate)
{
this.Argument = argument;
}
public static readonly SlotInfo ArgumentSlot = new SlotInfo("Argument");
ILInstruction argument = null!;
public ILInstruction Argument {
get { return this.argument; }
set {
ValidateChild(value);
SetChildInstruction(ref this.argument, value, 0);
}
}
protected sealed override int GetChildCount()
{
return 1;
}
protected sealed override ILInstruction GetChild(int index)
{
switch (index)
{
case 0:
return this.argument;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override void SetChild(int index, ILInstruction value)
{
switch (index)
{
case 0:
this.Argument = value;
break;
default:
throw new IndexOutOfRangeException();
}
}
protected sealed override SlotInfo GetChildSlot(int index)
{
switch (index)
{
case 0:
return ArgumentSlot;
default:
throw new IndexOutOfRangeException();
}
}
public sealed override ILInstruction Clone()
{
var clone = (CachedDelegate)ShallowClone();
clone.Argument = this.argument.Clone();
return clone;
}
public override StackType ResultType => Argument.ResultType;
public override IType InferType(ICompilation compilation) => Argument.InferType(compilation);
protected override InstructionFlags ComputeFlags()
{
return argument.Flags | InstructionFlags.ControlFlow;
}
public override InstructionFlags DirectFlags {
get {
return InstructionFlags.ControlFlow;
}
}
protected override void WriteToCore(ITextOutput output, ILAstWritingOptions options)
{
WriteILRange(output, options);
output.Write(OpCode);
output.Write('(');
this.argument.WriteTo(output, options);
output.Write(')');
}
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitCachedDelegate(this);
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{
return visitor.VisitCachedDelegate(this);
}
public override T AcceptVisitor<C, T>(ILVisitor<C, T> visitor, C context)
{
return visitor.VisitCachedDelegate(this, context);
}
protected internal override bool PerformMatch(ILInstruction? other, ref Patterns.Match match)
{
var o = other as CachedDelegate;
return o != null && this.argument.PerformMatch(o.argument, ref match);
}
}
}
namespace ICSharpCode.Decompiler.IL
{
/// <summary>Creates an array instance.</summary>
public sealed partial class NewArr : ILInstruction
@ -7412,6 +7511,10 @@ namespace ICSharpCode.Decompiler.IL @@ -7412,6 +7511,10 @@ namespace ICSharpCode.Decompiler.IL
{
Default(inst);
}
protected internal virtual void VisitCachedDelegate(CachedDelegate inst)
{
Default(inst);
}
protected internal virtual void VisitNewArr(NewArr inst)
{
Default(inst);
@ -7822,6 +7925,10 @@ namespace ICSharpCode.Decompiler.IL @@ -7822,6 +7925,10 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst);
}
protected internal virtual T VisitCachedDelegate(CachedDelegate inst)
{
return Default(inst);
}
protected internal virtual T VisitNewArr(NewArr inst)
{
return Default(inst);
@ -8232,6 +8339,10 @@ namespace ICSharpCode.Decompiler.IL @@ -8232,6 +8339,10 @@ namespace ICSharpCode.Decompiler.IL
{
return Default(inst, context);
}
protected internal virtual T VisitCachedDelegate(CachedDelegate inst, C context)
{
return Default(inst, context);
}
protected internal virtual T VisitNewArr(NewArr inst, C context)
{
return Default(inst, context);
@ -8433,6 +8544,7 @@ namespace ICSharpCode.Decompiler.IL @@ -8433,6 +8544,7 @@ namespace ICSharpCode.Decompiler.IL
"unbox",
"unbox.any",
"newobj",
"cached.delegate",
"newarr",
"default.value",
"throw",
@ -9003,6 +9115,17 @@ namespace ICSharpCode.Decompiler.IL @@ -9003,6 +9115,17 @@ namespace ICSharpCode.Decompiler.IL
type = default(IType);
return false;
}
public bool MatchCachedDelegate([NotNullWhen(true)] out ILInstruction? argument)
{
var inst = this as CachedDelegate;
if (inst != null)
{
argument = inst.Argument;
return true;
}
argument = default(ILInstruction);
return false;
}
public bool MatchNewArr([NotNullWhen(true)] out IType? type)
{
var inst = this as NewArr;

3
ICSharpCode.Decompiler/IL/Instructions.tt

@ -287,6 +287,9 @@ @@ -287,6 +287,9 @@
Unary, HasTypeOperand, MemoryAccess, MayThrow, ResultType("this.type")),
new OpCode("newobj", "Creates an object instance and calls the constructor.",
CustomClassName("NewObj"), Call, ResultType("Method.DeclaringType")),
new OpCode("cached.delegate", "Reuses a cached delegate, evaluating the argument only when the cache is empty.",
CustomChildren(new [] { new ChildInfo("argument") }), ControlFlow,
ResultType("Argument.InferType(compilation)", "Argument.ResultType")),
new OpCode("newarr", "Creates an array instance.",
CustomClassName("NewArr"), HasTypeOperand,
CustomChildren(new [] { new ArgumentInfo("indices") { IsCollection = true } }, true),

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

@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -79,7 +79,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// }
/// ... one usage of CachedAnonMethodDelegate ...
/// =>
/// ... one usage of DelegateConstruction ...
/// ... one usage of cached.delegate(DelegateConstruction) ...
/// </summary>
bool CachedDelegateInitializationWithField(IfInstruction inst)
{
@ -101,7 +101,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -101,7 +101,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (usages.Length != 1)
return false;
context.Step("CachedDelegateInitializationWithField", inst);
usages[0].ReplaceWith(value);
usages[0].ReplaceWith(new CachedDelegate(value));
context.EndStep(value);
return true;
}
@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -111,7 +111,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc v(DelegateConstruction)
/// }
/// =>
/// stloc v(DelegateConstruction)
/// stloc v(cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationWithLocal(IfInstruction inst)
{
@ -141,6 +141,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -141,6 +141,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return false;
context.Step("CachedDelegateInitializationWithLocal", inst);
((Block)otherStore.Parent).Instructions.Remove(otherStore);
((StLoc)storeInst).Value = new CachedDelegate(value);
inst.ReplaceWith(storeInst);
context.EndStep(storeInst);
return true;
@ -152,7 +153,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -152,7 +153,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc s(stobj(ldsflda(CachedAnonMethodDelegate), DelegateConstruction))
/// }
/// =>
/// stloc s(DelegateConstruction)
/// stloc s(cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationRoslynInStaticWithLocal(IfInstruction inst)
{
@ -174,7 +175,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -174,7 +175,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!DelegateConstruction.MatchDelegateConstruction((NewObj)stobj.Value, out _, out _, out _, true))
return false;
context.Step("CachedDelegateInitializationRoslynInStaticWithLocal", inst);
storeBeforeIf.Value = stobj.Value;
storeBeforeIf.Value = new CachedDelegate(stobj.Value);
return true;
}
@ -184,7 +185,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -184,7 +185,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc s(stobj(ldflda(CachedAnonMethodDelegate), DelegateConstruction))
/// }
/// =>
/// stloc s(DelegateConstruction)
/// stloc s(cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationRoslynWithLocal(IfInstruction inst)
{
@ -206,7 +207,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -206,7 +207,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!DelegateConstruction.MatchDelegateConstruction((NewObj)stobj.Value, out _, out _, out _, true))
return false;
context.Step("CachedDelegateInitializationRoslynWithLocal", inst);
storeBeforeIf.Value = stobj.Value;
storeBeforeIf.Value = new CachedDelegate(stobj.Value);
return true;
}
@ -217,7 +218,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -217,7 +218,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc s(ldobj System.Action(ldsflda $I4-1))
/// }
/// =>
/// stloc s(DelegateConstruction)
/// stloc s(cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationVB(IfInstruction inst)
{
@ -249,7 +250,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -249,7 +250,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))
return false;
context.Step("CachedDelegateInitializationVB", inst);
var stloc = new StLoc(s, delegateConstruction);
var stloc = new StLoc(s, new CachedDelegate(delegateConstruction));
inst.ReplaceWith(stloc);
context.EndStep(stloc);
return true;
@ -261,7 +262,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -261,7 +262,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// }
/// leave IL_0005 (stsfld CachedAnonMethodDelegate(DelegateConstruction))
/// =>
/// leave IL_0005 (DelegateConstruction)
/// leave IL_0005 (cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationVBWithReturn(IfInstruction inst)
{
@ -279,7 +280,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -279,7 +280,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))
return false;
context.Step("CachedDelegateInitializationVBWithReturn", inst);
leaveAfterIf.Value = delegateConstruction;
leaveAfterIf.Value = new CachedDelegate(delegateConstruction);
return true;
}
@ -290,7 +291,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -290,7 +291,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
/// stloc s(stobj delegateType(ldflda CachedAnonMethodDelegate(ldloc closure), DelegateConstruction))
/// }
/// =>
/// stloc s(DelegateConstruction)
/// stloc s(cached.delegate(DelegateConstruction))
/// </summary>
bool CachedDelegateInitializationVBWithClosure(IfInstruction inst)
{
@ -322,7 +323,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -322,7 +323,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (!DelegateConstruction.MatchDelegateConstruction(delegateConstruction, out _, out _, out _, true))
return false;
context.Step("CachedDelegateInitializationVBWithClosure", inst);
var stloc = new StLoc(s, delegateConstruction);
var stloc = new StLoc(s, new CachedDelegate(delegateConstruction));
inst.ReplaceWith(stloc);
context.EndStep(stloc);
return true;

2
global.json

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
{
"sdk": {
"version": "11.0.0",
"version": "11.0.100-preview.7.26381.103",
"rollForward": "major",
"allowPrerelease": true
},

Loading…
Cancel
Save