Giter Site home page Giter Site logo

icsharpcode / ilspy Goto Github PK

View Code? Open in Web Editor NEW
21.1K 714.0 3.3K 41.67 MB

.NET Decompiler with support for PDB generation, ReadyToRun, Metadata (&more) - cross-platform!

C# 99.48% Batchfile 0.02% F# 0.02% PowerShell 0.18% Visual Basic .NET 0.19% Jupyter Notebook 0.10% Shell 0.01%
decompiler decompiler-engine c-sharp dotnet dotnetcore mono unity pdb ilspy decompile

ilspy's Introduction

ILSpy NuGet Build ILSpy Mastodon Follow Twitter Follow ILSpy VS extension

ILSpy is the open-source .NET assembly browser and decompiler.

Download: latest release | latest CI build (master) | Microsoft Store (RTM versions only)

Decompiler Frontends

Aside from the WPF UI ILSpy (downloadable via Releases, see also plugins), the following other frontends are available:

  • Visual Studio 2022 ships with decompilation support for F12 enabled by default (using our engine v8.1).
  • In Visual Studio 2019, you have to manually enable F12 support. Go to Tools / Options / Text Editor / C# / Advanced and check "Enable navigation to decompiled source"
  • C# for Visual Studio Code ships with decompilation support as well. To enable, activate the setting "Enable Decompilation Support".
  • Our Visual Studio 2022 extension marketplace
  • Our Visual Studio 2017/2019 extension marketplace
  • Our Visual Studio Code Extension repository | marketplace
  • Our Linux/Mac/Windows ILSpy UI based on Avalonia - check out https://github.com/icsharpcode/AvaloniaILSpy
  • Our ICSharpCode.Decompiler NuGet for your own projects
  • Our dotnet tool for Linux/Mac/Windows - check out ILSpyCmd in this repository
  • Our Linux/Mac/Windows PowerShell cmdlets in this repository

Features

  • Decompilation to C# (check out the language support status)
  • Whole-project decompilation
  • Search for types/methods/properties (learn about the options)
  • Hyperlink-based type/method/property navigation
  • Base/Derived types navigation, history
  • Assembly metadata explorer (feature walkthrough)
  • BAML to XAML decompiler
  • ReadyToRun binary support for .NET Core (see the tutorial)
  • Extensible via plugins
  • Additional features in DEBUG builds (for the devs)

License

ILSpy is distributed under the MIT License. Please see the About doc for details, as well as third party notices for included open-source libraries.

How to build

Windows:

  • Make sure Windows PowerShell (at least version) 5.0 or PowerShell 7+ is installed.
  • Clone the ILSpy repository using git.
  • Execute git submodule update --init --recursive to download the ILSpy-Tests submodule (used by some test cases).
  • Install Visual Studio (documented version: 17.8). You can install the necessary components in one of 3 ways:
    • Follow Microsoft's instructions for importing a configuration, and import the .vsconfig file located at the root of the solution.
    • Alternatively, you can open the ILSpy solution (ILSpy.sln) and Visual Studio will prompt you to install the missing components.
    • Finally, you can manually install the necessary components via the Visual Studio Installer. The workloads/components are as follows:
      • Workload ".NET Desktop Development". This workload includes the .NET Framework 4.8 SDK and the .NET Framework 4.7.2 targeting pack, as well as the .NET 8.0 SDK (ILSpy.csproj targets .NET 8.0, but we have net472 projects too). Note: The optional components of this workload are not required for ILSpy
      • Workload "Visual Studio extension development" (ILSpy.sln contains a VS extension project) Note: The optional components of this workload are not required for ILSpy
      • Individual Component "MSVC v143 - VS 2022 C++ x64/x86 build tools" (or similar)
        • The VC++ toolset is optional; if present it is used for editbin.exe to modify the stack size used by ILSpy.exe from 1MB to 16MB, because the decompiler makes heavy use of recursion, where small stack sizes lead to problems in very complex methods.
    • Open ILSpy.sln in Visual Studio.
      • NuGet package restore will automatically download further dependencies
      • Run project "ILSpy" for the ILSpy UI
      • Use the Visual Studio "Test Explorer" to see/run the tests
      • If you are only interested in a specific subset of ILSpy, you can also use
        • ILSpy.Wpf.slnf: for the ILSpy WPF frontend
        • ILSpy.XPlat.slnf: for the cross-platform CLI or PowerShell cmdlets
        • ILSpy.AddIn.slnf: for the Visual Studio plugin

