|
|
@ -78,13 +78,14 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally))) |
|
|
|
if (storeInst.Variable.LoadInstructions.Any(ld => !ld.IsDescendantOf(tryFinally))) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (storeInst.Variable.AddressInstructions.Any(la => !la.IsDescendantOf(tryFinally))) |
|
|
|
if (storeInst.Variable.AddressInstructions.Any(la => !la.IsDescendantOf(tryFinally) || (la.IsDescendantOf(tryFinally.TryBlock) && !ILInlining.IsUsedAsThisPointerInCall(la)))) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (storeInst.Variable.StoreInstructions.OfType<ILInstruction>().Any(st => st != storeInst)) |
|
|
|
if (storeInst.Variable.StoreInstructions.OfType<ILInstruction>().Any(st => st != storeInst)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (!(tryFinally.FinallyBlock is BlockContainer container) || !MatchDisposeBlock(container, storeInst.Variable, storeInst.Value.MatchLdNull())) |
|
|
|
if (!(tryFinally.FinallyBlock is BlockContainer container) || !MatchDisposeBlock(container, storeInst.Variable, storeInst.Value.MatchLdNull())) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
context.Step("UsingTransform", tryFinally); |
|
|
|
context.Step("UsingTransform", tryFinally); |
|
|
|
|
|
|
|
storeInst.Variable.Kind = VariableKind.UsingLocal; |
|
|
|
block.Instructions.RemoveAt(i); |
|
|
|
block.Instructions.RemoveAt(i); |
|
|
|
block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock); |
|
|
|
block.Instructions[i - 1] = new UsingInstruction(storeInst.Variable, storeInst.Value, tryFinally.TryBlock); |
|
|
|
return true; |
|
|
|
return true; |
|
|
@ -129,13 +130,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
if (callVirt.Arguments.Count != 1) |
|
|
|
if (callVirt.Arguments.Count != 1) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
var firstArg = cv.Arguments.FirstOrDefault(); |
|
|
|
var firstArg = cv.Arguments.FirstOrDefault(); |
|
|
|
if (!(firstArg.MatchUnboxAny(out var innerArg1, out var unboxType) && unboxType.IsKnownType(KnownTypeCode.IDisposable))) |
|
|
|
if (!(firstArg.MatchUnboxAny(out var innerArg1, out var unboxType) && unboxType.IsKnownType(KnownTypeCode.IDisposable))) { |
|
|
|
return false; |
|
|
|
if (!firstArg.MatchAddressOf(out var innerArg2)) |
|
|
|
if (!(innerArg1.MatchBox(out firstArg, out var boxType) && boxType.IsKnownType(KnownTypeCode.NullableOfT) && |
|
|
|
return false; |
|
|
|
|
|
|
|
return NullableLiftingTransform.MatchGetValueOrDefault(innerArg2, objVar); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
if (!(innerArg1.MatchBox(out firstArg, out var boxType) && boxType.IsKnownType(KnownTypeCode.NullableOfT) && |
|
|
|
NullableType.GetUnderlyingType(boxType).Equals(NullableType.GetUnderlyingType(objVar.Type)))) |
|
|
|
NullableType.GetUnderlyingType(boxType).Equals(NullableType.GetUnderlyingType(objVar.Type)))) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
return firstArg.MatchLdLoc(objVar); |
|
|
|
return firstArg.MatchLdLoc(objVar); |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
|
|
|
|
ILInstruction target; |
|
|
|
if (isReference) { |
|
|
|
if (isReference) { |
|
|
|
// reference types have a null check.
|
|
|
|
// reference types have a null check.
|
|
|
|
if (!entryPoint.Instructions[checkIndex].MatchIfInstruction(out var condition, out var disposeInst)) |
|
|
|
if (!entryPoint.Instructions[checkIndex].MatchIfInstruction(out var condition, out var disposeInst)) |
|
|
@ -146,10 +152,18 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (!(disposeBlock.Instructions[0] is CallVirt cv)) |
|
|
|
if (!(disposeBlock.Instructions[0] is CallVirt cv)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
target = cv.Arguments.FirstOrDefault(); |
|
|
|
|
|
|
|
if (target == null) |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
if (target.MatchBox(out var newTarget, out var type) && type.Equals(objVar.Type)) |
|
|
|
|
|
|
|
target = newTarget; |
|
|
|
callVirt = cv; |
|
|
|
callVirt = cv; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
if (!(entryPoint.Instructions[checkIndex] is CallVirt cv)) |
|
|
|
if (!(entryPoint.Instructions[checkIndex] is CallVirt cv)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
target = cv.Arguments.FirstOrDefault(); |
|
|
|
|
|
|
|
if (target == null) |
|
|
|
|
|
|
|
return false; |
|
|
|
callVirt = cv; |
|
|
|
callVirt = cv; |
|
|
|
} |
|
|
|
} |
|
|
|
if (callVirt.Method.FullName != "System.IDisposable.Dispose") |
|
|
|
if (callVirt.Method.FullName != "System.IDisposable.Dispose") |
|
|
@ -158,7 +172,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
if (callVirt.Arguments.Count != 1) |
|
|
|
if (callVirt.Arguments.Count != 1) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
return callVirt.Arguments[0].MatchLdLocRef(objVar) || (usingNull && callVirt.Arguments[0].MatchLdNull()); |
|
|
|
return target.MatchLdLocRef(objVar) || (usingNull && callVirt.Arguments[0].MatchLdNull()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|