|
|
|
@ -278,11 +278,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -278,11 +278,11 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
inst.Value.AcceptVisitor(this); |
|
|
|
|
if (IsParameterAssignment(inst, out var displayClass, out var field, out var parameter)) { |
|
|
|
|
context.Step($"Detected parameter assignment {parameter.Name}", inst); |
|
|
|
|
displayClass.Variables.Add(field, parameter); |
|
|
|
|
displayClass.Variables.Add((IField)field.MemberDefinition, parameter); |
|
|
|
|
instructionsToRemove.Add(inst); |
|
|
|
|
} else if (IsDisplayClassAssignment(inst, out displayClass, out field, out var variable)) { |
|
|
|
|
context.Step($"Detected display-class assignment {variable.Name}", inst); |
|
|
|
|
displayClass.Variables.Add(field, variable); |
|
|
|
|
displayClass.Variables.Add((IField)field.MemberDefinition, variable); |
|
|
|
|
instructionsToRemove.Add(inst); |
|
|
|
|
} else { |
|
|
|
|
inst.Target.AcceptVisitor(this); |
|
|
|
@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -324,7 +324,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
return false; |
|
|
|
|
if (!(inst.Value.MatchLdLoc(out var v) && v.Kind == VariableKind.Parameter && v.Function == currentFunction)) |
|
|
|
|
return false; |
|
|
|
|
if (displayClass.Variables.ContainsKey(field)) |
|
|
|
|
if (displayClass.Variables.ContainsKey((IField)field.MemberDefinition)) |
|
|
|
|
return false; |
|
|
|
|
if (displayClassVar.Function != currentFunction) |
|
|
|
|
return false; |
|
|
|
@ -339,7 +339,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -339,7 +339,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
field = null; |
|
|
|
|
if (!(inst is LdFlda ldflda)) |
|
|
|
|
return false; |
|
|
|
|
field = (IField)ldflda.Field.MemberDefinition; |
|
|
|
|
field = ldflda.Field; |
|
|
|
|
return IsDisplayClassLoad(ldflda.Target, out displayClassVar) |
|
|
|
|
&& displayClasses.TryGetValue(displayClassVar, out displayClass); |
|
|
|
|
} |
|
|
|
@ -350,11 +350,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -350,11 +350,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
// Get display class info
|
|
|
|
|
if (!IsDisplayClassFieldAccess(inst, out _, out DisplayClass displayClass, out IField field)) |
|
|
|
|
return; |
|
|
|
|
// We want the specialized version, so that display-class type parameters are
|
|
|
|
|
// substituted with the type parameters from the use-site.
|
|
|
|
|
var fieldType = field.Type; |
|
|
|
|
// However, use the unspecialized member definition to make reference comparisons in dictionary possible.
|
|
|
|
|
field = (IField)field.MemberDefinition; |
|
|
|
|
if (!displayClass.Variables.TryGetValue(field, out var v)) { |
|
|
|
|
context.Step($"Introduce captured variable for {field.FullName}", inst); |
|
|
|
|
// Introduce a fresh variable for the display class field.
|
|
|
|
|
Debug.Assert(displayClass.Definition == field.DeclaringTypeDefinition); |
|
|
|
|
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, GetVariableTypeFromClosureField(field), field.Name); |
|
|
|
|
v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, fieldType, field.Name); |
|
|
|
|
v.HasInitialValue = true; |
|
|
|
|
v.CaptureScope = displayClass.CaptureScope; |
|
|
|
|
inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); |
|
|
|
@ -364,20 +369,5 @@ namespace ICSharpCode.Decompiler.IL.Transforms
@@ -364,20 +369,5 @@ namespace ICSharpCode.Decompiler.IL.Transforms
|
|
|
|
|
inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private IType GetVariableTypeFromClosureField(IField field) |
|
|
|
|
{ |
|
|
|
|
if (!(field.Type is ITypeParameter typeParameter)) |
|
|
|
|
return field.Type; |
|
|
|
|
var rootMethod = context.Function.Method; |
|
|
|
|
if (typeParameter.Owner != field.DeclaringTypeDefinition) |
|
|
|
|
return field.Type; |
|
|
|
|
if (typeParameter.Index >= rootMethod.TypeParameters.Count) { |
|
|
|
|
Debug.Assert(false, "Cannot map display-class type parameter to method type parameter"); |
|
|
|
|
return field.Type; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return rootMethod.TypeParameters[typeParameter.Index]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|