Note: Visual Studio includes a version of the .NET SDK that is managed by the Visual Studio installer - once you update, it may get upgraded too. Please note that ILSpy is only compatible with the .NET 8.0 SDK and Visual Studio will refuse to load some projects in the solution (and unit tests will fail). If this problem occurs, please manually install the .NET 8.0 SDK from here.

Unix / Mac:

  • Make sure .NET 8.0 SDK is installed.
  • Make sure PowerShell is installed (formerly known as PowerShell Core)
  • Clone the repository using git.
  • Execute git submodule update --init --recursive to download the ILSpy-Tests submodule (used by some test cases).
  • Use dotnet build ILSpy.XPlat.slnf to build the non-Windows flavors of ILSpy (.NET Core Global Tool and PowerShell Core).

How to contribute

Current and past contributors.

Privacy Policy for ILSpy

ILSpy does not collect any personally identifiable information, nor does it send user files to 3rd party services. ILSpy does not use any APM (Application Performance Management) service to collect telemetry or metrics.

ilspy's People

Contributors

arturek avatar bbi-yggyking avatar chicken-bones avatar christophwille avatar cshung avatar dependabot[bot] avatar dgrunwald avatar dsrbecky avatar dymanoid avatar edharvey avatar edkazcarlson avatar elektrokill avatar eusebiu avatar jbevain avatar linquize avatar lordjz avatar ltrzesniewski avatar maikebing avatar miloush avatar mohe2015 avatar ondrejpetrzilka avatar pentp avatar rklier avatar rpinski avatar sharwell avatar siegfriedpammer avatar slaks avatar tom-englert avatar wwh1004 avatar yyjdelete avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ilspy's Issues

System.InvalidCastException: Cast from Int64 to Boolean not supported.

