Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 15 years ago
parent
commit
0c2a2abc93
  1. 2
      ICSharpCode.Decompiler/Disassembler/ILStructure.cs
  2. 5
      ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs
  3. 6
      ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs
  4. 59
      ICSharpCode.Decompiler/Tests/BooleanConsumedAsInteger.il
  5. 25
      ICSharpCode.Decompiler/Tests/ExceptionHandling.cs
  6. 8
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  7. 109
      ILSpy/CSharpLanguage.cs
  8. 38
      ILSpy/TextView/DecompilerTextView.cs
  9. 42
      ILSpy/TreeNodes/ResourceEntryNode.cs
  10. 5
      ILSpy/TreeNodes/ResourceListTreeNode.cs
  11. 10
      NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

2
ICSharpCode.Decompiler/Disassembler/ILStructure.cs

@ -92,7 +92,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -92,7 +92,7 @@ namespace ICSharpCode.Decompiler.Disassembler
AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh));
if (eh.HandlerType == ExceptionHandlerType.Filter)
AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.FilterEnd.Offset, eh));
AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd.Offset, eh));
AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh));
}
// Very simple loop detection: look for backward branches
List<KeyValuePair<Instruction, Instruction>> allBranches = FindAllBranches(body);

5
ICSharpCode.Decompiler/ILAst/ILAstBuilder.cs

@ -567,8 +567,9 @@ namespace Decompiler @@ -567,8 +567,9 @@ namespace Decompiler
int startIndex;
for (startIndex = 0; body[startIndex].Offset != eh.HandlerStart.Offset; startIndex++);
int endInclusiveIndex;
// Note that the end(exclusiove) instruction may not necessarly be in our body
for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++);
if (eh.HandlerEnd == null) endInclusiveIndex = body.Count - 1;
// Note that the end(exclusive) instruction may not necessarly be in our body
else for (endInclusiveIndex = 0; body[endInclusiveIndex].Next.Offset != eh.HandlerEnd.Offset; endInclusiveIndex++);
int count = 1 + endInclusiveIndex - startIndex;
HashSet<ExceptionHandler> nestedEHs = new HashSet<ExceptionHandler>(ehs.Where(e => (eh.HandlerStart.Offset <= e.TryStart.Offset && e.TryEnd.Offset < eh.HandlerEnd.Offset) || (eh.HandlerStart.Offset < e.TryStart.Offset && e.TryEnd.Offset <= eh.HandlerEnd.Offset)));
ehs.ExceptWith(nestedEHs);

6
ICSharpCode.Decompiler/ILAst/TypeAnalysis.cs

@ -286,7 +286,9 @@ namespace Decompiler @@ -286,7 +286,9 @@ namespace Decompiler
case ILCode.Ldvirtftn:
return typeSystem.IntPtr;
case ILCode.Ldc_I4:
return (IsIntegerOrEnum(expectedType) || IsBoolean(expectedType)) ? expectedType : typeSystem.Int32;
if (IsBoolean(expectedType) && ((int)expr.Operand == 0 || (int)expr.Operand == 1))
return typeSystem.Boolean;
return IsIntegerOrEnum(expectedType) ? expectedType : typeSystem.Int32;
case ILCode.Ldc_I8:
return (IsIntegerOrEnum(expectedType)) ? expectedType : typeSystem.Int64;
case ILCode.Ldc_R4:
@ -561,7 +563,7 @@ namespace Decompiler @@ -561,7 +563,7 @@ namespace Decompiler
} else {
left.ExpectedType = right.ExpectedType = TypeWithMoreInformation(leftPreferred, rightPreferred);
left.InferredType = DoInferTypeForExpression(left, left.ExpectedType);
right.InferredType = DoInferTypeForExpression(left, right.ExpectedType);
right.InferredType = DoInferTypeForExpression(right, right.ExpectedType);
return left.ExpectedType;
}
}

59
ICSharpCode.Decompiler/Tests/BooleanConsumedAsInteger.il

@ -0,0 +1,59 @@ @@ -0,0 +1,59 @@
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 4:0:0:0
}
.assembly BooleanConsumedAsInteger
{
.hash algorithm 0x00008004
.ver 1:0:0:0
}
.module BooleanConsumedAsInteger.exe
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000003 // ILONLY 32BITREQUIRED
.class private auto ansi beforefieldinit BooleanConsumedAsInteger.Program extends [mscorlib]System.Object
{
.method public hidebysig static void Main(string[] args) cil managed
{
.entrypoint
.maxstack 8
ret
}
.method public hidebysig static int32 ReturnBoolAsInt() cil managed
{
ldnull
ldnull
call bool [mscorlib] System.Object::Equals(object, object)
ret
}
.method public hidebysig static int32 BitwiseOperationOnBool() cil managed
{
ldnull
ldnull
call bool [mscorlib] System.Object::Equals(object, object)
ldc.i4 255
and
ret
}
.method public hidebysig specialname rtspecialname
instance void .ctor() cil managed
{
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [mscorlib]System.Object::.ctor()
IL_0006: ret
} // end of method Program::.ctor
} // end of class StackTests.Program
// =============================================================

