Browse Source

#899: decode jmp instruction into tail call

pull/904/head
Daniel Grunwald 8 years ago
parent
commit
6a1b623140
  1. 6
      ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs
  2. 1
      ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj
  3. 47
      ICSharpCode.Decompiler.Tests/TestCases/Correctness/Jmp.il
  4. 18
      ICSharpCode.Decompiler/IL/ILReader.cs

6
ICSharpCode.Decompiler.Tests/CorrectnessTestRunner.cs

@ -162,6 +162,12 @@ namespace ICSharpCode.Decompiler.Tests @@ -162,6 +162,12 @@ namespace ICSharpCode.Decompiler.Tests
RunIL("BitNot.il", CompilerOptions.UseDebug | CompilerOptions.Force32Bit, AssemblerOptions.Force32Bit);
}
[Test]
public void Jmp()
{
RunIL("Jmp.il");
}
[Test]
public void UnsafeCode([ValueSource("defaultOptions")] CompilerOptions options)
{

1
ICSharpCode.Decompiler.Tests/ICSharpCode.Decompiler.Tests.csproj

@ -44,6 +44,7 @@ @@ -44,6 +44,7 @@
</ItemGroup>
<ItemGroup>
<None Include="TestCases\Correctness\Jmp.il" />
<None Include="TestCases\Correctness\BitNot.il" />
<None Include="TestCases\Correctness\Readme.txt" />
</ItemGroup>

47
ICSharpCode.Decompiler.Tests/TestCases/Correctness/Jmp.il

@ -0,0 +1,47 @@ @@ -0,0 +1,47 @@
.assembly extern mscorlib
{
.publickeytoken = ( b7 7a 5c 56 19 34 e0 89 )
.ver 4:0:0:0
}
.assembly 'Jmp'
{
.ver 0:0:0:0
}
.module Jmp.exe
.corflags 0x00000001 // ILOnly
.class private auto ansi abstract sealed beforefieldinit Program
extends [mscorlib]System.Object
{
.method public hidebysig static void Main (string[] args) cil managed
{
.maxstack 8
.entrypoint
ldstr "Method1(100) = {0}"
ldc.i4 100
call int32 Program::Method1(int32)
box int32
call void [mscorlib]System.Console::WriteLine(string, object)
ret
} // end of method Main
.method public static int32 Method1(int32 val)
{
ldarg.0
ldc.i4.1
add
starg.s 0
jmp int32 Program::Method2(int32)
}
.method public static int32 Method2(int32 val)
{
ldarg.0
ldc.i4.5
mul
ret
}
}

18
ICSharpCode.Decompiler/IL/ILReader.cs

@ -537,7 +537,7 @@ namespace ICSharpCode.Decompiler.IL @@ -537,7 +537,7 @@ namespace ICSharpCode.Decompiler.IL
case Cil.Code.Initblk:
return new Initblk(size: Pop(StackType.I4), value: Pop(StackType.I4), address: PopPointer());
case Cil.Code.Jmp:
throw new NotImplementedException();
return DecodeJmp();
case Cil.Code.Ldarg:
case Cil.Code.Ldarg_S:
return Push(Ldarg(((ParameterDefinition)cecilInst.Operand).Sequence));
@ -1251,6 +1251,22 @@ namespace ICSharpCode.Decompiler.IL @@ -1251,6 +1251,22 @@ namespace ICSharpCode.Decompiler.IL
return Push(new BinaryNumericInstruction(@operator, left, right, checkForOverflow, sign));
}
ILInstruction DecodeJmp()
{
IMethod method = ReadAndDecodeMethodReference();
// Translate jmp into tail call:
Call call = new Call(method);
call.IsTail = true;
call.ILStackWasEmpty = true;
if (!method.IsStatic) {
call.Arguments.Add(Ldarg(0));
}
foreach (var p in method.Parameters) {
call.Arguments.Add(Ldarg(call.Arguments.Count));
}
return new Leave(mainContainer, call);
}
ILInstruction LdToken(IMetadataTokenProvider token)
{
if (token is TypeReference)

Loading…
Cancel
Save