at ICSharpCode.NRefactory.Utils.CSharpPrimitiveCast.CSharpPrimitiveCastUnchecked(TypeCode targetType, Object input)
at Decompiler.AstMethodBodyBuilder.MakePrimitive(Int64 val, TypeReference type)
at Decompiler.AstMethodBodyBuilder.TransformByteCode(ILExpression byteCode, List`1 args)
at Decompiler.AstMethodBodyBuilder.TransformExpression(ILExpression expr)
...

IL_005a: ldloc.2
IL_005b: ldfld class RSClient_I32.__CallBackClass_busChangedEventHandler class RSClient_I32.__CallBackClass_SinkHelper::m_busChangedDelegate
IL_0060: ldarg <-------------- ldarg 1
IL_0064: castclass object
IL_0069: callvirt instance bool [mscorlib]System.Delegate::Equals(object)
IL_006e: ldc.i4 255 <----------- System.InvalidCastException
IL_0073: and
IL_0074: ldc.i4 0
IL_0079: beq IL_00d4

Lost method parameters

public override void add_busChanged(__RSControl_busChangedEventHandler) <---- handler1
{
bool flag;
try
{
Monitor.Enter(this, ref flag);
if (this.m_ConnectionPoint == null)
{
this.Init();
}
__RSControl_SinkHelper __RSControl_SinkHelper = new __RSControl_SinkHelper();
int i = 0;
this.m_ConnectionPoint.Advise((object)__RSControl_SinkHelper, ref i);
__RSControl_SinkHelper.m_dwCookie = i;
__RSControl_SinkHelper.m_busChangedDelegate = ; <----- handler1
this.m_aEventSinkHelpers.Add((object)__RSControl_SinkHelper);
}
finally
{
if (flag)
{
Monitor.Exit(this);
}
}
}

IL_0048: ldarg <---- 1

Attribute the loss of 'extern'

mscorlib v.4.0
Microsoft.Win32.OAVariantLib

private static void ChangeTypeEx(Variant result, Variant source, int lcid, IntPtr typeHandle, int cvType, short flags);

should be

private static extern void ChangeTypeEx(Variant result, Variant source, int lcid, IntPtr typeHandle, int cvType, short flags);

redundant explicit boxing

double num = 12.345;
double num2 = 12.0;
Console.WriteLine("{0:#.#} {1:#.#}", box(System.Double, num), box(System.Double, num2));

Notice the unnecessary box(...) instructions around num and num2.

Decompilation of inline comparisons into a 'flag' variable done wrong.

For instance:

for (int current = 0; ; )
{
    bool flag = current < 100; //<----- note this 'flag' variable created automatically by the decompiler
    if (!flag)
    {
        break;
    }
    else
    {
        this.DoSomething();
        current += 1;
    }
}

List<int> list = new List<int>();
list.Add(1);
list.Add(2);
flag = (list == null); //<----- the same 'flag' used again, although not in scope.
if (!flag)
{
    this.DoSomething();
}

Wrong static System.Decimal()

mscorlib
System.Decimal

static Decimal()
{
uint[] expr_07 = new uint[10];
Array arg_0D_0 = expr_07;
uint[] arg_12_0 = expr_07;
RuntimeHelpers.InitializeArray(arg_0D_0, ldtoken($$method0x6006097-1));
decimal.Powers10 = arg_12_0;
decimal.Zero = new decimal(0);
decimal.One = new decimal(1);
decimal.MinusOne = new decimal(-1);
decimal.MaxValue = new decimal(-1, -1, -1, false, 0);
decimal.MinValue = new decimal(-1, -1, -1, 128 != 0, 0);
decimal.NearNegativeZero = new decimal(1, 0, 0, 128 != 0, 27);
decimal.NearPositiveZero = new decimal(1, 0, 0, false, 27);
}

must be

static Decimal()
{
Powers10 = new uint[] { 1, 10, 100, 0x3e8, 0x2710, 0x186a0, 0xf4240, 0x989680, 0x5f5e100, 0x3b9aca00 };
Zero = 0M;
One = 1M;
MinusOne = -1M;
MaxValue = 79228162514264337593543950335M;
MinValue = -79228162514264337593543950335M;
NearNegativeZero = -0.000000000000000000000000001M;
NearPositiveZero = 0.000000000000000000000000001M;
}

.NET 3.5 support

It takes several minor modifications to run ILSpy on .NET 3.5
Can we please add those with #if or something?


Majority of modifications are about generic collection covariance missing in .NET 3.5 -- basically sticking OfType<> now and then fixes it.

There are several string.Join calls with an absent signature. Select+ToArray does it.

There is a little Mono.Cecil patch to do with some obscure static type invocation. This one would just have to be ignored I guess.

And couple of WPF properties missing -- like layout rounding and text render preferences.

I've got the code and can post it.

GenericMethod fail

input:
public static T GenericMethod(T t)
{
return t;
}

output:
public static T GenericMethod(T t)
{
return t;
}

Incorrect decompile of a NaN or +/-Infinity literal.

System.Double.NaN decompiles to the following code:
public const double NaN = NaN.0;

Obviously that will not compile. There are similar issues for System.Double.PositiveInfinity, and System.Double.NegativeInfinity.

Instead NaN is best represented as 0.0/0.0.

The C# 4.0 compiler will compile that into a NaN that is bit-for-bit identical to System.Double.NaN.

Similarly PositiveInfinity is best represented as 1.0/0.0, and NegativeInfinity as -1.0/0.0.
Those expressions also compile bit for bit identical to the System.Double members.

enum value looses type when boxed

Console.WriteLine("{0} $$ {1}", AttributeTargets.Class, AttributeTargets.Field | AttributeTargets.Property);

Should print:
Class $$ Property, Field

but prints
Class $$ 384

I prepared a fix for this issue (see parts of commit arturek/ILSpy@679d525806d8ca7c0820) as a part of my work on custom attribute support but I am still working on some other issues related to it (and on validation of correctness of this change). I can notify you when I finish if you are interested in it.

Feature Request: IL Opcode tooltips

Reflector provides convenient tooltips when hovering over an IL opcode, describing the opcode and giving the hexadecimal value of it. The descriptions are taken from the xml documentation summary tags for the corresponding fields in the System.Reflection.Emit.OpCodes class.

Please consider adding such tooltips once you have support for loading and displaying the xml documentation for an assembly.

"Check for updates" fails behind a web proxy

"Check for updates" does not support web-proxy. If PC requires a web-proxy to connect to the internet, the check fails with an exception:

System.AggregateException: One or more errors occurred. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: Impossibile stabilire la connessione. Risposta non corretta della parte connessa dopo l'intervallo di tempo oppure mancata risposta dall'host collegato 195.234.231.66:80
at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
.... [SNIP] ....

Invalid stind/ldind

class Class1
{
    private int i = 0;
    public void method(out string str)
    {
        str = "qq";
        str += i.ToString();
    }
}

public void method(out string str)
{
str = "qq";
string expr_09 = ref str;
string arg_0A_0 = expr_09;
stind.ref(expr_09, ldind.ref(arg_0A_0) + this.i.ToString());
}

foreach loops decompiled wrong

(this issue is just for reference, I know this is top priority :-)

The following 'foreach' loop:

        List<int> list = new List<int>();
        list.Add(1);
        list.Add(2);
        list.Add(3);
        list.Add(4);
        list.Add(5);

        foreach (int i in list)
        {
            DoSomething();
        }

decompiled to this:

List<int> list = new List<int>();
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
list.Add(5);
List.Enumerator<int> enumerator = list.GetEnumerator();
try
{
    for (; ; )
    {
        flag = enumerator.MoveNext();
        if (!flag)
        {
            break;
        }
        else
        {
            current = enumerator.Current;
            this.DoSomething();
        }
    }
}
finally
{
    var arg_AF_0 = ref enumerator;
    constrained(System.Collections.Generic.List`1/Enumerator<System.Int32>);
    arg_AF_0.Dispose();
}

