mirror of
https://github.com/danbulant/Cosmos
synced 2026-05-20 21:08:51 +00:00
301 lines
14 KiB
C#
301 lines
14 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Xml;
|
|
using EcmaCil.IL;
|
|
|
|
namespace EcmaCil
|
|
{
|
|
public class Dump
|
|
{
|
|
private static void DumpType(TypeMeta item, XmlWriter output)
|
|
{
|
|
var xArrayType = item as ArrayTypeMeta;
|
|
if (xArrayType != null)
|
|
{
|
|
DumpArrayType(xArrayType, output);
|
|
return;
|
|
}
|
|
var xPointerType = item as PointerTypeMeta;
|
|
if (xPointerType != null)
|
|
{
|
|
DumpPointerType(xPointerType, output);
|
|
return;
|
|
}
|
|
if (item.GetType() == typeof(TypeMeta))
|
|
{
|
|
DumpTypeMeta(item, output);
|
|
return;
|
|
}
|
|
throw new NotImplementedException("Type '" + item.GetType().FullName + "' not implemented");
|
|
}
|
|
|
|
private static void DumpPointerType(PointerTypeMeta xPointerType, XmlWriter output)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private static void DumpTypeMeta(TypeMeta item, XmlWriter output)
|
|
{
|
|
output.WriteStartElement("TypeMeta");
|
|
{
|
|
#if DEBUG
|
|
output.WriteAttributeString("MetaId", (string)item.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
//output.WriteAttributeString("FullName", type.FullName);
|
|
//output.WriteAttributeString("BaseType", (type.BaseType != null ? "#" + type.BaseType.MetaId : ""));
|
|
#if DEBUG
|
|
if (item.BaseType != null)
|
|
{
|
|
output.WriteAttributeString("BaseType", (string)item.BaseType.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
}
|
|
if (item.Descendants.Count > 0)
|
|
{
|
|
output.WriteStartElement("Descendants");
|
|
{
|
|
foreach (var xDescendant in item.Descendants)
|
|
{
|
|
output.WriteStartElement("Descendant");
|
|
{
|
|
output.WriteAttributeString("Type", (string)xDescendant.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
}
|
|
output.WriteEndElement(); // Descendant
|
|
}
|
|
}
|
|
output.WriteEndElement(); // descendants
|
|
}
|
|
|
|
#else
|
|
if (item.BaseType != null)
|
|
{
|
|
output.WriteAttributeString("HasBaseType", "true");
|
|
}
|
|
#endif
|
|
output.WriteStartElement("Methods");
|
|
{
|
|
foreach (var xMethod in item.Methods)
|
|
{
|
|
DumpMethod(xMethod, output);
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
|
|
private static void DumpArrayType(ArrayTypeMeta aArrayType, XmlWriter output)
|
|
{
|
|
output.WriteStartElement("Array");
|
|
{
|
|
output.WriteAttributeString("Dimensions", aArrayType.Dimensions.ToString());
|
|
#if DEBUG
|
|
output.WriteAttributeString("ElementType", (string)aArrayType.ElementType.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
|
|
private static void DumpMethod(MethodMeta method, XmlWriter output)
|
|
{
|
|
output.WriteStartElement("Method");
|
|
{
|
|
#if DEBUG
|
|
output.WriteAttributeString("MetaId", (string)method.Data[DataIds.DebugMetaId]);
|
|
#endif
|
|
//output.WriteAttributeString("FullName", method.Name);
|
|
output.WriteAttributeString("IsStatic", method.IsStatic.ToString());
|
|
output.WriteAttributeString("IsVirtual", method.IsVirtual.ToString());
|
|
output.WriteAttributeString("StartsNewVirtualTree", method.StartsNewVirtualTree.ToString());
|
|
#if DEBUG
|
|
if (method.Overrides!=null)
|
|
{
|
|
output.WriteAttributeString("Overrides", (string)method.Overrides.Data[DataIds.DebugMetaId]);
|
|
}
|
|
if (method.ReturnType != null)
|
|
{
|
|
output.WriteAttributeString("ReturnType", (string)method.ReturnType.Data[DataIds.DebugMetaId]);
|
|
}
|
|
#endif
|
|
output.WriteStartElement("Parameters");
|
|
{
|
|
foreach (var xParam in method.Parameters)
|
|
{
|
|
DumpParameter(xParam, output);
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
if (method.Body != null)
|
|
{
|
|
output.WriteStartElement("Body");
|
|
{
|
|
#region Locals
|
|
output.WriteAttributeString("InitLocals", method.Body.InitLocals.ToString());
|
|
|
|
output.WriteStartElement("Locals");
|
|
{
|
|
for (int i = 0; i < method.Body.LocalVariables.Length; i++)
|
|
{
|
|
output.WriteStartElement("Local");
|
|
{
|
|
output.WriteAttributeString("Index", i.ToString());
|
|
#if DEBUG
|
|
output.WriteAttributeString("Type", (string)method.Body.LocalVariables[i].Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
//output.WriteAttributeString("IsPinned", method.Body.LocalVariables[i].IsPinned.ToString());
|
|
//output.WriteAttributeString("LocalType", "#" + method.Body.LocalVariables[i].LocalType.MetaId);
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
#endregion
|
|
#region ExceptionHandlingClauses
|
|
output.WriteStartElement("ExceptionHandlingClauses");
|
|
{
|
|
if (method.Body.ExceptionHandlingClauses != null)
|
|
{
|
|
foreach (var xClause in method.Body.ExceptionHandlingClauses)
|
|
{
|
|
output.WriteStartElement("Clause");
|
|
{
|
|
output.WriteAttributeString("Flags", xClause.Flags.ToString());
|
|
output.WriteAttributeString("HandlerStart", xClause.HandlerStart.ToString());
|
|
output.WriteAttributeString("HandlerEnd", xClause.HandlerEnd.ToString());
|
|
output.WriteAttributeString("TryStart", xClause.TryStart.ToString());
|
|
output.WriteAttributeString("TryEnd", xClause.TryEnd.ToString());
|
|
output.WriteAttributeString("FilterStart", xClause.FilterStart.ToString());
|
|
if (xClause.CatchType != null)
|
|
{
|
|
// output.WriteAttributeString("CatchType", "#" + xClause.CatchType.MetaId);
|
|
output.WriteAttributeString("HasCatchType", "true");
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
#endregion
|
|
#region instructions
|
|
output.WriteStartElement("Instructions");
|
|
{
|
|
for (int i = 0; i < method.Body.Instructions.Length; i++)
|
|
{
|
|
var xInstruction = method.Body.Instructions[i];
|
|
output.WriteStartElement("Instruction");
|
|
{
|
|
output.WriteAttributeString("Index", i.ToString());
|
|
output.WriteAttributeString("Kind", xInstruction.InstructionKind.ToString());
|
|
switch (xInstruction.GetType().Name)
|
|
{
|
|
case "InstructionNone":
|
|
break;
|
|
case "InstructionInt32":
|
|
var xInstr32 = (InstructionInt32)xInstruction;
|
|
output.WriteAttributeString("Value", xInstr32.Value.ToString());
|
|
break;
|
|
case "InstructionLocal":
|
|
var xInstrLocal = (InstructionLocal)xInstruction;
|
|
output.WriteAttributeString("LocalIndex", Array.IndexOf<LocalVariableMeta>(method.Body.LocalVariables, xInstrLocal.LocalVariable).ToString());
|
|
break;
|
|
case "InstructionMethod":
|
|
var xInstrMethod = (InstructionMethod)xInstruction;
|
|
#if DEBUG
|
|
output.WriteAttributeString("Method", (string)xInstrMethod.Value.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
//output.WriteAttributeString("Method", "#" + xInstrMethod.Value.MetaId);
|
|
break;
|
|
case "InstructionArgument":
|
|
var xInstrArg = (InstructionArgument)xInstruction;
|
|
#if DEBUG
|
|
output.WriteAttributeString("Argument", (string)xInstrArg.Argument.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
break;
|
|
case "InstructionBranch":
|
|
var xInstrBranch = (InstructionBranch)xInstruction;
|
|
output.WriteAttributeString("TargetIdx", xInstrBranch.Target.InstructionIndex.ToString());
|
|
break;
|
|
case "InstructionType":
|
|
var xInstrType = (InstructionType)xInstruction;
|
|
//output.WriteAttributeString("Type", xInstrType.Type.MetaId);
|
|
break;
|
|
case "InstructionField":
|
|
var xInstrField = (InstructionField)xInstruction;
|
|
//output.WriteAttributeString("Field", xInstrField.Field.Name);
|
|
break;
|
|
case "InstructionString":
|
|
var xInstrString = (InstructionString)xInstruction;
|
|
output.WriteAttributeString("LiteralString", xInstrString.LiteralString);
|
|
break;
|
|
case "InstructionSwitch":
|
|
break;
|
|
case "InstructionToken":
|
|
break;
|
|
case "InstructionSingle":
|
|
var xInstrSingle = (InstructionSingle)xInstruction;
|
|
output.WriteAttributeString("Value", xInstrSingle.Value.ToString());
|
|
break;
|
|
case "InstructionDouble":
|
|
var xInstrDouble = (InstructionDouble)xInstruction;
|
|
output.WriteAttributeString("Value", xInstrDouble.Value.ToString());
|
|
break;
|
|
case "InstructionInt64":
|
|
var xInstrInt64 = (InstructionInt64)xInstruction;
|
|
output.WriteAttributeString("Value", xInstrInt64.Value.ToString());
|
|
break;
|
|
default:
|
|
throw new NotImplementedException("Instruction kind not implemented: " + xInstruction.GetType().Name);
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
#endregion
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
|
|
private static void DumpParameter(MethodParameterMeta param, XmlWriter output)
|
|
{
|
|
output.WriteStartElement("Parameter");
|
|
{
|
|
if (param == null)
|
|
{
|
|
Console.Write("");
|
|
}
|
|
output.WriteAttributeString("IsByRef", param.IsByRef.ToString());
|
|
#if DEBUG
|
|
output.WriteAttributeString("MetaId", (string)param.Data[EcmaCil.DataIds.DebugMetaId]);
|
|
#endif
|
|
//output.WriteAttributeString("Name", param.Name);
|
|
//output.WriteAttributeString("IsPointer", param.IsPointer.ToString());
|
|
//output.WriteAttributeString("ParameterType", "#" + param.PropertyType.MetaId);
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
|
|
public static void DumpTypes(IEnumerable<TypeMeta> types, XmlWriter output)
|
|
{
|
|
output.WriteStartDocument();
|
|
{
|
|
output.WriteStartElement("Types");
|
|
{
|
|
foreach (var xType in types)
|
|
{
|
|
DumpType(xType, output);
|
|
}
|
|
}
|
|
output.WriteEndElement();
|
|
}
|
|
output.WriteEndDocument();
|
|
}
|
|
|
|
#region instructions dumping
|
|
#endregion
|
|
}
|
|
}
|