Browse Source

Disassembler: Refactor InstructionOutputExtensions.WriteTo: Reduce code duplication; Add support for unmanaged calling conventions

pull/1596/head
Siegfried Pammer 6 years ago
parent
commit
ab892a603b
  1. 153
      ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs

153
ICSharpCode.Decompiler/IL/InstructionOutputExtensions.cs

@ -133,14 +133,7 @@ namespace ICSharpCode.Decompiler.IL @@ -133,14 +133,7 @@ namespace ICSharpCode.Decompiler.IL
case HandleKind.MethodDefinition: {
var md = metadata.GetMethodDefinition((MethodDefinitionHandle)entity);
methodSignature = md.DecodeSignature(new DisassemblerSignatureProvider(module, output), new Metadata.GenericContext((MethodDefinitionHandle)entity, module));
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
WriteSignatureHeader(output, methodSignature);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
var declaringType = md.GetDeclaringType();
@ -189,13 +182,7 @@ namespace ICSharpCode.Decompiler.IL @@ -189,13 +182,7 @@ namespace ICSharpCode.Decompiler.IL
}
output.Write('>');
}
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
WriteParameterList(output, methodSignature);
break;
}
case HandleKind.MemberReference:
@ -204,28 +191,13 @@ namespace ICSharpCode.Decompiler.IL @@ -204,28 +191,13 @@ namespace ICSharpCode.Decompiler.IL
switch (mr.GetKind()) {
case MemberReferenceKind.Method:
methodSignature = mr.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
WriteSignatureHeader(output, methodSignature);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(output, module, metadata, mr.Parent, genericContext, syntax);
output.Write("::");
output.WriteReference(module, entity, DisassemblerHelpers.Escape(memberName));
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
if (i == methodSignature.RequiredParameterCount)
output.Write("..., ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
WriteParameterList(output, methodSignature);
break;
case MemberReferenceKind.Field:
var fieldSignature = mr.DecodeFieldSignature(new DisassemblerSignatureProvider(module, output), genericContext);
@ -245,14 +217,7 @@ namespace ICSharpCode.Decompiler.IL @@ -245,14 +217,7 @@ namespace ICSharpCode.Decompiler.IL
var methodDefinition = metadata.GetMethodDefinition((MethodDefinitionHandle)ms.Method);
var methodName = metadata.GetString(methodDefinition.Name);
methodSignature = methodDefinition.DecodeSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
WriteSignatureHeader(output, methodSignature);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
var declaringType = methodDefinition.GetDeclaringType();
@ -266,52 +231,21 @@ namespace ICSharpCode.Decompiler.IL @@ -266,52 +231,21 @@ namespace ICSharpCode.Decompiler.IL
} else {
output.Write(DisassemblerHelpers.Escape(methodName));
}
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
WriteTypeParameterList(output, syntax, substitution);
WriteParameterList(output, methodSignature);
break;
case HandleKind.MemberReference:
var memberReference = metadata.GetMemberReference((MemberReferenceHandle)ms.Method);
memberName = metadata.GetString(memberReference.Name);
methodSignature = memberReference.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
WriteSignatureHeader(output, methodSignature);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write(' ');
WriteParent(output, module, metadata, memberReference.Parent, genericContext, syntax);
output.Write("::");
output.Write(DisassemblerHelpers.Escape(memberName));
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
WriteTypeParameterList(output, syntax, substitution);
WriteParameterList(output, methodSignature);
break;
}
break;
@ -320,22 +254,9 @@ namespace ICSharpCode.Decompiler.IL @@ -320,22 +254,9 @@ namespace ICSharpCode.Decompiler.IL
switch (standaloneSig.GetKind()) {
case StandaloneSignatureKind.Method:
methodSignature = standaloneSig.DecodeMethodSignature(new DisassemblerSignatureProvider(module, output), genericContext);
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
if (methodSignature.Header.CallingConvention == SignatureCallingConvention.VarArgs) {
output.Write("vararg ");
}
WriteSignatureHeader(output, methodSignature);
methodSignature.ReturnType(ILNameSyntax.SignatureNoNamedTypeParameters);
output.Write('(');
for (int i = 0; i < methodSignature.ParameterTypes.Length; i++) {
if (i > 0)
output.Write(", ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(')');
WriteParameterList(output, methodSignature);
break;
case StandaloneSignatureKind.LocalVariables:
default:
@ -349,6 +270,56 @@ namespace ICSharpCode.Decompiler.IL @@ -349,6 +270,56 @@ namespace ICSharpCode.Decompiler.IL
}
}
static void WriteTypeParameterList(ITextOutput output, ILNameSyntax syntax, System.Collections.Immutable.ImmutableArray<Action<ILNameSyntax>> substitution)
{
output.Write('<');
for (int i = 0; i < substitution.Length; i++) {
if (i > 0)
output.Write(", ");
substitution[i](syntax);
}
output.Write('>');
}
static void WriteParameterList(ITextOutput output, MethodSignature<Action<ILNameSyntax>> methodSignature)
{
output.Write("(");
for (int i = 0; i < methodSignature.ParameterTypes.Length; ++i) {
if (i > 0)
output.Write(", ");
if (i == methodSignature.RequiredParameterCount)
output.Write("..., ");
methodSignature.ParameterTypes[i](ILNameSyntax.SignatureNoNamedTypeParameters);
}
output.Write(")");
}
static void WriteSignatureHeader(ITextOutput output, MethodSignature<Action<ILNameSyntax>> methodSignature)
{
if (methodSignature.Header.HasExplicitThis) {
output.Write("instance explicit ");
} else if (methodSignature.Header.IsInstance) {
output.Write("instance ");
}
switch (methodSignature.Header.CallingConvention) {
case SignatureCallingConvention.CDecl:
output.Write("unmanaged cdecl ");
break;
case SignatureCallingConvention.StdCall:
output.Write("unmanaged stdcall ");
break;
case SignatureCallingConvention.ThisCall:
output.Write("unmanaged thiscall ");
break;
case SignatureCallingConvention.FastCall:
output.Write("unmanaged fastcall ");
break;
case SignatureCallingConvention.VarArgs:
output.Write("vararg ");
break;
}
}
static void WriteParent(ITextOutput output, PEFile module, MetadataReader metadata, EntityHandle parentHandle, Metadata.GenericContext genericContext, ILNameSyntax syntax)
{
switch (parentHandle.Kind) {

Loading…
Cancel
Save