"else" not needed after "throw new ArgumentNullException"

Hi,

I have noticed in a few places that an "else" is shown after argument checks (for nullity or anything else).

For example, in System.Collections.ArrayList :

public static ArrayList Adapter(IList list)
{
    if (list == null)
    {
        throw new ArgumentNullException("list");
    }
    else
    {
        return new ArrayList.IListWrapper(list);
    }
}

The else is not necessary.

passing null to a method/constructor that has multiple signatures

When the method has multiple signatures; such as foo(MyObject o) and foo(string s), then code calling for with a null argument must have a cast. Currently ILSpy will display foo(null) and it should be foo((string) null) or foo((MyObject) null).

I found this while looking at the .ctor for System.Xml.Resolvers.XmlPreloadedResolver.

Crash wen update checking disabled

Steps to reproduce:

  1. disable update checking
  2. open about page
    FormatException raised (String was not recognized as valid DateTime).
    After this steps application crashed on start-up until clearing of c:\Users\user\AppData\Roaming\ISharpCode\ folder

request for generating default in switch

Some times the generated code has many gotos because code from defaults is not identified here is an example:

input:

public static int Switch(int i)
{
    int j;
    switch (i)
    {
        case 0:
        {
            j = i + 1;
            break;
        }
        case 1:
        {
            j = i + 2;
            break;
        }
        default:
        {
            return -1;                  
        }
    }
    return j * 2;
}

