|
|
@ -66,6 +66,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
protected internal override void VisitLdObj(LdObj inst) |
|
|
|
{ |
|
|
|
base.VisitLdObj(inst); |
|
|
|
AddressOfLdLocToLdLoca(inst, context); |
|
|
|
LdObjToLdLoc(inst, context); |
|
|
|
} |
|
|
|
|
|
|
@ -83,6 +84,27 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
internal static void AddressOfLdLocToLdLoca(LdObj inst, ILTransformContext context) |
|
|
|
{ |
|
|
|
// ldobj(...(addressof(ldloc V))) where ... can be zero or more ldflda instructions
|
|
|
|
// =>
|
|
|
|
// ldobj(...(ldloca V))
|
|
|
|
var temp = inst.Target; |
|
|
|
var range = temp.ILRanges; |
|
|
|
while (temp.MatchLdFlda(out var ldfldaTarget, out _)) { |
|
|
|
temp = ldfldaTarget; |
|
|
|
range = range.Concat(temp.ILRanges); |
|
|
|
} |
|
|
|
if (temp.MatchAddressOf(out var addressOfTarget) && addressOfTarget.MatchLdLoc(out var v)) { |
|
|
|
context.Step($"ldobj(...(addressof(ldloca {v.Name}))) => ldobj(...(ldloca {v.Name}))", inst); |
|
|
|
var replacement = new LdLoca(v).WithILRange(addressOfTarget); |
|
|
|
foreach (var r in range) { |
|
|
|
replacement = replacement.WithILRange(r); |
|
|
|
} |
|
|
|
temp.ReplaceWith(replacement); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected internal override void VisitCall(Call inst) |
|
|
|
{ |
|
|
|
var expr = HandleCall(inst, context); |
|
|
|