diff --git a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs index 43837b8ae..612b86caf 100644 --- a/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/MethodBodyDisassembler.cs @@ -46,6 +46,11 @@ namespace ICSharpCode.Decompiler.Disassembler /// public bool ShowSequencePoints { get; set; } + /// + /// Show metadata tokens for instructions with token operands. + /// + public bool ShowMetadataTokens { get; set; } + IList sequencePoints; int nextSequencePointIndex; @@ -107,7 +112,12 @@ namespace ICSharpCode.Decompiler.Disassembler void DisassembleLocalsBlock(MethodBodyBlock body) { - if (body.LocalSignature.IsNil) return; + if (body.LocalSignature.IsNil) + return; + output.Write(".locals"); + WriteMetadataToken(body.LocalSignature, spaceBefore: true); + if (body.LocalVariablesInitialized) + output.Write(" init"); var blob = metadata.GetStandaloneSignature(body.LocalSignature); if (blob.GetKind() != StandaloneSignatureKind.LocalVariables) return; @@ -118,24 +128,20 @@ namespace ICSharpCode.Decompiler.Disassembler if (reader.ReadCompressedInteger() == 0) return; var signature = blob.DecodeLocalSignature(signatureDecoder, genericContext); - if (!signature.IsEmpty) { - output.Write(".locals "); - if (body.LocalVariablesInitialized) - output.Write("init "); - output.WriteLine("("); - output.Indent(); - int index = 0; - foreach (var v in signature) { - output.WriteDefinition("[" + index + "] ", v); - v(ILNameSyntax.TypeName); - if (index + 1 < signature.Length) - output.Write(','); - output.WriteLine(); - index++; - } - output.Unindent(); - output.WriteLine(")"); + output.Write(' '); + output.WriteLine("("); + output.Indent(); + int index = 0; + foreach (var v in signature) { + output.WriteDefinition("[" + index + "] ", v); + v(ILNameSyntax.TypeName); + if (index + 1 < signature.Length) + output.Write(','); + output.WriteLine(); + index++; } + output.Unindent(); + output.WriteLine(")"); } internal void WriteExceptionHandlers(PEFile module, MethodDefinitionHandle handle, MethodBodyBlock body) @@ -305,6 +311,7 @@ namespace ICSharpCode.Decompiler.Disassembler output.Write(' '); var handle = MetadataTokens.EntityHandle(blob.ReadInt32()); handle.WriteTo(module, output, genericContext); + WriteMetadataToken(handle, spaceBefore: true); break; case OperandType.Tok: output.Write(' '); @@ -325,6 +332,7 @@ namespace ICSharpCode.Decompiler.Disassembler break; } handle.WriteTo(module, output, genericContext); + WriteMetadataToken(handle, spaceBefore: true); break; case OperandType.ShortI: output.Write(' '); @@ -347,9 +355,10 @@ namespace ICSharpCode.Decompiler.Disassembler DisassemblerHelpers.WriteOperand(output, blob.ReadDouble()); break; case OperandType.String: - var userString = metadata.GetUserString(MetadataTokens.UserStringHandle(blob.ReadInt32())); + var userString = MetadataTokens.UserStringHandle(blob.ReadInt32()); output.Write(' '); - DisassemblerHelpers.WriteOperand(output, userString); + DisassemblerHelpers.WriteOperand(output, metadata.GetUserString(userString)); + WriteMetadataToken(userString, spaceBefore: true); break; case OperandType.Switch: int[] targets = ILParser.DecodeSwitchTargets(ref blob); @@ -385,5 +394,15 @@ namespace ICSharpCode.Decompiler.Disassembler } output.WriteLine(); } + + private void WriteMetadataToken(Handle handle, bool spaceBefore) + { + if (ShowMetadataTokens) { + if (spaceBefore) { + output.Write(' '); + } + output.Write("/* {0:X8} */", MetadataTokens.GetToken(handle)); + } + } } } diff --git a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs index d735e4e3c..397f31fdb 100644 --- a/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs +++ b/ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs @@ -50,6 +50,11 @@ namespace ICSharpCode.Decompiler.Disassembler set => methodBodyDisassembler.ShowSequencePoints = value; } + public bool ShowMetadataTokens { + get => methodBodyDisassembler.ShowMetadataTokens; + set => methodBodyDisassembler.ShowMetadataTokens = value; + } + public bool ExpandMemberDefinitions { get; set; } = false; public ReflectionDisassembler(ITextOutput output, CancellationToken cancellationToken) @@ -139,6 +144,7 @@ namespace ICSharpCode.Decompiler.Disassembler void DisassembleMethodHeaderInternal(PEFile module, MethodDefinitionHandle handle, MetadataReader metadata, GenericContext genericContext) { + WriteMetadataToken(handle, spaceAfter:true); var methodDefinition = metadata.GetMethodDefinition(handle); // .method public hidebysig specialname // instance default class [mscorlib]System.IO.TextWriter get_BaseWriter () cil managed @@ -256,6 +262,16 @@ namespace ICSharpCode.Decompiler.Disassembler output.Unindent(); } + private void WriteMetadataToken(Handle handle, bool spaceAfter) + { + if (ShowMetadataTokens) { + output.Write("/* {0:X8} */", MetadataTokens.GetToken(handle)); + if (spaceAfter) { + output.Write(' '); + } + } + } + void DisassembleMethodBlock(PEFile module, MethodDefinitionHandle handle, MetadataReader metadata, GenericContext genericContext) { var methodDefinition = metadata.GetMethodDefinition(handle); diff --git a/ILSpy/Languages/ILLanguage.cs b/ILSpy/Languages/ILLanguage.cs index 887f2a415..aa6d52864 100644 --- a/ILSpy/Languages/ILLanguage.cs +++ b/ILSpy/Languages/ILLanguage.cs @@ -54,6 +54,7 @@ namespace ICSharpCode.ILSpy return new ReflectionDisassembler(output, options.CancellationToken) { DetectControlStructure = detectControlStructure, ShowSequencePoints = options.DecompilerSettings.ShowDebugInfo, + ShowMetadataTokens = Options.DisplaySettingsPanel.CurrentDisplaySettings.ShowMetadataTokens, ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions }; } diff --git a/ILSpy/TextView/ILAsm-Mode.xshd b/ILSpy/TextView/ILAsm-Mode.xshd index 76fbc1afa..e334aab36 100644 --- a/ILSpy/TextView/ILAsm-Mode.xshd +++ b/ILSpy/TextView/ILAsm-Mode.xshd @@ -500,6 +500,10 @@ // + + /\* + \*/ + " "