output:

public static int Switch(int i)
{
    int j;
    switch (i)
    {
        case 0:
        {
            j = i + 1;
            goto IL_20;
        }
        case 1:
        {
            j = i + 2;
            goto IL_20;
        }
    }
    return -1;
    IL_20:
    return j * 2;
}

initobj(...)

mscorlib
namespace System.Globalization
class TimeSpanParse
internal static TimeSpan ParseExact(string input, string format, IFormatProvider formatProvider, TimeSpanStyles styles)
{
initobj(System.Globalization.TimeSpanParse/TimeSpanResult, ref timeSpanResult);
must be
TimeSpanResult timeSpanResult = new TimeSpanResult();
...
}

typing gone wrong

Found this code when browsing ILSpy code on ILSpy:

function path: ILSpy/ICSharpCode.ILSpy/CSharpLanguage/d__7

  • look at typing of arg_22_0
  • in addition it has gone out of scope in 2nd assignment and in test

private IEnumerator System.Collections.Generic.IEnumerable<ICSharpCode.ILSpy.CSharpLanguage>.GetEnumerator()
{
if (Thread.CurrentThread.ManagedThreadId == this.<>l__initialThreadId)
{
var arg_22_0 = this.<>1__state == -2 == 0; // <<< assinged bool
}
else
{
arg_22_0 = 1; // <<< assigned int
}
if (arg_22_0 == null) // <<< compared to pointer
{
this.<>1__state = 0;
CSharpLanguage.d__7 d__7 = this;
}
else
{
d__7 = new CSharpLanguage.d__7(0);
}
IEnumerator enumerator = d__7;
return enumerator;
}

Unnecessary base..ctor(); call

The decompiler creates an unnecessary even confusing base..ctor() call in the constructor.

Artificial code to show you, what I mean:

public MyClass()
{
    this.myField1 = true;
    base..ctor();
}

StackBefore == null

Ln 207 if (branchTarget.StackBefore.Count != newStack.Count) // is true

Ln 233 int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count; // StackBefore == null

Ln 384 int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count; // StackBefore == null

'for' loops decompiled wrong

The decompiled version of this:

    public void ForLoopTest()
    {
        for (int i = 0; i < 100; ++i)
        {
            DoSomething();
        }
    }

is this:

public void ForLoopTest()
{
for (int i = 0; ; )
{
if (i >= 100) // should be placed after first semicolon
{
break;
}
else
{
this.DoSomething(); // redundant 'this.'
i += 1; // can be changed to ++i or i++ and placed after second semicolon
}
}
}

Attributes are missing

I cannot see the attributes used in classes neither members. Is this a bug? or, can this be a feature to add?

stind.i4(hr, 0);

mscorlib
Microsoft.Win32.Win32Native.SetFilePointer()

should be

hr = 0;

try {} catch problem

method()
{
try
{
try
{ }
finaly()
{ }
// leave to return
}
catch()
{ }

}

FILE: ILAstBuilder.cs

List StackAnalysis(MethodDefinition methodDef)
{
Ln 207 // if (branchTarget.StackBefore.Count != newStack.Count) <-- is true
Ln 233 // int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count; <-- StackBefore == null
}

List ConvertToAst(List body)
{
Ln 364 // int popCount = byteCode.PopCount ?? byteCode.StackBefore.Count; <-- StackBefore == null
}

ldelem.any

class MyArray<T> where T : new()
{
    private T[] arr;

    public MyArray()
    {
        this.arr = new T[20];
    }

    public MyArray(int capacity)
    {
        this.arr = new T[capacity];
    }

    public void Size(int capacity)
    {
        T[] destinationArray = new T[capacity];
        Array.Copy(this.arr, destinationArray, this.arr.Length);
        this.arr = destinationArray;
    }