25
ICSharpCode.Decompiler/Tests/ExceptionHandling.cs

@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
public class ExceptionHandling
{
public void MethodEndingWithEndFinally()
{
try {
throw null;
} finally {
Console.WriteLine();
}
}
public void MethodEndingWithRethrow()
{
try {
throw null;
} catch {
throw;
}
}
}

8
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -49,6 +49,7 @@ @@ -49,6 +49,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="DelegateConstruction.cs" />
<Compile Include="ExceptionHandling.cs" />
<Compile Include="Loops.cs" />
<Compile Include="PropertiesAndEvents.cs" />
<Compile Include="TestRunner.cs" />
@ -64,5 +65,12 @@ @@ -64,5 +65,12 @@
<Name>ICSharpCode.Decompiler</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Folder Include="StackTests" />
</ItemGroup>
<ItemGroup>
<None Include="BooleanConsumedAsInteger.il" />
<None Include="StackTests\StackTests.il" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>

109
ILSpy/CSharpLanguage.cs

@ -17,12 +17,15 @@ @@ -17,12 +17,15 @@
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Resources;
using System.Threading.Tasks;
using System.Xaml;
using System.Xml;
using Decompiler;
using Decompiler.Transforms;
using ICSharpCode.Decompiler;
@ -115,7 +118,9 @@ namespace ICSharpCode.ILSpy @@ -115,7 +118,9 @@ namespace ICSharpCode.ILSpy
{
if (options.FullDecompilation) {
if (options.SaveAsProjectDirectory != null) {
var files = WriteFilesInProject(assembly, options);
HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var files = WriteCodeFilesInProject(assembly, options, directories).ToList();
files.AddRange(WriteResourceFilesInProject(assembly, fileName, options, directories));
WriteProjectFile(new TextOutputWriter(output), files, assembly.MainModule);
} else {
foreach (TypeDefinition type in assembly.MainModule.Types) {
@ -130,7 +135,8 @@ namespace ICSharpCode.ILSpy @@ -130,7 +135,8 @@ namespace ICSharpCode.ILSpy
}
}
void WriteProjectFile(TextWriter writer, IEnumerable<string> files, ModuleDefinition module)
#region WriteProjectFile
void WriteProjectFile(TextWriter writer, IEnumerable<Tuple<string, string>> files, ModuleDefinition module)
{
const string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
string platformName;
@ -236,13 +242,15 @@ namespace ICSharpCode.ILSpy @@ -236,13 +242,15 @@ namespace ICSharpCode.ILSpy
}
w.WriteEndElement(); // </ItemGroup> (References)
w.WriteStartElement("ItemGroup"); // Code
foreach (string file in files.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) {
w.WriteStartElement("Compile");
w.WriteAttributeString("Include", file);
foreach (IGrouping<string, string> gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) {
w.WriteStartElement("ItemGroup");
foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) {
w.WriteStartElement(gr.Key);
w.WriteAttributeString("Include", file);
w.WriteEndElement();
}
w.WriteEndElement();
}
w.WriteEndElement();
w.WriteStartElement("Import");
w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.CSharp.targets");
@ -251,8 +259,10 @@ namespace ICSharpCode.ILSpy @@ -251,8 +259,10 @@ namespace ICSharpCode.ILSpy
w.WriteEndDocument();
}
}
#endregion
IEnumerable<string> WriteFilesInProject(AssemblyDefinition assembly, DecompilationOptions options)
#region WriteCodeFilesInProject
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(AssemblyDefinition assembly, DecompilationOptions options, HashSet<string> directories)
{
var files = assembly.MainModule.Types.Where(t => t.Name != "<Module>").GroupBy(
delegate (TypeDefinition type) {
@ -261,11 +271,11 @@ namespace ICSharpCode.ILSpy @@ -261,11 +271,11 @@ namespace ICSharpCode.ILSpy
return file;
} else {
string dir = TextView.DecompilerTextView.CleanUpName(type.Namespace);
Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
return Path.Combine(dir, file);
}
}, StringComparer.OrdinalIgnoreCase).ToList();
AstMethodBodyBuilder.ClearUnhandledOpcodes();
Parallel.ForEach(
files,
@ -279,8 +289,83 @@ namespace ICSharpCode.ILSpy @@ -279,8 +289,83 @@ namespace ICSharpCode.ILSpy
}
});
AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
return files.Select(f => f.Key);
return files.Select(f => Tuple.Create("Compile", f.Key));
}
#endregion
#region WriteResourceFilesInProject
IEnumerable<Tuple<string, string>> WriteResourceFilesInProject(AssemblyDefinition assembly, string assemblyFileName, DecompilationOptions options, HashSet<string> directories)
{
AppDomain bamlDecompilerAppDomain = null;
try {
foreach (EmbeddedResource r in assembly.MainModule.Resources.OfType<EmbeddedResource>()) {
string fileName;
Stream s = r.GetResourceStream();
s.Position = 0;
if (r.Name.EndsWith(".g.resources", StringComparison.OrdinalIgnoreCase)) {
IEnumerable<DictionaryEntry> rs = null;
try {
rs = new ResourceSet(s).Cast<DictionaryEntry>();
} catch (ArgumentException) {
}
if (rs != null && rs.All(e => e.Value is Stream)) {
foreach (var pair in rs) {
fileName = Path.Combine(((string)pair.Key).Split('/').Select(p => TextView.DecompilerTextView.CleanUpName(p)).ToArray());
string dirName = Path.GetDirectoryName(fileName);
if (!string.IsNullOrEmpty(dirName) && directories.Add(dirName)) {
Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dirName));
}
Stream entryStream = (Stream)pair.Value;
entryStream.Position = 0;
if (fileName.EndsWith(".baml", StringComparison.OrdinalIgnoreCase)) {
MemoryStream ms = new MemoryStream();
entryStream.CopyTo(ms);
BamlDecompiler decompiler = TreeNodes.ResourceEntryNode.CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, assemblyFileName);
string xaml = null;
try {
xaml = decompiler.DecompileBaml(ms, assemblyFileName);
} catch (XamlXmlWriterException) {} // ignore XAML writer exceptions
if (xaml != null) {
File.WriteAllText(Path.Combine(options.SaveAsProjectDirectory, Path.ChangeExtension(fileName, ".xaml")), xaml);
yield return Tuple.Create("Page", Path.ChangeExtension(fileName, ".xaml"));
continue;
}
}
using (FileStream fs = new FileStream(Path.Combine(options.SaveAsProjectDirectory, fileName), FileMode.Create, FileAccess.Write)) {
entryStream.CopyTo(fs);
}
yield return Tuple.Create("Resource", fileName);
}
continue;
}
}
fileName = GetFileNameForResource(r.Name, directories);
using (FileStream fs = new FileStream(Path.Combine(options.SaveAsProjectDirectory, fileName), FileMode.Create, FileAccess.Write)) {
s.CopyTo(fs);
}
yield return Tuple.Create("EmbeddedResource", fileName);
}
} finally {
if (bamlDecompilerAppDomain != null)
AppDomain.Unload(bamlDecompilerAppDomain);
}
}
string GetFileNameForResource(string fullName, HashSet<string> directories)
{
string[] splitName = fullName.Split('.');
string fileName = TextView.DecompilerTextView.CleanUpName(fullName);
for (int i = splitName.Length - 1; i > 0; i--) {
string ns = string.Join(".", splitName, 0, i);
if (directories.Contains(ns)) {
string name = string.Join(".", splitName, i, splitName.Length - i);
fileName = Path.Combine(ns, TextView.DecompilerTextView.CleanUpName(name));
break;
}
}
return fileName;
}
#endregion
AstBuilder CreateAstBuilder(DecompilationOptions options, TypeDefinition currentType)
{

38
ILSpy/TextView/DecompilerTextView.cs

@ -283,21 +283,31 @@ namespace ICSharpCode.ILSpy.TextView @@ -283,21 +283,31 @@ namespace ICSharpCode.ILSpy.TextView
Thread thread = new Thread(new ThreadStart(
delegate {
try {
AvalonEditTextOutput textOutput = new AvalonEditTextOutput();
textOutput.LengthLimit = outputLengthLimit;
DecompileNodes(context, textOutput);
textOutput.PrepareDocument();
tcs.SetResult(textOutput);
#if DEBUG
} catch (AggregateException ex) {
tcs.SetException(ex);
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
#else
} catch (Exception ex) {
tcs.SetException(ex);
#if DEBUG
if (Debugger.IsAttached) {
try {
AvalonEditTextOutput textOutput = new AvalonEditTextOutput();
textOutput.LengthLimit = outputLengthLimit;
DecompileNodes(context, textOutput);
textOutput.PrepareDocument();
tcs.SetResult(textOutput);
} catch (AggregateException ex) {
tcs.SetException(ex);
} catch (OperationCanceledException ex) {
tcs.SetException(ex);
}
} else
#endif
{
try {
AvalonEditTextOutput textOutput = new AvalonEditTextOutput();
textOutput.LengthLimit = outputLengthLimit;
DecompileNodes(context, textOutput);
textOutput.PrepareDocument();
tcs.SetResult(textOutput);
} catch (Exception ex) {
tcs.SetException(ex);
}
}
}));
thread.Start();

42
ILSpy/TreeNodes/ResourceEntryNode.cs

@ -86,24 +86,36 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -86,24 +86,36 @@ namespace ICSharpCode.ILSpy.TreeNodes
{
var asm = this.Ancestors().OfType<AssemblyTreeNode>().FirstOrDefault().LoadedAssembly;
// Construct and initialize settings for a second AppDomain.
AppDomainSetup bamlDecompilerAppDomainSetup = new AppDomainSetup();
bamlDecompilerAppDomainSetup.ApplicationBase = "file:///" + Path.GetDirectoryName(asm.FileName);
bamlDecompilerAppDomainSetup.DisallowBindingRedirects = false;
bamlDecompilerAppDomainSetup.DisallowCodeDownload = true;
bamlDecompilerAppDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// Create the second AppDomain.
AppDomain bamlDecompilerAppDomain = AppDomain.CreateDomain("BamlDecompiler AD", null, bamlDecompilerAppDomainSetup);
AppDomain bamlDecompilerAppDomain = null;
try {
BamlDecompiler decompiler = CreateBamlDecompilerInAppDomain(ref bamlDecompilerAppDomain, asm.FileName);
BamlDecompiler decompiler = (BamlDecompiler)bamlDecompilerAppDomain.CreateInstanceFromAndUnwrap(typeof(BamlDecompiler).Assembly.Location, typeof(BamlDecompiler).FullName);
MemoryStream bamlStream = new MemoryStream();
value.Position = 0;
value.CopyTo(bamlStream);
MemoryStream bamlStream = new MemoryStream();
value.Position = 0;
value.CopyTo(bamlStream);
output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName));
return true;
} finally {
if (bamlDecompilerAppDomain != null)
AppDomain.Unload(bamlDecompilerAppDomain);
}
}
output.Write(decompiler.DecompileBaml(bamlStream, asm.FileName));
return true;
public static BamlDecompiler CreateBamlDecompilerInAppDomain(ref AppDomain appDomain, string assemblyFileName)
{
if (appDomain == null) {
// Construct and initialize settings for a second AppDomain.
AppDomainSetup bamlDecompilerAppDomainSetup = new AppDomainSetup();
bamlDecompilerAppDomainSetup.ApplicationBase = "file:///" + Path.GetDirectoryName(assemblyFileName);
bamlDecompilerAppDomainSetup.DisallowBindingRedirects = false;
bamlDecompilerAppDomainSetup.DisallowCodeDownload = true;
bamlDecompilerAppDomainSetup.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// Create the second AppDomain.
appDomain = AppDomain.CreateDomain("BamlDecompiler AD", null, bamlDecompilerAppDomainSetup);
}
return (BamlDecompiler)appDomain.CreateInstanceFromAndUnwrap(typeof(BamlDecompiler).Assembly.Location, typeof(BamlDecompiler).FullName);
}
public override bool Save(DecompilerTextView textView)

