Skip to content

Commit 4df9a34

Browse files
authored
Improve assembly dump (#178)
***NO_CI***
1 parent b0f9059 commit 4df9a34

File tree

7 files changed

+249
-154
lines changed

7 files changed

+249
-154
lines changed

MetadataProcessor.Shared/Extensions/TypeReferenceExtensions.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
1-
//
2-
// Copyright (c) .NET Foundation and Contributors
3-
// See LICENSE file in the project root for full license information.
4-
//
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
53

6-
using Mono.Cecil;
74
using System.Collections.Generic;
85
using System.Linq;
96
using System.Text;
7+
using Mono.Cecil;
108

119
namespace nanoFramework.Tools.MetadataProcessor.Core.Extensions
1210
{
@@ -78,7 +76,9 @@ public static string TypeSignatureAsString(this TypeReference type)
7876

7977
if (type.MetadataType == MetadataType.Class)
8078
{
81-
StringBuilder classSig = new StringBuilder("CLASS [");
79+
StringBuilder classSig = new StringBuilder("CLASS ");
80+
classSig.Append(type.FullName);
81+
classSig.Append(" [");
8282
classSig.Append(type.MetadataToken.ToInt32().ToString("x8"));
8383
classSig.Append("]");
8484

@@ -87,7 +87,9 @@ public static string TypeSignatureAsString(this TypeReference type)
8787

8888
if (type.MetadataType == MetadataType.ValueType)
8989
{
90-
StringBuilder valueTypeSig = new StringBuilder("VALUETYPE [");
90+
StringBuilder valueTypeSig = new StringBuilder("VALUETYPE ");
91+
valueTypeSig.Append(type.FullName);
92+
valueTypeSig.Append(" [");
9193
valueTypeSig.Append(type.MetadataToken.ToInt32().ToString("x8"));
9294
valueTypeSig.Append("]");
9395

@@ -96,8 +98,9 @@ public static string TypeSignatureAsString(this TypeReference type)
9698

9799
if (type.IsArray)
98100
{
99-
StringBuilder arraySig = new StringBuilder("SZARRAY ");
101+
StringBuilder arraySig = new StringBuilder();
100102
arraySig.Append(type.GetElementType().TypeSignatureAsString());
103+
arraySig.Append("[]");
101104

102105
return arraySig.ToString();
103106
}

MetadataProcessor.Shared/nanoDumperGenerator.cs

Lines changed: 78 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,16 @@
1-
//
2-
// Copyright (c) .NET Foundation and Contributors
3-
// See LICENSE file in the project root for full license information.
4-
//
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
53

6-
using Mono.Cecil;
7-
using Mono.Cecil.Cil;
8-
using Mono.Collections.Generic;
9-
using Mustache;
10-
using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
114
using System;
125
using System.Collections.Generic;
136
using System.IO;
147
using System.Linq;
158
using System.Text;
9+
using Mono.Cecil;
10+
using Mono.Cecil.Cil;
11+
using Mono.Collections.Generic;
12+
using Mustache;
13+
using nanoFramework.Tools.MetadataProcessor.Core.Extensions;
1614

1715
namespace nanoFramework.Tools.MetadataProcessor.Core
1816
{
@@ -210,7 +208,7 @@ private void DumpUserStrings(DumpAllTable dumpTable)
210208

211209
private void DumpTypeDefinitions(DumpAllTable dumpTable)
212210
{
213-
foreach (var t in _tablesContext.TypeDefinitionTable.Items.OrderBy(tr => tr.MetadataToken.ToInt32()))
211+
foreach (TypeDefinition t in _tablesContext.TypeDefinitionTable.Items.OrderBy(tr => tr.MetadataToken.ToInt32()))
214212
{
215213
// fill type definition
216214
var typeDef = new TypeDef()
@@ -227,7 +225,7 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
227225
typeDef.Name = t.FullName;
228226
}
229227

230-
var typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(
228+
uint typeFlags = (uint)nanoTypeDefinitionTable.GetFlags(
231229
t,
232230
_tablesContext.MethodDefinitionTable);
233231

@@ -254,7 +252,7 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
254252
}
255253

256254
// list generic parameters
257-
foreach (var gp in t.GenericParameters)
255+
foreach (GenericParameter gp in t.GenericParameters)
258256
{
259257
var genericParam = new GenericParam()
260258
{
@@ -269,7 +267,7 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
269267
}
270268

271269
// list type fields
272-
foreach (var f in t.Fields)
270+
foreach (FieldDefinition f in t.Fields)
273271
{
274272
uint att = (uint)f.Attributes;
275273

@@ -286,7 +284,7 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
286284
}
287285

288286
// list type methods
289-
foreach (var m in t.Methods)
287+
foreach (MethodDefinition m in t.Methods)
290288
{
291289
var methodDef = new MethodDef()
292290
{
@@ -297,19 +295,19 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
297295
Signature = PrintSignatureForMethod(m)
298296
};
299297

300-
var methodFlags = nanoMethodDefinitionTable.GetFlags(m);
298+
uint methodFlags = nanoMethodDefinitionTable.GetFlags(m);
301299
methodDef.Flags = methodFlags.ToString("x8");
302300

303301
if (m.HasBody)
304302
{
305303
// locals
306304
if (m.Body.HasVariables)
307305
{
308-
methodDef.Locals = $"{m.Body.Variables.Count.ToString()}: {PrintSignatureForLocalVar(m.Body.Variables)}";
306+
methodDef.Locals = PrintSignatureForLocalVar(m.Body.Variables);
309307
}
310308

311309
// exceptions
312-
foreach (var eh in m.Body.ExceptionHandlers)
310+
foreach (Mono.Cecil.Cil.ExceptionHandler eh in m.Body.ExceptionHandlers)
313311
{
314312
var h = new ExceptionHandler();
315313

@@ -332,32 +330,66 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
332330
methodDef.ILCodeInstructionsCount = m.Body.Instructions.Count.ToString();
333331

334332
// IL code
335-
foreach (var instruction in m.Body.Instructions)
333+
foreach (Instruction instruction in m.Body.Instructions)
336334
{
337335
ILCode ilCode = new ILCode();
338336

339337
ilCode.IL += instruction.OpCode.Name.PadRight(12);
340338

341339
if (instruction.Operand != null)
342340
{
343-
if (instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineField ||
344-
instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineMethod ||
345-
instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineType ||
346-
instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineTok ||
347-
instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineSig)
341+
if (instruction.OpCode.OperandType == OperandType.InlineTok ||
342+
instruction.OpCode.OperandType == OperandType.InlineSig)
343+
{
344+
ilCode.IL += $"[{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
345+
}
346+
else if (instruction.OpCode.OperandType == OperandType.InlineField)
347+
{
348+
// output the field type name
349+
ilCode.IL += $"{((FieldReference)instruction.Operand).FieldType.FullName}";
350+
351+
// output the token
352+
ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
353+
}
354+
else if (instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineMethod)
355+
{
356+
// output the method name
357+
ilCode.IL += $"{((MethodReference)instruction.Operand).FullName}";
358+
359+
// output the token
360+
ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
361+
}
362+
else if (instruction.OpCode.OperandType == OperandType.InlineType)
348363
{
349-
ilCode.IL += $"[{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32().ToString("x8")}]";
364+
// Mono.Cecil.ArrayType
365+
if (instruction.Operand is ArrayType arrayType)
366+
{
367+
// output the type name
368+
ilCode.IL += $"{arrayType.ElementType.FullName}[]";
369+
}
370+
else
371+
{
372+
// output the type name
373+
ilCode.IL += $"{((TypeReference)instruction.Operand).FullName}";
374+
}
375+
376+
// output the token
377+
ilCode.IL += $" [{((IMetadataTokenProvider)instruction.Operand).MetadataToken.ToInt32():x8}]";
350378
}
351-
else if (instruction.OpCode.OperandType == Mono.Cecil.Cil.OperandType.InlineString)
379+
else if (instruction.OpCode.OperandType == OperandType.InlineString)
352380
{
353381
// strings need a different processing
354382
// get string ID from table
355-
var stringReferenceId = _tablesContext.StringTable.GetOrCreateStringId((string)instruction.Operand, true);
383+
ushort stringReferenceId = _tablesContext.StringTable.GetOrCreateStringId((string)instruction.Operand, true);
356384

357385
// fake the metadata token from the ID
358-
var stringMetadataToken = new MetadataToken(TokenType.String, stringReferenceId);
386+
MetadataToken stringMetadataToken = new MetadataToken(TokenType.String, stringReferenceId);
387+
388+
// output the string
389+
ilCode.IL += $"\"{(string)instruction.Operand}\"";
359390

360-
ilCode.IL += $"[{stringMetadataToken.ToInt32().ToString("x8")}]";
391+
// ouput the metadata token
392+
ilCode.IL += $" [{stringMetadataToken.ToInt32():x8}]";
361393
}
362394

363395
}
@@ -370,7 +402,7 @@ private void DumpTypeDefinitions(DumpAllTable dumpTable)
370402
}
371403

372404
// list interface implementations
373-
foreach (var i in t.Interfaces)
405+
foreach (InterfaceImplementation i in t.Interfaces)
374406
{
375407
typeDef.InterfaceDefinitions.Add(
376408
new InterfaceDef()
@@ -446,11 +478,11 @@ private string PrintSignatureForMethod(MethodReference method)
446478
{
447479
var sig = new StringBuilder(method.ReturnType.TypeSignatureAsString());
448480

449-
sig.Append("( ");
481+
sig.Append('(');
450482

451-
foreach (var p in method.Parameters)
483+
foreach (ParameterDefinition param in method.Parameters)
452484
{
453-
sig.Append(p.ParameterType.TypeSignatureAsString());
485+
sig.Append(param.ParameterType.TypeSignatureAsString());
454486
sig.Append(", ");
455487
}
456488

@@ -461,37 +493,34 @@ private string PrintSignatureForMethod(MethodReference method)
461493
}
462494
else
463495
{
464-
sig.Append(" ");
496+
sig.Append(' ');
465497
}
466498

467-
sig.Append(" )");
499+
sig.Append(')');
468500

469501
return sig.ToString();
470502
}
471503

472-
473504
private string PrintSignatureForLocalVar(Collection<VariableDefinition> variables)
474505
{
506+
const string localIdentation = " ";
507+
475508
StringBuilder sig = new StringBuilder();
476-
sig.Append("{ ");
477509

478-
foreach (var l in variables)
479-
{
480-
sig.Append(l.VariableType.TypeSignatureAsString());
481-
sig.Append(", ");
482-
}
510+
sig.Append('(');
483511

484-
// remove trailing", "
485-
if (variables.Count > 0)
512+
for (int localIndex = 0; localIndex < variables.Count; localIndex++)
486513
{
487-
sig.Remove(sig.Length - 2, 2);
488-
}
489-
else
490-
{
491-
sig.Append(" ");
514+
sig.Append($"{(localIndex > 0 ? localIdentation : "")} [{localIndex}] ");
515+
sig.Append(variables[localIndex].VariableType.TypeSignatureAsString());
516+
517+
if (localIndex < variables.Count - 1)
518+
{
519+
sig.AppendLine(", ");
520+
}
492521
}
493522

494-
sig.Append(" }");
523+
sig.Append(" )");
495524

496525
return sig.ToString();
497526
}

0 commit comments

Comments
 (0)