    public void Grow(int capacity)
    {
        if (capacity >= this.arr.Length)
        {
            this.Size(capacity + 1);
        }
        if (this.arr[capacity] == null) 
        {
            this.arr[capacity] = new T();
        }
    }
}

public void Grow(int capacity)
{
if (capacity >= this.arr.Length)
{
base.Size(capacity + 1); <===============
}
if (ldelem.any(T, this.arr, capacity) == null) <===========
{
T[] arg_5F_0 = this.arr; <==== new T();
int arg_5F_1 = capacity;
T t = default(T);
T arg_5F_2;
if (t == null)
{
arg_5F_2 = Activator.CreateInstance();
}
else
{
t = default(T);
arg_5F_2 = t;
}
arg_5F_0[arg_5F_1] = arg_5F_2;
}
}

ICSharpCode.Decompiler.DecompilerException: Error decompiling System.Void System.Decimal::.cctor()

mscorlib
System.Decimal:

---> System.InvalidCastException: Cast from Int64 to Boolean not supported.

must be

static Decimal()
{
Powers10 = new uint[] { 1, 10, 100, 0x3e8, 0x2710, 0x186a0, 0xf4240, 0x989680, 0x5f5e100, 0x3b9aca00 };
Zero = 0M;
One = 1M;
MinusOne = -1M;
MaxValue = 79228162514264337593543950335M;
MinValue = -79228162514264337593543950335M;
NearNegativeZero = -0.000000000000000000000000001M;
NearPositiveZero = 0.000000000000000000000000001M;
}

redundant 'continue' in a foreach loop

this:

        foreach (string s in list)
        {
            s.ToLower();
        }

decompiled to this on debug build:

foreach (string current in list)
{
    current.ToLower();
    continue;
}

and to this on release build:

using (List.Enumerator<string> enumerator = list.GetEnumerator())
{
    while (enumerator.MoveNext())
    {
        enumerator.Current.ToLower();
        continue;
    }
}

Conditional boolean return

ILSpy 1.0.0.427 gives the following for System.Double.IsNaN():
public static bool IsNaN(double d)
{
if (d != d)
{
return true;
}
return false;
}

That decompilation is entirely correct, but it is subobptimal. It would be better as a one liner like reflector gives:
public static bool IsNaN(double d)
{
return (d != d);
}

The pattern matching should also be able to handle returning the negation of the condition, for cases of the form "if(...) return false; else return true;".

System.Xaml.XamlXmlWriterException: Cannot write the given positional parameters because a matching constructor was not found.

Trying to decompile queryview.baml located in Profiler.Controls.dll causes this exception:

System.Xaml.XamlXmlWriterException: Cannot write the given positional parameters because a matching constructor was not found.
at System.Xaml.XamlXmlWriter.ExpandPositionalParameters.ExpandPositionalParametersIntoProperties(XamlXmlWriter writer)
at System.Xaml.XamlXmlWriter.ExpandPositionalParameters.WriteEndMember(XamlXmlWriter writer)
at System.Xaml.XamlXmlWriter.WriteEndMember()
at ICSharpCode.ILSpy.BamlDecompiler.DecompileBaml(MemoryStream bamlCode, Dictionary2 assemblies, String containingAssemblyFile) in d:\Projects\SharpDevelop\ILSpy\ILSpy\BamlDecompiler.cs:line 53 at ICSharpCode.ILSpy.BamlDecompiler.DecompileBaml(MemoryStream bamlCode, Dictionary2 assemblies, String containingAssemblyFile)
at ICSharpCode.ILSpy.TreeNodes.ResourceEntryNode.LoadBaml(AvalonEditTextOutput output) in d:\Projects\SharpDevelop\ILSpy\ILSpy\TreeNodes\ResourceEntryNode.cs:line 111
at ICSharpCode.ILSpy.TreeNodes.ResourceEntryNode.<>c__DisplayClass5.b__1() in d:\Projects\SharpDevelop\ILSpy\ILSpy\TreeNodes\ResourceEntryNode.cs:line 55