5
ILSpy/TreeNodes/ResourceListTreeNode.cs

@ -156,9 +156,10 @@ namespace ICSharpCode.ILSpy.TreeNodes @@ -156,9 +156,10 @@ namespace ICSharpCode.ILSpy.TreeNodes
if (er != null) {
try {
Stream s = er.GetResourceStream();
s.Position = 0;
if (er.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase)) {
ResourceSet set = new ResourceSet(s);
foreach (DictionaryEntry entry in set.Cast<DictionaryEntry>().OrderBy(e => e.Key.ToString())) {
ResourceReader reader = new ResourceReader(s);
foreach (DictionaryEntry entry in reader.Cast<DictionaryEntry>().OrderBy(e => e.Key.ToString())) {
if (entry.Value is Stream)
Children.Add(new ResourceEntryNode(entry.Key.ToString(), (Stream)entry.Value));
}

10
NRefactory/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -342,16 +342,6 @@ @@ -342,16 +342,6 @@
<Compile Include="CSharp\Ast\Statements\DoWhileStatement.cs" />
<Compile Include="CSharp\Ast\Statements\YieldBreakStatement.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="CSharp\" />
<Folder Include="CSharp\Ast\PatternMatching" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>
<Name>Mono.Cecil</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Mono.Cecil\Mono.Cecil.csproj">
<Project>{D68133BD-1E63-496E-9EDE-4FBDBF77B486}</Project>

Loading…
Cancel
Save