XML debug symbols

This commit is contained in:
Joshua "Yoshi" Askharoun
2025-11-28 18:06:19 -06:00
parent 396d4f4015
commit 806d697e79
5 changed files with 79 additions and 23 deletions
-1
View File
@@ -62,7 +62,6 @@ internal class DecompileContext
DebugSymbols = new()
{
CompiledFileName = _loadResult.ErrorContextUri,
ScriptSymbols = [],
};
_instructions = ObjectSection.Decode(_loadResult.ObjectSection)
+2 -11
View File
@@ -622,10 +622,6 @@ partial class Decompiler
public string FormatSyntaxNode(SyntaxNode root, CancellationToken cancellationToken = default)
{
uint? scriptOffset = null;
ScriptDebugSymbols debugSymbols = new()
{
SourceMap = []
};
root = root.NormalizeWhitespace();
@@ -636,7 +632,7 @@ partial class Decompiler
var location = node.GetLocation();
debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End);
//debugSymbols.SourceMap[offset] = new(location.SourceSpan.Start, location.SourceSpan.End);
if (scriptOffset is null && node is CompilationUnitSyntax)
scriptOffset = offset;
@@ -646,12 +642,7 @@ partial class Decompiler
.SyntaxTree
.GetText(cancellationToken);
debugSymbols.SourceCode = sourceText.ToString();
if (scriptOffset is not null)
_context.DebugSymbols.ScriptSymbols[scriptOffset.Value] = debugSymbols;
return debugSymbols.SourceCode;
return sourceText.ToString();
}
private bool TryDecompileExpression(Instruction instruction, Stack<object> stack, ControlFlowAnalyzer cfa = null)
+54 -10
View File
@@ -143,7 +143,7 @@ public partial class Decompiler
return xDoc;
}
public string DecompileToSource()
public string DecompileToSource(bool generateDebugSymbols)
{
var xmlDoc = Decompile();
@@ -159,7 +159,47 @@ public partial class Decompiler
{
xmlDoc.WriteTo(writer);
}
return sb.ToString();
var xmlStr = sb.ToString();
if (generateDebugSymbols)
PopulateDebugSymbolsWithXml(xmlDoc, xmlStr);
return xmlStr;
}
public void PopulateDebugSymbolsWithXml(XDocument xmlDoc, string xmlStr)
{
// Reparse the file to get line info
var xmlDocWithLineInfo = XDocument.Parse(xmlStr, LoadOptions.SetLineInfo);
var lineInfoNodes = xmlDocWithLineInfo.DescendantNodes();
var offsetInfoNodes = xmlDoc.DescendantNodes();
foreach (var (liNode, oiNode) in lineInfoNodes.Zip(offsetInfoNodes, (l, o) => (l, o)))
{
var offsetInfo = oiNode.Annotation<UIBOffsetXmlAnnotation>();
if (offsetInfo is null)
continue;
if (liNode is not IXmlLineInfo lineInfo || !lineInfo.HasLineInfo())
continue;
var offset = offsetInfo.Offset;
var start = new SourcePosition(lineInfo.LineNumber, lineInfo.LinePosition);
var elementStr = oiNode.ToString();
var endLine = start.Line + elementStr.Count(c => c == '\n');
var endColumn = elementStr.Length;
var idxLastLine = elementStr.LastIndexOf('\n');
if (idxLastLine > 0)
endColumn -= idxLastLine;
var end = new SourcePosition(endLine, endColumn);
var span = new SourceSpan(start, end);
DebugSymbols.SourceMap.Xml[offset] = span;
}
}
public FileDebugSymbols DebugSymbols => _context.DebugSymbols;
@@ -189,7 +229,7 @@ public partial class Decompiler
case OpCode.ConstructObject:
var typeToCtor = _context.GetImportedType(instruction.Operands.ElementAt(0));
var xObj = new XElement(_context.GetXName(typeToCtor));
var xObj = new XElement(_context.GetXName(typeToCtor)).WithOffset(instruction);
stack.Push(new IrisObject(xObj, typeToCtor));
break;
@@ -213,7 +253,8 @@ public partial class Decompiler
var target = stack.Pop();
var xTarget = (XElement)ToXmlFriendlyObject(target);
PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType));
var xPropSetter = PropertyAssignOnXElement(xTarget, propertyToInit, IrisObject.Create(newPropValue, propertyToInit.PropertyType, _context, initType));
xPropSetter.SetOffset(instruction);
stack.Push(new IrisObject(xTarget, propertyToInit.Owner));
break;
@@ -231,10 +272,10 @@ public partial class Decompiler
var dictValueObj = IrisObject.Create(dictValue, dictValueType, _context, initType);
var targetDictPropertyIndex = (ushort)instruction.Operands.ElementAt(0).Value;
if (targetDictPropertyIndex is ushort.MaxValue)
PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key);
else
PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
var xKeyValue = targetDictPropertyIndex is ushort.MaxValue
? PropertyDictionaryAddOnXElement(targetInstance, dictValueObj, key)
: PropertyDictionaryAddOnXElement(targetInstance, _context.ImportTables.PropertyImports[targetDictPropertyIndex], dictValueObj, key);
xKeyValue.SetOffset(instruction);
break;
case OpCode.PropertyListAdd:
@@ -252,6 +293,7 @@ public partial class Decompiler
var targetInstance2 = (XElement)ToXmlFriendlyObject(stack.Peek());
XObject xListItem;
var targetListPropertyIndex = (ushort)instruction.Operands.First().Value;
if (targetListPropertyIndex != ushort.MaxValue)
{
@@ -264,12 +306,14 @@ public partial class Decompiler
valueToAddObj = valueToAddObj with { Type = valueToAddType };
}
PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
xListItem = PropertyListAddOnXElement(targetInstance2, targetListProperty, valueToAddObj);
}
else
{
PropertyListAddOnXElement(targetInstance2, valueToAddObj);
xListItem = PropertyListAddOnXElement(targetInstance2, valueToAddObj);
}
xListItem.SetOffset(instruction);
break;
case OpCode.InitializeInstance:
+22
View File
@@ -1,5 +1,6 @@
using Microsoft.CodeAnalysis;
using Microsoft.Iris.Asm.Models;
using System.Xml.Linq;
namespace Microsoft.Iris.DecompXml;
@@ -23,5 +24,26 @@ internal static class UIBOffsetAnnotation
}
public static uint GetOffset(SyntaxAnnotation offsetAnnotation) => uint.Parse(offsetAnnotation.Data);
public static void SetOffset(this XObject xObj, uint offset) => xObj.AddAnnotation(new UIBOffsetXmlAnnotation(offset));
public static void SetOffset(this XObject xObj, Instruction instruction) => xObj.SetOffset(instruction.Offset);
public static XObject WithOffset(this XObject xObj, Instruction instruction)
{
xObj.SetOffset(instruction.Offset);
return xObj;
}
public static XObject WithNewOffset(this XObject xObj, Instruction instruction)
{
if (xObj.GetOffset() is null)
xObj.SetOffset(instruction.Offset);
return xObj;
}
public static uint? GetOffset(this XObject xObj) => xObj.Annotation<UIBOffsetXmlAnnotation>()?.Offset;
}
internal record UIBOffsetXmlAnnotation(uint Offset);