Browse Source

Fixed several bugs in the IL disassembler.

pull/194/merge
Daniel Grunwald 14 years ago
parent
commit
d362f8d0f6
  1. 155
      ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs
  2. 59
      ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs
  3. 130
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  4. 14
      ICSharpCode.Decompiler/ILAst/ILAstTypes.cs
  5. 4
      ILSpy/ILAstLanguage.cs
  6. 44
      ILSpy/ILLanguage.cs

155
ICSharpCode.Decompiler/Disassembler/DisassemblerHelpers.cs

@ -22,6 +22,26 @@ using Mono.Cecil.Cil; @@ -22,6 +22,26 @@ using Mono.Cecil.Cil;
namespace ICSharpCode.Decompiler.Disassembler
{
public enum ILNameSyntax
{
/// <summary>
/// class/valuetype + TypeName (built-in types use keyword syntax)
/// </summary>
Signature,
/// <summary>
/// Like signature, but always refers to type parameters using their position
/// </summary>
SignatureNoNamedTypeParameters,
/// <summary>
/// [assembly]Full.Type.Name (even for built-in types)
/// </summary>
TypeName,
/// <summary>
/// Name (even for built-in types)
/// </summary>
ShortTypeName
}
public static class DisassemblerHelpers
{
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction)
@ -35,6 +55,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -35,6 +55,7 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteOffsetReference(writer, exceptionHandler.TryStart);
writer.Write('-');
WriteOffsetReference(writer, exceptionHandler.TryEnd);
writer.Write(' ');
writer.Write(exceptionHandler.HandlerType.ToString());
if (exceptionHandler.FilterStart != null) {
writer.Write(' ');
@ -84,44 +105,70 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -84,44 +105,70 @@ namespace ICSharpCode.Decompiler.Disassembler
{
if (method.HasThis)
writer.Write("instance ");
method.ReturnType.WriteTo(writer);
method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
writer.Write(' ');
if (method.DeclaringType != null) {
method.DeclaringType.WriteTo(writer, true);
method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write("::");
}
writer.WriteReference(method.Name, method);
writer.WriteReference(Escape(method.Name), method);
GenericInstanceMethod gim = method as GenericInstanceMethod;
if (gim != null) {
writer.Write('<');
for (int i = 0; i < gim.GenericArguments.Count; i++) {
if (i > 0)
writer.Write(", ");
gim.GenericArguments[i].WriteTo(writer);
}
writer.Write('>');
}
writer.Write("(");
var parameters = method.Parameters;
for(int i = 0; i < parameters.Count; ++i) {
if (i > 0) writer.Write(", ");
parameters[i].ParameterType.WriteTo(writer);
parameters[i].ParameterType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
}
writer.Write(")");
}
static void WriteTo(this FieldReference field, ITextOutput writer)
{
field.FieldType.WriteTo(writer);
field.FieldType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
writer.Write(' ');
field.DeclaringType.WriteTo(writer);
field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write("::");
writer.WriteReference(field.Name, field);
writer.WriteReference(Escape(field.Name), field);
}
static bool IsValidIdentifier(string identifier)
{
if (string.IsNullOrEmpty(identifier))
return false;
if (!(char.IsLetter(identifier[0]) || identifier[0] == '_' || identifier[0] == '.'))
return false;
for (int i = 1; i < identifier.Length; i++) {
if (!(char.IsLetterOrDigit(identifier[i]) || identifier[i] == '_' || identifier[i] == '.' || identifier[i] == '`'))
return false;
}
return true;
}
public static string Escape(string identifier)
{
return identifier;
if (IsValidIdentifier(identifier) && identifier != "value")
return identifier;
else
return "'" + identifier + "'";
}
public static void WriteTo(this TypeReference type, ITextOutput writer, bool onlyName = false, bool shortName = false)
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
{
if (type is PinnedType) {
writer.Write("pinned ");
((PinnedType)type).ElementType.WriteTo(writer, onlyName, shortName);
((PinnedType)type).ElementType.WriteTo(writer, syntax);
} else if (type is ArrayType) {
ArrayType at = (ArrayType)type;
at.ElementType.WriteTo(writer, onlyName, shortName);
at.ElementType.WriteTo(writer, syntax);
writer.Write('[');
writer.Write(string.Join(", ", at.Dimensions));
writer.Write(']');
@ -129,49 +176,54 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -129,49 +176,54 @@ namespace ICSharpCode.Decompiler.Disassembler
writer.Write('!');
if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method)
writer.Write('!');
writer.Write(type.Name);
if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
writer.Write(((GenericParameter)type).Position.ToString());
else
writer.Write(Escape(type.Name));
} else if (type is ByReferenceType) {
((ByReferenceType)type).ElementType.WriteTo(writer, onlyName, shortName);
((ByReferenceType)type).ElementType.WriteTo(writer, syntax);
writer.Write('&');
} else if (type is PointerType) {
((PointerType)type).ElementType.WriteTo(writer, onlyName, shortName);
((PointerType)type).ElementType.WriteTo(writer, syntax);
writer.Write('*');
} else if (type is GenericInstanceType) {
type.GetElementType().WriteTo(writer, onlyName, shortName);
type.GetElementType().WriteTo(writer, syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature);
writer.Write('<');
var arguments = ((GenericInstanceType)type).GenericArguments;
for (int i = 0; i < arguments.Count; i++) {
if (i > 0)
writer.Write(", ");
arguments[i].WriteTo(writer, onlyName, shortName);
arguments[i].WriteTo(writer, syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature);
}
writer.Write('>');
} else if (type is OptionalModifierType) {
writer.Write("modopt(");
((OptionalModifierType)type).ModifierType.WriteTo(writer, true, shortName);
((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write(") ");
((OptionalModifierType)type).ElementType.WriteTo(writer, onlyName, shortName);
((OptionalModifierType)type).ElementType.WriteTo(writer, syntax);
} else if (type is RequiredModifierType) {
writer.Write("modreq(");
((RequiredModifierType)type).ModifierType.WriteTo(writer, true, shortName);
((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write(") ");
((RequiredModifierType)type).ElementType.WriteTo(writer, onlyName, shortName);
((RequiredModifierType)type).ElementType.WriteTo(writer, syntax);
} else {
string name = PrimitiveTypeName(type);
if (name != null) {
if (syntax == ILNameSyntax.ShortTypeName) {
writer.WriteReference(Escape(type.Name), type);
} else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) {
writer.Write(name);
} else {
if (!onlyName)
if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
writer.Write(type.IsValueType ? "valuetype " : "class ");
if (type.DeclaringType != null) {
type.DeclaringType.WriteTo(writer, true, shortName);
type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
writer.Write('/');
writer.WriteReference(Escape(type.Name), type);
} else {
if (!type.IsDefinition && type.Scope != null && !shortName && !(type is TypeSpecification))
if (!type.IsDefinition && type.Scope != null && !(type is TypeSpecification))
writer.Write("[{0}]", Escape(type.Scope.Name));
writer.WriteReference(shortName ? type.Name : type.FullName, type);
writer.WriteReference(Escape(type.FullName), type);
}
}
}
@ -196,7 +248,19 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -196,7 +248,19 @@ namespace ICSharpCode.Decompiler.Disassembler
VariableReference variableRef = operand as VariableReference;
if (variableRef != null) {
writer.WriteReference(variableRef.Index.ToString(), variableRef);
if (string.IsNullOrEmpty(variableRef.Name))
writer.WriteReference(variableRef.Index.ToString(), variableRef);
else
writer.WriteReference(Escape(variableRef.Name), variableRef);
return;
}
ParameterReference paramRef = operand as ParameterReference;
if (paramRef != null) {
if (string.IsNullOrEmpty(paramRef.Name))
writer.WriteReference(paramRef.Index.ToString(), paramRef);
else
writer.WriteReference(Escape(paramRef.Name), paramRef);
return;
}
@ -208,7 +272,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -208,7 +272,7 @@ namespace ICSharpCode.Decompiler.Disassembler
TypeReference typeRef = operand as TypeReference;
if (typeRef != null) {
typeRef.WriteTo(writer);
typeRef.WriteTo(writer, ILNameSyntax.TypeName);
return;
}
@ -224,6 +288,41 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -224,6 +288,41 @@ namespace ICSharpCode.Decompiler.Disassembler
return;
}
if (operand is float) {
float val = (float)operand;
if (val == 0) {
writer.Write("0.0");
} else if (float.IsInfinity(val) || float.IsNaN(val)) {
byte[] data = BitConverter.GetBytes(val);
writer.Write('(');
for (int i = 0; i < data.Length; i++) {
if (i > 0)
writer.Write(' ');
writer.Write(data[i].ToString("X2"));
}
writer.Write(')');
} else {
writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
}
return;
} else if (operand is double) {
double val = (double)operand;
if (val == 0) {
writer.Write("0.0");
} else if (double.IsInfinity(val) || double.IsNaN(val)) {
byte[] data = BitConverter.GetBytes(val);
writer.Write('(');
for (int i = 0; i < data.Length; i++) {
if (i > 0)
writer.Write(' ');
writer.Write(data[i].ToString("X2"));
}
writer.Write(')');
} else {
writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture));
}
return;
}
s = ToInvariantCultureString(operand);
writer.Write(s);
}
@ -261,6 +360,8 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -261,6 +360,8 @@ namespace ICSharpCode.Decompiler.Disassembler
return "char";
case "System.Object":
return "object";
case "System.IntPtr":
return "native int";
default:
return null;
}

59
ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs

@ -69,8 +69,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -69,8 +69,12 @@ namespace ICSharpCode.Decompiler.Disassembler
foreach (var v in method.Body.Variables) {
output.WriteDefinition("[" + v.Index + "] ", v);
v.VariableType.WriteTo(output);
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(v.Name));
if (!string.IsNullOrEmpty(v.Name)) {
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(v.Name));
}
if (v.Index + 1 < method.Body.Variables.Count)
output.Write(',');
output.WriteLine();
}
output.Unindent();
@ -85,20 +89,24 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -85,20 +89,24 @@ namespace ICSharpCode.Decompiler.Disassembler
foreach (var inst in method.Body.Instructions) {
inst.WriteTo(output);
// add IL code mappings - used in debugger
methodMapping.MemberCodeMappings.Add(
new SourceCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset },
MemberMapping = methodMapping
});
if (methodMapping != null) {
// add IL code mappings - used in debugger
methodMapping.MemberCodeMappings.Add(
new SourceCodeMapping() {
SourceCodeLine = output.CurrentLine,
ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset },
MemberMapping = methodMapping
});
}
output.WriteLine();
}
output.WriteLine();
foreach (var eh in method.Body.ExceptionHandlers) {
eh.WriteTo(output);
if (method.Body.HasExceptionHandlers) {
output.WriteLine();
foreach (var eh in method.Body.ExceptionHandlers) {
eh.WriteTo(output);
output.WriteLine();
}
}
}
}
@ -116,7 +124,8 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -116,7 +124,8 @@ namespace ICSharpCode.Decompiler.Disassembler
output.WriteLine();
break;
case ILStructureType.Try:
output.WriteLine(".try {");
output.WriteLine(".try");
output.WriteLine("{");
break;
case ILStructureType.Handler:
switch (s.ExceptionHandler.HandlerType) {
@ -125,22 +134,24 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -125,22 +134,24 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("catch");
if (s.ExceptionHandler.CatchType != null) {
output.Write(' ');
s.ExceptionHandler.CatchType.WriteTo(output);
s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
}
output.WriteLine(" {");
output.WriteLine();
break;
case Mono.Cecil.Cil.ExceptionHandlerType.Finally:
output.WriteLine("finally {");
output.WriteLine("finally");
break;
case Mono.Cecil.Cil.ExceptionHandlerType.Fault:
output.WriteLine("fault {");
output.WriteLine("fault");
break;
default:
throw new NotSupportedException();
}
output.WriteLine("{");
break;
case ILStructureType.Filter:
output.WriteLine("filter {");
output.WriteLine("filter");
output.WriteLine("{");
break;
default:
throw new NotSupportedException();
@ -150,6 +161,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -150,6 +161,7 @@ namespace ICSharpCode.Decompiler.Disassembler
void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
{
bool prevInstructionWasBranch = false;
int childIndex = 0;
while (inst != null && inst.Offset < s.EndOffset) {
int offset = inst.Offset;
@ -158,7 +170,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -158,7 +170,12 @@ namespace ICSharpCode.Decompiler.Disassembler
WriteStructureHeader(child);
WriteStructureBody(child, ref inst, currentMethodMapping, codeSize);
WriteStructureFooter(child);
prevInstructionWasBranch = false;
} else {
if (prevInstructionWasBranch) {
output.WriteLine(); // put empty line after branch instructions
}
inst.WriteTo(output);
// add IL code mappings - used in debugger
@ -172,6 +189,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -172,6 +189,12 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.WriteLine();
prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch
|| inst.OpCode.FlowControl == FlowControl.Cond_Branch
|| inst.OpCode.FlowControl == FlowControl.Return
|| inst.OpCode.FlowControl == FlowControl.Throw;
inst = inst.Next;
}
}