deadlock

mscorlib
namespace System.Globalization
class TimeSpanParse.

Unsafe code

This issue is just to help remind you of the current lack of support for unsafe code in ILSpy. A reasonable example of a fairly simple unsafe function is System.Double.IsInfinity.

Reflector gives the following code:
public static unsafe bool IsInfinity(double d)
{
return (((((long) &d)) & 0x7fffffffffffffffL) == 0x7ff0000000000000L);
}

ILSpy 1.0.0.427 Gives:
public static bool IsInfinity(double d)
{
return (ldind.i8((object)ref d) & 9223372036854775807L) == 9218868437227405312L;
}

There are a few things needed for this:

  • Unsafe blocks can be identified and be inserted into the code.
  • If the unsafe block covers a large enough percentage of the a function, it should be promoted to an "unsafe" keyword on the function itself.
  • The indirect loading instructions must be converted to pointer references.
  • Type inference needs to be improved to support inferring pointer types in expressions like those shown.

This particular function would also greatly benefit from an option or heuristics for displaying literals in Hexadecimal format, but that would be a separate issue.

StackOverflow in C# decompiler

Hey,
I've got the latest sources and I tried to decompile the SearchBox from ILSpy and ILSpy crashed...

When debugging I got this error:
Can not intercept exception. Debugged program can not be continued and properties can not be evaluated.
System.StackOverflowException
at Object Decompiler.Transforms.PushNegation.VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, Object data) in e:\ILSpy\ICSharpCode.Decompiler\Ast\Transforms\PushNegation.cs:line 80
at Object ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression.AcceptVisitor(IAstVisitor2 visitor, Object data) in e:\ILSpy\NRefactory\ICSharpCode.NRefactory\CSharp\Ast\Expressions\BinaryOperatorExpression.cs:line 72 at Object Decompiler.Transforms.PushNegation.VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, Object data) in e:\ILSpy\ICSharpCode.Decompiler\Ast\Transforms\PushNegation.cs:line 86 at Object ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression.AcceptVisitor(IAstVisitor2 visitor, Object data) in e:\ILSpy\NRefactory\ICSharpCode.NRefactory\CSharp\Ast\Expressions\BinaryOperatorExpression.cs:line 72
at Object Decompiler.Transforms.PushNegation.VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, Object data) in e:\ILSpy\ICSharpCode.Decompiler\Ast\Transforms\PushNegation.cs:line 86
at Object ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression.AcceptVisitor(IAstVisitor2 visitor, Object data) in e:\ILSpy\NRefactory\ICSharpCode.NRefactory\CSharp\Ast\Expressions\BinaryOperatorExpression.cs:line 72 at Object Decompiler.Transforms.PushNegation.VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, Object data) in e:\ILSpy\ICSharpCode.Decompiler\Ast\Transforms\PushNegation.cs:line 86 at Object ICSharpCode.NRefactory.CSharp.BinaryOperatorExpression.AcceptVisitor(IAstVisitor2 visitor, Object data) in e:\ILSpy\NRefactory\ICSharpCode.NRefactory\CSharp\Ast\Expressions\BinaryOperatorExpression.cs:line 72

typo in test runner

ICSharpCode.Decompiler/Tests/TestRunner.cs line 75

        while ((line2 = r2.ReadLine()) != null) {
            ok = false;
  •           diff.WriteLine("+" + line1);
    
  •           diff.WriteLine("+" + line2);
        }
    

redundant ctor

in a class without a ctor, ILSpy shows this:

public() : base()
{
}

C# null check is wrong

C# null checks are decompiled as :
if(instance)
{
instance.Dispose();
}
Correct should be
if (instance != null)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.