Browse Source

Merge pull request #3015 from ElektroKill/mcs264-pinned-region

pull/3030/head
Siegfried Pammer 2 years ago committed by GitHub
parent
commit
175854791e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs
  2. 20
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.cs
  3. 74
      ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.il
  4. 46
      ICSharpCode.Decompiler/IL/ControlFlow/DetectPinnedRegions.cs

6
ICSharpCode.Decompiler.Tests/ILPrettyTestRunner.cs

@ -269,6 +269,12 @@ namespace ICSharpCode.Decompiler.Tests
await Run(); await Run();
} }
[Test]
public async Task MonoFixed()
{
await Run();
}
async Task Run([CallerMemberName] string testName = null, DecompilerSettings settings = null, async Task Run([CallerMemberName] string testName = null, DecompilerSettings settings = null,
AssemblerOptions assemblerOptions = AssemblerOptions.Library) AssemblerOptions assemblerOptions = AssemblerOptions.Library)
{ {

20
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.cs

@ -0,0 +1,20 @@
using System;
public class MonoFixed
{
public unsafe void FixMultipleStrings(string text)
{
fixed (char* ptr = text)
{
fixed (char* ptr2 = Environment.UserName)
{
fixed (char* ptr3 = text)
{
*ptr = 'c';
*ptr2 = 'd';
*ptr3 = 'e';
}
}
}
}
}

74
ICSharpCode.Decompiler.Tests/TestCases/ILPretty/MonoFixed.il

@ -0,0 +1,74 @@
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 4:0:0:0
}
.assembly MonoFixed
{
.ver 1:0:0:0
}
.module MonoFixed.exe
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WindowsCui
.corflags 0x00000001 // ILOnly
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = (
01 00 00 00
)
.class public auto ansi beforefieldinit MonoFixed
extends [mscorlib]System.Object
{
.method public hidebysig instance void FixMultipleStrings (string text) cil managed
{
.maxstack 7
.locals init (
[0] char* pinned,
[1] char* pinned,
[2] char* pinned,
[3] string pinned,
[4] string pinned,
[5] string pinned
)
IL_0000: ldarg.1
IL_0001: stloc.3
IL_0002: ldloc.3
IL_0003: conv.i
IL_0004: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()
IL_0009: add
IL_000a: stloc.0
IL_000b: call string [mscorlib]System.Environment::get_UserName()
IL_0010: stloc.s 4
IL_0012: ldloc.s 4
IL_0014: conv.i
IL_0015: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()
IL_001a: add
IL_001b: stloc.1
IL_001c: ldarg.1
IL_001d: stloc.s 5
IL_001f: ldloc.s 5
IL_0021: conv.i
IL_0022: call int32 [mscorlib]System.Runtime.CompilerServices.RuntimeHelpers::get_OffsetToStringData()
IL_0027: add
IL_0028: stloc.2
IL_0029: ldloc.0
IL_002a: ldc.i4.s 99
IL_002c: stind.i2
IL_002d: ldloc.1
IL_002e: ldc.i4.s 100
IL_0030: stind.i2
IL_0031: ldloc.2
IL_0032: ldc.i4.s 101
IL_0034: stind.i2
IL_0035: ldnull
IL_0036: stloc.3
IL_0037: ldnull
IL_0038: stloc.s 4
IL_003a: ldnull
IL_003b: stloc.s 5
IL_003d: ret
}
}

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

@ -1,4 +1,4 @@
// Copyright (c) 2016 Daniel Grunwald // Copyright (c) 2016 Daniel Grunwald
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy of this // Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software // software and associated documentation files (the "Software"), to deal in the Software
@ -878,28 +878,44 @@ namespace ICSharpCode.Decompiler.IL.ControlFlow
} }
return; return;
} }
if (body.EntryPoint.Instructions.Count != 3)
{
return;
}
if (nativeVar.Type.GetStackType() != StackType.I) if (nativeVar.Type.GetStackType() != StackType.I)
return; return;
if (!initInst.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(pinnedRegion.Variable))
return; Block targetBlock;
if (!IsBranchOnNull(body.EntryPoint.Instructions[1], nativeVar, out Block targetBlock)) Block adjustOffsetToStringData = null;
return; if (body.EntryPoint.Instructions.Count == 2)
if (!body.EntryPoint.Instructions[2].MatchBranch(out Block adjustOffsetToStringData)) {
return; if (!initInst.MatchBinaryNumericInstruction(BinaryNumericOperator.Add, out ILInstruction left, out ILInstruction right))
if (!(adjustOffsetToStringData.Parent == body && adjustOffsetToStringData.IncomingEdgeCount == 1 return;
&& IsOffsetToStringDataBlock(adjustOffsetToStringData, nativeVar, targetBlock))) if (!left.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(pinnedRegion.Variable))
return;
if (!IsOffsetToStringDataCall(right))
return;
if (!body.EntryPoint.Instructions[1].MatchBranch(out targetBlock))
return;
}
else if (body.EntryPoint.Instructions.Count == 3)
{
if (!initInst.UnwrapConv(ConversionKind.StopGCTracking).MatchLdLoc(pinnedRegion.Variable))
return;
if (!IsBranchOnNull(body.EntryPoint.Instructions[1], nativeVar, out targetBlock))
return;
if (!body.EntryPoint.Instructions[2].MatchBranch(out adjustOffsetToStringData))
return;
if (!(adjustOffsetToStringData.Parent == body && adjustOffsetToStringData.IncomingEdgeCount == 1
&& IsOffsetToStringDataBlock(adjustOffsetToStringData, nativeVar, targetBlock)))
return;
}
else
return; return;
context.Step("Handle pinned string (with adjustOffsetToStringData)", pinnedRegion); context.Step("Handle pinned string (with adjustOffsetToStringData)", pinnedRegion);
if (targetBlock.Parent == body) if (targetBlock.Parent == body)
{ {
// remove old entry point // remove old entry point
body.Blocks.RemoveAt(0); body.Blocks.RemoveAt(0);
body.Blocks.RemoveAt(adjustOffsetToStringData.ChildIndex); if (adjustOffsetToStringData is not null)
body.Blocks.RemoveAt(adjustOffsetToStringData.ChildIndex);
// make targetBlock the new entry point // make targetBlock the new entry point
body.Blocks.RemoveAt(targetBlock.ChildIndex); body.Blocks.RemoveAt(targetBlock.ChildIndex);
body.Blocks.Insert(0, targetBlock); body.Blocks.Insert(0, targetBlock);

Loading…
Cancel
Save