130
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -32,7 +32,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -32,7 +32,6 @@ namespace ICSharpCode.Decompiler.Disassembler
{
ITextOutput output;
CancellationToken cancellationToken;
bool detectControlStructure;
bool isInType; // whether we are currently disassembling a whole type (-> defaultCollapsed for foldings)
MethodBodyDisassembler methodBodyDisassembler;
@ -42,23 +41,22 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -42,23 +41,22 @@ namespace ICSharpCode.Decompiler.Disassembler
throw new ArgumentNullException("output");
this.output = output;
this.cancellationToken = cancellationToken;
this.detectControlStructure = detectControlStructure;
this.methodBodyDisassembler = new MethodBodyDisassembler(output, detectControlStructure, cancellationToken);
}
#region Disassemble Method
EnumNameCollection<MethodAttributes> methodAttributeFlags = new EnumNameCollection<MethodAttributes>() {
{ MethodAttributes.Static, "static" },
{ MethodAttributes.Final, "final" },
{ MethodAttributes.Virtual, "virtual" },
{ MethodAttributes.HideBySig, "hidebysig" },
{ MethodAttributes.Abstract, "abstract" },
{ MethodAttributes.SpecialName, "specialname" },
{ MethodAttributes.PInvokeImpl, "pinvokeimpl" },
{ MethodAttributes.UnmanagedExport, "export" },
{ MethodAttributes.RTSpecialName, "rtspecialname" },
{ MethodAttributes.RequireSecObject, "requiresecobj" },
{ MethodAttributes.NewSlot, "newslot" }
{ MethodAttributes.NewSlot, "newslot" },
{ MethodAttributes.Virtual, "virtual" },
{ MethodAttributes.Abstract, "abstract" },
{ MethodAttributes.Static, "static" }
};
EnumNameCollection<MethodAttributes> methodVisibility = new EnumNameCollection<MethodAttributes>() {
@ -156,7 +154,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -156,7 +154,7 @@ namespace ICSharpCode.Decompiler.Disassembler
methodBodyDisassembler.Disassemble(method.Body, methodMapping);
}
CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name);
CloseBlock("end of method " + method.DeclaringType.Name + "::" + method.Name);
} else {
output.WriteLine();
}
@ -234,12 +232,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -234,12 +232,11 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(" = ");
DisassemblerHelpers.WriteOperand(output, field.Constant);
}
output.WriteLine();
if (field.HasCustomAttributes) {
OpenBlock(false);
output.MarkFoldStart();
WriteAttributes(field.CustomAttributes);
CloseBlock();
} else {
output.WriteLine();
output.MarkFoldEnd();
}
}
#endregion
@ -255,9 +252,21 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -255,9 +252,21 @@ namespace ICSharpCode.Decompiler.Disassembler
{
output.WriteDefinition(".property ", property);
WriteFlags(property.Attributes, propertyAttributes);
if (property.HasThis)
output.Write("instance ");
property.PropertyType.WriteTo(output);
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(property.Name));
output.Write("(");
if (property.HasParameters) {
output.WriteLine();
output.Indent();
WriteParameters(property.Parameters);
output.Unindent();
}
output.Write(")");
OpenBlock(false);
WriteAttributes(property.CustomAttributes);
WriteNestedMethod(".get", property.GetMethod);
@ -272,16 +281,10 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -272,16 +281,10 @@ namespace ICSharpCode.Decompiler.Disassembler
{
if (method == null)
return;
if (detectControlStructure) {
output.WriteDefinition(keyword, method);
output.Write(' ');
DisassembleMethodInternal(method);
} else {
output.Write(keyword);
output.Write(' ');
method.WriteTo(output);
output.WriteLine();
}
output.Write(keyword);
output.Write(' ');
method.WriteTo(output);
output.WriteLine();
}
#endregion
@ -361,7 +364,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -361,7 +364,7 @@ namespace ICSharpCode.Decompiler.Disassembler
const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;
WriteFlags(type.Attributes & ~masks, typeAttributes);
output.Write(DisassemblerHelpers.Escape(type.Name));
output.Write(DisassemblerHelpers.Escape(type.DeclaringType != null ? type.Name : type.FullName));
WriteTypeParameters(output, type);
output.MarkFoldStart(defaultCollapsed: isInType);
output.WriteLine();
@ -369,7 +372,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -369,7 +372,7 @@ namespace ICSharpCode.Decompiler.Disassembler
if (type.BaseType != null) {
output.Indent();
output.Write("extends ");
type.BaseType.WriteTo(output, true);
type.BaseType.WriteTo(output, ILNameSyntax.TypeName);
output.WriteLine();
output.Unindent();
}
@ -382,9 +385,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -382,9 +385,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write("implements ");
else
output.Write(" ");
if (type.Interfaces[index].Namespace != null)
output.Write("{0}.", type.Interfaces[index].Namespace);
output.Write(type.Interfaces[index].Name);
type.Interfaces[index].WriteTo(output, ILNameSyntax.TypeName);
}
output.WriteLine();
output.Unindent();
@ -417,6 +418,14 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -417,6 +418,14 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.WriteLine();
}
if (type.HasMethods) {
output.WriteLine("// Methods");
foreach (var m in type.Methods) {
cancellationToken.ThrowIfCancellationRequested();
DisassembleMethod(m);
output.WriteLine();
}
}
if (type.HasProperties) {
output.WriteLine("// Properties");
foreach (var prop in type.Properties) {
@ -434,18 +443,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -434,18 +443,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.WriteLine();
}
if (type.HasMethods) {
output.WriteLine("// Methods");
var accessorMethods = type.GetAccessorMethods();
foreach (var m in type.Methods) {
cancellationToken.ThrowIfCancellationRequested();
if (!(detectControlStructure && accessorMethods.Contains(m))) {
DisassembleMethod(m);
output.WriteLine();
}
}
}
CloseBlock("End of class " + type.FullName);
CloseBlock("end of class " + (type.DeclaringType != null ? type.Name : type.FullName));
isInType = oldIsInType;
}
@ -467,7 +465,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -467,7 +465,7 @@ namespace ICSharpCode.Decompiler.Disassembler
for (int j = 0; j < gp.Constraints.Count; j++) {
if (j > 0)
output.Write(", ");
gp.Constraints[j].WriteTo(output, true);
gp.Constraints[j].WriteTo(output, ILNameSyntax.TypeName);
}
output.Write(") ");
}
@ -616,9 +614,11 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -616,9 +614,11 @@ namespace ICSharpCode.Decompiler.Disassembler
{
output.Write(".assembly " + DisassemblerHelpers.Escape(asm.Name.Name));
OpenBlock(false);
Version v = asm.Name.Version;
if (v != null) {
output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision);
WriteAttributes(asm.CustomAttributes);
if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) {
output.Write(".publickey = ");
WriteBlob(asm.Name.PublicKey);
output.WriteLine();
}
if (asm.Name.HashAlgorithm != AssemblyHashAlgorithm.None) {
output.Write(".hash algorithm 0x{0:x8}", (int)asm.Name.HashAlgorithm);
@ -626,15 +626,51 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -626,15 +626,51 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(" // SHA1");
output.WriteLine();
}
if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) {
output.Write(".publickey = ");
WriteBlob(asm.Name.PublicKey);
output.WriteLine();
Version v = asm.Name.Version;
if (v != null) {
output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision);
}
WriteAttributes(asm.CustomAttributes);
CloseBlock();
}
public void WriteAssemblyReferences(ModuleDefinition module)
{
foreach (var mref in module.ModuleReferences) {
output.WriteLine(".module extern {0}", DisassemblerHelpers.Escape(mref.Name));
}
foreach (var aref in module.AssemblyReferences) {
output.Write(".assembly extern {0}", DisassemblerHelpers.Escape(aref.Name));
OpenBlock(false);
if (aref.PublicKeyToken != null) {
output.Write(".publickeytoken = ");
WriteBlob(aref.PublicKeyToken);
output.WriteLine();
}
if (aref.Version != null) {
output.WriteLine(".ver {0}:{1}:{2}:{3}", aref.Version.Major, aref.Version.Minor, aref.Version.Build, aref.Version.Revision);
}
CloseBlock();
}
}
public void WriteModuleHeader(ModuleDefinition module)
{
output.WriteLine(".module {0}", module.Name);
output.WriteLine("// MVID: {0}", module.Mvid.ToString("B").ToUpperInvariant());
// TODO: imagebase, file alignment, stackreserve, subsystem
output.WriteLine(".corflags 0x{0:x} // {1}", module.Attributes, module.Attributes.ToString());
WriteAttributes(module.CustomAttributes);
}
public void WriteModuleContents(ModuleDefinition module)
{
foreach (TypeDefinition td in module.Types) {
DisassembleType(td);
output.WriteLine();
}
}
/// <inheritdoc/>
public Tuple<string, List<MemberMapping>> CodeMappings {
get;

14
ICSharpCode.Decompiler/ILAst/ILAstTypes.cs

@ -378,10 +378,10 @@ namespace ICSharpCode.Decompiler.ILAst @@ -378,10 +378,10 @@ namespace ICSharpCode.Decompiler.ILAst
output.Write(((ILVariable)Operand).Name);
if (this.InferredType != null) {
output.Write(':');
this.InferredType.WriteTo(output, true, true);
this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName);
if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) {
output.Write("[exp:");
this.ExpectedType.WriteTo(output, true, true);
this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
output.Write(']');
}
}
@ -399,15 +399,15 @@ namespace ICSharpCode.Decompiler.ILAst @@ -399,15 +399,15 @@ namespace ICSharpCode.Decompiler.ILAst
output.Write(Code.GetName());
if (this.InferredType != null) {
output.Write(':');
this.InferredType.WriteTo(output, true, true);
this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName);
if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) {
output.Write("[exp:");
this.ExpectedType.WriteTo(output, true, true);
this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
output.Write(']');
}
} else if (this.ExpectedType != null) {
output.Write("[exp:");
this.ExpectedType.WriteTo(output, true, true);
this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName);
output.Write(']');
}
output.Write('(');
@ -425,13 +425,13 @@ namespace ICSharpCode.Decompiler.ILAst @@ -425,13 +425,13 @@ namespace ICSharpCode.Decompiler.ILAst
} else if (Operand is MethodReference) {
MethodReference method = (MethodReference)Operand;
if (method.DeclaringType != null) {
method.DeclaringType.WriteTo(output, true, true);
method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName);
output.Write("::");
}
output.WriteReference(method.Name, method);
} else if (Operand is FieldReference) {
FieldReference field = (FieldReference)Operand;
field.DeclaringType.WriteTo(output, true, true);
field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName);
output.Write("::");
output.WriteReference(field.Name, field);
} else {

4
ILSpy/ILAstLanguage.cs

@ -68,7 +68,7 @@ namespace ICSharpCode.ILSpy @@ -68,7 +68,7 @@ namespace ICSharpCode.ILSpy
output.Write(" : ");
if (v.IsPinned)
output.Write("pinned ");
v.Type.WriteTo(output, true, true);
v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
}
output.WriteLine();
}
@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy @@ -100,7 +100,7 @@ namespace ICSharpCode.ILSpy
public override string TypeToString(TypeReference t, bool includeNamespace, ICustomAttributeProvider attributeProvider)
{
PlainTextOutput output = new PlainTextOutput();
t.WriteTo(output, true, shortName: !includeNamespace);
t.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
return output.ToString();
}
}

