mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] Class method exports
This commit is contained in:
+1
-1
Submodule libs/MicrosoftIris updated: 13d2fc640b...e79bb7d755
@@ -18,6 +18,17 @@ namespace Microsoft.Iris.DecompXml;
|
|||||||
partial class Decompiler
|
partial class Decompiler
|
||||||
{
|
{
|
||||||
private SyntaxTree DecompileScript(uint startOffset, MarkupTypeSchema export)
|
private SyntaxTree DecompileScript(uint startOffset, MarkupTypeSchema export)
|
||||||
|
{
|
||||||
|
var statements = DecompileMethod(startOffset, export);
|
||||||
|
|
||||||
|
return SyntaxTree(
|
||||||
|
CompilationUnit().WithMembers(
|
||||||
|
[..statements.Select(GlobalStatement)]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<StatementSyntax> DecompileMethod(uint startOffset, MarkupTypeSchema export)
|
||||||
{
|
{
|
||||||
var methodBody = _context.GetMethodBody(startOffset).ToArray();
|
var methodBody = _context.GetMethodBody(startOffset).ToArray();
|
||||||
|
|
||||||
@@ -164,9 +175,23 @@ partial class Decompiler
|
|||||||
blockStack.Push(ifBlock);
|
blockStack.Push(ifBlock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpCode.Jump:
|
||||||
|
var jumpOffset = (uint)instruction.Operands.First().Value;
|
||||||
|
var statementsJumpedTo = DecompileMethod(jumpOffset, export);
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
blockStack.Peek().Statements.Add(
|
||||||
|
Block(List([..statementsJumpedTo]))
|
||||||
|
.WithTrailingTrivia(EndOfLine(Environment.NewLine), Comment($"// TODO: {instruction}"))
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
|
||||||
case not OpCode.ReturnVoid:
|
case not OpCode.ReturnVoid:
|
||||||
if (!TryDecompileExpression(instruction, stack, blockStack))
|
if (!TryDecompileExpression(instruction, stack, blockStack))
|
||||||
throw new NotImplementedException();
|
{
|
||||||
|
var unsupportedComment = Comment($"// Unsupported instruction: {instruction}");
|
||||||
|
blockStack.Peek().Statements.Add(EmptyStatement().WithLeadingTrivia(unsupportedComment));
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,13 +207,22 @@ partial class Decompiler
|
|||||||
throw new InvalidOperationException($"Failed to decompile script for {export.Name}, no top-level code blocks");
|
throw new InvalidOperationException($"Failed to decompile script for {export.Name}, no top-level code blocks");
|
||||||
|
|
||||||
// Unwrap top-most block to avoid extra curly braces around entire script
|
// Unwrap top-most block to avoid extra curly braces around entire script
|
||||||
var topBlock = blockStack.Pop();
|
return blockStack.Pop().Statements;
|
||||||
|
}
|
||||||
|
|
||||||
return SyntaxTree(
|
private MethodDeclarationSyntax DecompileMethodDeclaration(MarkupMethodSchema method, MarkupTypeSchema export)
|
||||||
CompilationUnit().WithMembers(
|
{
|
||||||
[..topBlock.Statements.Select(GlobalStatement)]
|
var targetType = export.ResolveScriptId(method.CodeOffset, out var offset);
|
||||||
)
|
var methodBody = DecompileMethod(offset, export);
|
||||||
);
|
|
||||||
|
var parameters = method.ParameterTypes
|
||||||
|
.Zip(method.ParameterNames, (t, n) => Parameter(Identifier(n)).WithType(IrisExpression.ToSyntax(t, _context)));
|
||||||
|
|
||||||
|
return MethodDeclaration(
|
||||||
|
IrisExpression.ToSyntax(method.ReturnType, _context),
|
||||||
|
method.Name)
|
||||||
|
.WithParameterList(ParameterList([..parameters]))
|
||||||
|
.WithBody(Block(methodBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatInlineExpression(ExpressionSyntax expr, CancellationToken token = default)
|
public static string FormatInlineExpression(ExpressionSyntax expr, CancellationToken token = default)
|
||||||
@@ -321,6 +355,16 @@ partial class Decompiler
|
|||||||
DecompileOperation(instruction, stack);
|
DecompileOperation(instruction, stack);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpCode.IsCheck:
|
||||||
|
var typeToCheckFor = _context.GetImportedType(instruction.Operands.First());
|
||||||
|
var objToCheck = stack.Pop();
|
||||||
|
|
||||||
|
stack.Push(IsPatternExpression(
|
||||||
|
IrisExpression.ToSyntax(objToCheck, _context),
|
||||||
|
TypePattern(IrisExpression.ToSyntax(typeToCheckFor, _context))
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,6 +79,26 @@ public partial class Decompiler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (export.FinalEvaluateOffsets is { Length: > 0 })
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (export.Methods is { Length: > 0 })
|
||||||
|
{
|
||||||
|
var xScripts = GetOrCreateElement(xExport, _nsUix + "Scripts");
|
||||||
|
|
||||||
|
foreach (var method in export.Methods.OfType<MarkupMethodSchema>())
|
||||||
|
{
|
||||||
|
var methodSyntax = DecompileMethodDeclaration(method, export);
|
||||||
|
var scriptText = FormatScript(methodSyntax.SyntaxTree);
|
||||||
|
|
||||||
|
XElement xScript = new(_nsUix + "Script", scriptText);
|
||||||
|
|
||||||
|
xScripts.Add(xScript);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (export.RefreshGroupOffsets is { Length: > 0 })
|
if (export.RefreshGroupOffsets is { Length: > 0 })
|
||||||
{
|
{
|
||||||
var xScripts = GetOrCreateElement(xExport, _nsUix + "Scripts");
|
var xScripts = GetOrCreateElement(xExport, _nsUix + "Scripts");
|
||||||
@@ -287,12 +307,7 @@ public partial class Decompiler
|
|||||||
if (instruction.OpCode is OpCode.DestructiveListen)
|
if (instruction.OpCode is OpCode.DestructiveListen)
|
||||||
refreshOffset = (uint)instruction.Operands.ElementAt(4).Value;
|
refreshOffset = (uint)instruction.Operands.ElementAt(4).Value;
|
||||||
|
|
||||||
MarkupTypeSchema markupTypeSchema = initType;
|
var markupTypeSchema = initType.ResolveScriptId(scriptId, out var scriptOffset);
|
||||||
uint num = scriptId >> 27;
|
|
||||||
while (num != markupTypeSchema.TypeDepth)
|
|
||||||
markupTypeSchema = markupTypeSchema.MarkupTypeBase;
|
|
||||||
|
|
||||||
var scriptOffset = scriptId & 0x07FFFFFFU;
|
|
||||||
|
|
||||||
string watch = null;
|
string watch = null;
|
||||||
InstructionObjectSource watchSource = InstructionObjectSource.Dynamic;
|
InstructionObjectSource watchSource = InstructionObjectSource.Dynamic;
|
||||||
|
|||||||
@@ -3,13 +3,15 @@ using Microsoft.CodeAnalysis.CSharp.Syntax;
|
|||||||
using Microsoft.Iris.Asm;
|
using Microsoft.Iris.Asm;
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
|
||||||
|
|
||||||
namespace Microsoft.Iris.DecompXml.Mock;
|
namespace Microsoft.Iris.DecompXml.Mock;
|
||||||
|
|
||||||
internal static class IrisExpression
|
internal static class IrisExpression
|
||||||
{
|
{
|
||||||
|
private static Dictionary<ulong, SyntaxKind> _predefinedTypeMap = null;
|
||||||
|
|
||||||
public static ExpressionSyntax ToSyntax(object obj, DecompileContext context)
|
public static ExpressionSyntax ToSyntax(object obj, DecompileContext context)
|
||||||
{
|
{
|
||||||
return obj switch
|
return obj switch
|
||||||
@@ -31,8 +33,13 @@ internal static class IrisExpression
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IdentifierNameSyntax ToSyntax(TypeSchema type, DecompileContext context) =>
|
public static TypeSyntax ToSyntax(TypeSchema type, DecompileContext context)
|
||||||
IdentifierName(context.GetQualifiedName(type).ToString());
|
{
|
||||||
|
if (TryMapPredefinedType(type, out var kind))
|
||||||
|
return PredefinedType(Token(kind));
|
||||||
|
|
||||||
|
return IdentifierName(context.GetQualifiedName(type).ToString());
|
||||||
|
}
|
||||||
|
|
||||||
public static IdentifierNameSyntax ToSyntax(SymbolReference symbolRef) =>
|
public static IdentifierNameSyntax ToSyntax(SymbolReference symbolRef) =>
|
||||||
IdentifierName(symbolRef.Symbol);
|
IdentifierName(symbolRef.Symbol);
|
||||||
@@ -50,4 +57,18 @@ internal static class IrisExpression
|
|||||||
_ => ToSyntax(obj, context),
|
_ => ToSyntax(obj, context),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool TryMapPredefinedType(TypeSchema type, out SyntaxKind kind)
|
||||||
|
{
|
||||||
|
_predefinedTypeMap ??= new()
|
||||||
|
{
|
||||||
|
[UIXTypes.MapIDToType(UIXTypeID.Void).UniqueId] = SyntaxKind.VoidKeyword,
|
||||||
|
[UIXTypes.MapIDToType(UIXTypeID.Int32).UniqueId] = SyntaxKind.IntKeyword,
|
||||||
|
[UIXTypes.MapIDToType(UIXTypeID.Int64).UniqueId] = SyntaxKind.LongKeyword,
|
||||||
|
[UIXTypes.MapIDToType(UIXTypeID.String).UniqueId] = SyntaxKind.StringKeyword,
|
||||||
|
[UIXTypes.MapIDToType(UIXTypeID.Boolean).UniqueId] = SyntaxKind.BoolKeyword,
|
||||||
|
};
|
||||||
|
|
||||||
|
return _predefinedTypeMap.TryGetValue(type.UniqueId, out kind);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,5 +15,11 @@
|
|||||||
<schema:LibraryPlaylistContentQuery Enabled="false" Name="Query" />
|
<schema:LibraryPlaylistContentQuery Enabled="false" Name="Query" />
|
||||||
<Boolean Boolean="false" Name="ContentNotInLibrary" />
|
<Boolean Boolean="false" Name="ContentNotInLibrary" />
|
||||||
</Locals>
|
</Locals>
|
||||||
|
<Scripts>
|
||||||
|
<Script></Script>
|
||||||
|
<Script></Script>
|
||||||
|
<Script></Script>
|
||||||
|
<Script></Script>
|
||||||
|
</Scripts>
|
||||||
</Class>
|
</Class>
|
||||||
</UIX>
|
</UIX>
|
||||||
+41
-1
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-16"?>
|
<?xml version="1.0" encoding="utf-16"?>
|
||||||
<UIX xmlns="http://schemas.microsoft.com/2007/uix" xmlns:iris="assembly://UIX/Microsoft.Iris" xmlns:style="res://UIXControls!Style.uix" xmlns:zuneUI="assembly://ZuneShell/ZuneUI" xmlns:imageStyle="res://UIXControls!ImageStyle.uix" xmlns:styles="res://ZuneShellResources!Styles.uix" xmlns:styles1="res://UIXControls!Styles.uix" xmlns:generic="assembly://System.Private.CoreLib/System.Collections.Generic">
|
<UIX xmlns="http://schemas.microsoft.com/2007/uix" xmlns:iris="assembly://UIX/Microsoft.Iris" xmlns:style="res://UIXControls!Style.uix" xmlns:zuneUI="assembly://ZuneShell/ZuneUI" xmlns:imageStyle="res://UIXControls!ImageStyle.uix" xmlns:styles="res://ZuneShellResources!Styles.uix" xmlns:styles1="res://UIXControls!Styles.uix" xmlns:generic="assembly://System.Private.CoreLib/System.Collections.Generic" xmlns:configuration="assembly://ZuneDBApi/Microsoft.Zune.Configuration">
|
||||||
<Class Name="Styles" Shared="true">
|
<Class Name="Styles" Shared="true">
|
||||||
<Properties>
|
<Properties>
|
||||||
<zuneUI:FontLoader Resource="ZuneShellResources.dll" Name="FontLoader">
|
<zuneUI:FontLoader Resource="ZuneShellResources.dll" Name="FontLoader">
|
||||||
@@ -818,6 +818,46 @@
|
|||||||
<Image Source="res://ZuneShellResources!WindowsPhoneEnergyBar.png" Name="WindowsPhoneEnergyBar" />
|
<Image Source="res://ZuneShellResources!WindowsPhoneEnergyBar.png" Name="WindowsPhoneEnergyBar" />
|
||||||
<Image Source="res://ZuneShellResources!WindowsPhoneAppList.png" Name="WindowsPhoneAppList" />
|
<Image Source="res://ZuneShellResources!WindowsPhoneAppList.png" Name="WindowsPhoneAppList" />
|
||||||
</Properties>
|
</Properties>
|
||||||
|
<Scripts>
|
||||||
|
<Script>void UpdateDefaultFrameBackground()
|
||||||
|
{
|
||||||
|
DefaultBackgroundImage = new Image(this.GetDefaultFrameBackground());
|
||||||
|
}</Script>
|
||||||
|
<Script>string GetDefaultFrameBackground()
|
||||||
|
{
|
||||||
|
source = null;
|
||||||
|
if (!zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:QuickplayPage)
|
||||||
|
{
|
||||||
|
if (zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage && string.IsNullOrEmpty(zuneUI:Shell.SessionStartupPath))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:QuickplayPage || zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage && string.IsNullOrEmpty(zuneUI:Shell.SessionStartupPath) && configuration:ClientConfiguration.Shell.StartupPage == zuneUI:Shell.MainFrame.Quickplay.DefaultUIPath)
|
||||||
|
{
|
||||||
|
if (zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:QuickplayPage || zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage && string.IsNullOrEmpty(zuneUI:Shell.SessionStartupPath) && configuration:ClientConfiguration.Shell.StartupPage == zuneUI:Shell.MainFrame.Quickplay.DefaultUIPath || zuneUI:ZuneShell.DefaultInstance.CurrentPage is zuneUI:StartupPage && zuneUI:Shell.SessionStartupPath == zuneUI:Shell.MainFrame.Quickplay.DefaultUIPath)
|
||||||
|
{
|
||||||
|
source = QuickplayFrameBackground.Value;
|
||||||
|
{
|
||||||
|
// Unsupported instruction: CSYM 63
|
||||||
|
;
|
||||||
|
} // TODO: JMP 170
|
||||||
|
}// Unsupported instruction: VTC 960
|
||||||
|
;
|
||||||
|
source = FrameBackgrounds.get_Item(DefaultBackgroundIndex).Value;
|
||||||
|
// Unsupported instruction: CSYM 63
|
||||||
|
;
|
||||||
|
}</Script>
|
||||||
|
</Scripts>
|
||||||
</Class>
|
</Class>
|
||||||
<Class Name="SharedStyles" Shared="true">
|
<Class Name="SharedStyles" Shared="true">
|
||||||
<Properties>
|
<Properties>
|
||||||
|
|||||||
+11238
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user