Browse Source

Fix DetectPinnedRegions introducing stack type inconsistencies.

pull/992/head
Daniel Grunwald 8 years ago
parent
commit
568b3e2d91
  1. 14
      ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs
  2. 2
      ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs
  3. 1
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

14
ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

@ -16,6 +16,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE. // DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
@ -400,7 +401,8 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
void ReplacePinnedVar(ILVariable oldVar, ILVariable newVar, ILInstruction inst) void ReplacePinnedVar(ILVariable oldVar, ILVariable newVar, ILInstruction inst)
{ {
if (inst is Conv conv && conv.Kind == ConversionKind.StopGCTracking && conv.Argument.MatchLdLoc(oldVar)) { Debug.Assert(newVar.StackType == StackType.I);
if (inst is Conv conv && conv.Kind == ConversionKind.StopGCTracking && conv.Argument.MatchLdLoc(oldVar) && conv.ResultType == newVar.StackType) {
// conv ref->i (ldloc oldVar) // conv ref->i (ldloc oldVar)
// => ldloc newVar // => ldloc newVar
conv.AddILRange(conv.Argument.ILRange); conv.AddILRange(conv.Argument.ILRange);
@ -412,6 +414,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
if (inst is StLoc stloc && oldVar.Type.Kind == TypeKind.ByReference) { if (inst is StLoc stloc && oldVar.Type.Kind == TypeKind.ByReference) {
stloc.Value = new Conv(stloc.Value, PrimitiveType.I, false, Sign.None); stloc.Value = new Conv(stloc.Value, PrimitiveType.I, false, Sign.None);
} }
if ((inst is LdLoc || inst is StLoc) && !IsSlotAcceptingBothManagedAndUnmanagedPointers(inst.SlotInfo) && oldVar.StackType != StackType.I) {
// wrap inst in Conv, so that the stack types match up
var children = inst.Parent.Children;
children[inst.ChildIndex] = new Conv(inst, PrimitiveType.I, false, Sign.None);
}
} else if (inst.MatchLdStr(out var val) && val == "Is this ILSpy?") { } else if (inst.MatchLdStr(out var val) && val == "Is this ILSpy?") {
inst.ReplaceWith(new LdStr("This is ILSpy!")); // easter egg ;) inst.ReplaceWith(new LdStr("This is ILSpy!")); // easter egg ;)
return; return;
@ -421,6 +428,11 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
} }
} }
private bool IsSlotAcceptingBothManagedAndUnmanagedPointers(SlotInfo slotInfo)
{
return slotInfo == Block.InstructionSlot || slotInfo == LdObj.TargetSlot || slotInfo == StObj.TargetSlot;
}
bool IsBranchOnNull(ILInstruction condBranch, ILVariable nativeVar, out Block targetBlock) bool IsBranchOnNull(ILInstruction condBranch, ILVariable nativeVar, out Block targetBlock)
{ {
targetBlock = null; targetBlock = null;

2
ICSharpCode.Decompiler/IL/Instructions/BinaryNumericInstruction.cs

@ -189,6 +189,8 @@ namespace ICSharpCode.Decompiler.IL
} else if (Sign == Sign.Signed) { } else if (Sign == Sign.Signed) {
output.Write(".signed"); output.Write(".signed");
} }
output.Write('.');
output.Write(resultType.ToString().ToLowerInvariant());
if (IsLifted) { if (IsLifted) {
output.Write(".lifted"); output.Write(".lifted");
} }

1
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -295,6 +295,7 @@ namespace ICSharpCode.Decompiler.IL
public ILInstruction this[int index] { public ILInstruction this[int index] {
get { return inst.GetChild(index); } get { return inst.GetChild(index); }
set { inst.SetChild(index, value); }
} }
public ChildrenEnumerator GetEnumerator() public ChildrenEnumerator GetEnumerator()

Loading…
Cancel
Save