44
ILSpy/ILLanguage.cs

@ -62,12 +62,38 @@ namespace ICSharpCode.ILSpy @@ -62,12 +62,38 @@ namespace ICSharpCode.ILSpy
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleProperty(property);
ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken);
rd.DisassembleProperty(property);
if (property.GetMethod != null) {
output.WriteLine();
rd.DisassembleMethod(property.GetMethod);
}
if (property.SetMethod != null) {
output.WriteLine();
rd.DisassembleMethod(property.SetMethod);
}
foreach (var m in property.OtherMethods) {
output.WriteLine();
rd.DisassembleMethod(m);
}
}
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).DisassembleEvent(ev);
ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken);
rd.DisassembleEvent(ev);
if (ev.AddMethod != null) {
output.WriteLine();
rd.DisassembleMethod(ev.AddMethod);
}
if (ev.RemoveMethod != null) {
output.WriteLine();
rd.DisassembleMethod(ev.RemoveMethod);
}
foreach (var m in ev.OtherMethods) {
output.WriteLine();
rd.DisassembleMethod(m);
}
}
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
@ -85,13 +111,23 @@ namespace ICSharpCode.ILSpy @@ -85,13 +111,23 @@ namespace ICSharpCode.ILSpy
output.WriteLine("// " + assembly.FileName);
output.WriteLine();
new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken).WriteAssemblyHeader(assembly.AssemblyDefinition);
ReflectionDisassembler rd = new ReflectionDisassembler(output, detectControlStructure, options.CancellationToken);
if (options.FullDecompilation)
rd.WriteAssemblyReferences(assembly.AssemblyDefinition.MainModule);
rd.WriteAssemblyHeader(assembly.AssemblyDefinition);
output.WriteLine();
rd.WriteModuleHeader(assembly.AssemblyDefinition.MainModule);
if (options.FullDecompilation) {
output.WriteLine();
output.WriteLine();
rd.WriteModuleContents(assembly.AssemblyDefinition.MainModule);
}
}
public override string TypeToString(TypeReference t, bool includeNamespace, ICustomAttributeProvider attributeProvider)
{
PlainTextOutput output = new PlainTextOutput();
t.WriteTo(output, true, shortName: !includeNamespace);
t.WriteTo(output, includeNamespace ? ILNameSyntax.TypeName : ILNameSyntax.ShortTypeName);
return output.ToString();
}
}

Loading…
Cancel
Save