mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] Importing shared data tables
This commit is contained in:
@@ -3,9 +3,9 @@
|
||||
"UIXC": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "decompile C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources_uixa -t C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources_uixa\\_DATATABLE.uixa",
|
||||
//"commandLineArgs": "decompile C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources\\_DATATABLE.UIB -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources_uixa",
|
||||
//"commandLineArgs": "compile C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources\\CreatePassport.uixa -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o C:\\Users\\jjask\\Documents\\Dump\\Zune",
|
||||
//"commandLineArgs": "compile C:\\Users\\jjask\\Documents\\Dump\\Zune\\_DATATABLE.uixa -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o C:\\Users\\jjask\\Documents\\Dump\\Zune",
|
||||
//"commandLineArgs": "decompile C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources\\_DATATABLE.UIB -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o C:\\Users\\jjask\\Documents\\Dump\\Zune\\ZuneShellResources_uixa",
|
||||
|
||||
//"commandLineArgs": "compile \"D:\\Documents\\REProj\\Zune\\UIXA\\ZuneShell.dll!_DataTable.uixa\" -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o D:\\Documents\\REProj\\Zune\\UIXA",
|
||||
//"commandLineArgs": "compile \"D:\\Documents\\REProj\\Zune\\UIXA\\ZuneShellResources.dll!_DataTable.uixa\" -A ZuneShell.dll -A UIXControls.dll -A ZuneDBApi.dll -o D:\\Documents\\REProj\\Zune\\UIXA",
|
||||
|
||||
@@ -16,7 +16,8 @@ internal class AsmMarkupLoader
|
||||
private readonly AsmMarkupLoadResult _loadResult;
|
||||
private LoadPass _currentValidationPass;
|
||||
private bool _usingSharedBinaryDataTable;
|
||||
private SourceMarkupImportTables _importTables;
|
||||
private AsmMarkupLoadResult _binaryDataTableLoadResult;
|
||||
private MarkupBinaryDataTable _binaryDataTable;
|
||||
private ObjectSection _objectSection;
|
||||
|
||||
private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
|
||||
@@ -70,16 +71,6 @@ internal class AsmMarkupLoader
|
||||
|
||||
var type = result.FindType(typeName);
|
||||
|
||||
//if (type is null)
|
||||
//{
|
||||
// foreach (var tryResult in _importedNamespaces.Values)
|
||||
// {
|
||||
// type = tryResult.FindType(typeName);
|
||||
// if (type is not null)
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
if (type is null)
|
||||
{
|
||||
ErrorManager.ReportError(qualifiedName.Line, qualifiedName.Column,
|
||||
@@ -105,11 +96,11 @@ internal class AsmMarkupLoader
|
||||
return;
|
||||
_currentValidationPass = currentPass;
|
||||
|
||||
if (_currentValidationPass == LoadPass.DeclareTypes)
|
||||
{
|
||||
if (_asmSource == null)
|
||||
return;
|
||||
if (_asmSource == null)
|
||||
return;
|
||||
|
||||
if (Program is null && !HasErrors)
|
||||
{
|
||||
var parseResult = Lexer.Program.TryParse(_asmSource);
|
||||
if (parseResult.WasSuccessful)
|
||||
{
|
||||
@@ -123,16 +114,49 @@ internal class AsmMarkupLoader
|
||||
return;
|
||||
}
|
||||
|
||||
if (_loadResult.BinaryDataTable != null)
|
||||
_usingSharedBinaryDataTable = Program.DataTableDirective is not null;
|
||||
if (_usingSharedBinaryDataTable)
|
||||
{
|
||||
_importTables = _loadResult.BinaryDataTable.SourceMarkupImportTables;
|
||||
_usingSharedBinaryDataTable = true;
|
||||
// Import the shared data table
|
||||
var dataTableUri = Program.DataTableDirective.Uri;
|
||||
var dataTableLoadResult = MarkupSystem.ResolveLoadResult(dataTableUri, _loadResult.IslandReferences);
|
||||
if (dataTableLoadResult is null)
|
||||
{
|
||||
ReportError($"Unable to load '{dataTableUri}' (shared data table)", Program.DataTableDirective);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dataTableLoadResult is not AsmMarkupLoadResult)
|
||||
{
|
||||
ReportError($"Shared data table at '{dataTableUri}' was not UIXA", Program.DataTableDirective);
|
||||
return;
|
||||
}
|
||||
|
||||
_binaryDataTableLoadResult = (AsmMarkupLoadResult)dataTableLoadResult;
|
||||
if (_binaryDataTableLoadResult != null)
|
||||
{
|
||||
_binaryDataTableLoadResult.Load(_currentValidationPass);
|
||||
_binaryDataTable = _binaryDataTableLoadResult.BinaryDataTable;
|
||||
|
||||
_binaryDataTable.SharedDependenciesTableWithBinaryDataTable ??= [_binaryDataTableLoadResult];
|
||||
_loadResult.SetDependenciesTable(_binaryDataTable.SharedDependenciesTableWithBinaryDataTable);
|
||||
}
|
||||
else
|
||||
MarkHasErrors();
|
||||
}
|
||||
else
|
||||
{
|
||||
_importTables = new SourceMarkupImportTables();
|
||||
_binaryDataTable = new MarkupBinaryDataTable(_loadResult.Uri);
|
||||
_binaryDataTable.SetConstantsTable(new MarkupConstantsTable());
|
||||
_binaryDataTable.SetSourceMarkupImportTables(new SourceMarkupImportTables());
|
||||
}
|
||||
|
||||
_loadResult.SetBinaryDataTable(_binaryDataTable);
|
||||
}
|
||||
|
||||
if (_currentValidationPass == LoadPass.DeclareTypes)
|
||||
{
|
||||
|
||||
foreach (var nsImport in Program.Directives.OfType<NamespaceImport>())
|
||||
{
|
||||
LoadResult loadResult;
|
||||
@@ -256,9 +280,9 @@ internal class AsmMarkupLoader
|
||||
_loadResult.MarkLoadFailed();
|
||||
|
||||
MarkupImportTables importTables = null;
|
||||
if (_importTables != null)
|
||||
if (_binaryDataTable.SourceMarkupImportTables != null)
|
||||
{
|
||||
importTables = _importTables.PrepareImportTables();
|
||||
importTables = _binaryDataTable.SourceMarkupImportTables.PrepareImportTables();
|
||||
_loadResult.SetImportTables(importTables);
|
||||
}
|
||||
|
||||
@@ -323,10 +347,10 @@ internal class AsmMarkupLoader
|
||||
|
||||
var contentBuffer = binaryEncodedConstant.Content;
|
||||
|
||||
ByteCodeWriter binaryConstantWrtier = new();
|
||||
binaryConstantWrtier.Write(contentBuffer, (uint)contentBuffer.Length);
|
||||
ByteCodeWriter binaryConstantWriter = new();
|
||||
binaryConstantWriter.Write(contentBuffer, (uint)contentBuffer.Length);
|
||||
|
||||
var binaryConstantReader = binaryConstantWrtier.CreateReader();
|
||||
var binaryConstantReader = binaryConstantWriter.CreateReader();
|
||||
constantValue = constantTypeSchema.DecodeBinary(binaryConstantReader);
|
||||
|
||||
persistData = constantValue;
|
||||
@@ -395,9 +419,9 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
LoadResult[] loadResultArray = LoadResult.EmptyList;
|
||||
int length = 0;
|
||||
if (_importTables != null)
|
||||
if (_binaryDataTable.SourceMarkupImportTables != null)
|
||||
{
|
||||
foreach (LoadResult importedLoadResult in _importTables.ImportedLoadResults)
|
||||
foreach (LoadResult importedLoadResult in _binaryDataTable.SourceMarkupImportTables.ImportedLoadResults)
|
||||
{
|
||||
if (importedLoadResult != _loadResult)
|
||||
++length;
|
||||
@@ -407,7 +431,7 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
loadResultArray = new LoadResult[length];
|
||||
int index = 0;
|
||||
foreach (LoadResult importedLoadResult in _importTables.ImportedLoadResults)
|
||||
foreach (LoadResult importedLoadResult in _binaryDataTable.SourceMarkupImportTables.ImportedLoadResults)
|
||||
{
|
||||
if (importedLoadResult != _loadResult)
|
||||
{
|
||||
@@ -472,12 +496,14 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
if (loadResult == MarkupSystem.UIXGlobal)
|
||||
return;
|
||||
for (int index = 0; index < _importTables.ImportedLoadResults.Count; ++index)
|
||||
|
||||
for (int index = 0; index < _binaryDataTable.SourceMarkupImportTables.ImportedLoadResults.Count; ++index)
|
||||
{
|
||||
if ((LoadResult)_importTables.ImportedLoadResults[index] == loadResult)
|
||||
if ((LoadResult)_binaryDataTable.SourceMarkupImportTables.ImportedLoadResults[index] == loadResult)
|
||||
return;
|
||||
}
|
||||
_importTables.ImportedLoadResults.Add(loadResult);
|
||||
|
||||
_binaryDataTable.SourceMarkupImportTables.ImportedLoadResults.Add(loadResult);
|
||||
}
|
||||
|
||||
public int TrackImportedType(TypeSchema type)
|
||||
@@ -485,14 +511,14 @@ internal class AsmMarkupLoader
|
||||
if (type is null) return -1;
|
||||
|
||||
TrackImportedLoadResult(type.Owner);
|
||||
return TrackImportedSchema(_importTables.ImportedTypes, type);
|
||||
return TrackImportedSchema(_binaryDataTable.SourceMarkupImportTables.ImportedTypes, type);
|
||||
}
|
||||
|
||||
public int TrackImportedConstructor(ConstructorSchema constructor)
|
||||
{
|
||||
if (constructor is null) return -1;
|
||||
|
||||
int num = TrackImportedSchema(_importTables.ImportedConstructors, constructor);
|
||||
int num = TrackImportedSchema(_binaryDataTable.SourceMarkupImportTables.ImportedConstructors, constructor);
|
||||
TrackImportedType(constructor.Owner);
|
||||
foreach (TypeSchema parameterType in constructor.ParameterTypes)
|
||||
TrackImportedType(parameterType);
|
||||
@@ -503,7 +529,7 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
if (property is null) return -1;
|
||||
|
||||
int num = TrackImportedSchema(_importTables.ImportedProperties, property);
|
||||
int num = TrackImportedSchema(_binaryDataTable.SourceMarkupImportTables.ImportedProperties, property);
|
||||
TrackImportedType(property.Owner);
|
||||
return num;
|
||||
}
|
||||
@@ -512,7 +538,7 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
if (method is null) return -1;
|
||||
|
||||
int num = TrackImportedSchema(_importTables.ImportedMethods, method);
|
||||
int num = TrackImportedSchema(_binaryDataTable.SourceMarkupImportTables.ImportedMethods, method);
|
||||
TrackImportedType(method.Owner);
|
||||
foreach (TypeSchema parameterType in method.ParameterTypes)
|
||||
TrackImportedType(parameterType);
|
||||
@@ -523,7 +549,7 @@ internal class AsmMarkupLoader
|
||||
{
|
||||
if (evt is null) return -1;
|
||||
|
||||
int num = TrackImportedSchema(_importTables.ImportedEvents, evt);
|
||||
int num = TrackImportedSchema(_binaryDataTable.SourceMarkupImportTables.ImportedEvents, evt);
|
||||
TrackImportedType(evt.Owner);
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Iris.Asm.Models;
|
||||
using Microsoft.Iris.Markup;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -24,9 +25,8 @@ public class Disassembler
|
||||
{
|
||||
_loadResult = loadResult;
|
||||
|
||||
_dataTableLoadResult = dataTableLoadResult is not null
|
||||
? dataTableLoadResult
|
||||
: loadResult.BinaryDataTable?.SharedDependenciesTableWithBinaryDataTable?.FirstOrDefault() as MarkupLoadResult;
|
||||
_dataTableLoadResult = dataTableLoadResult
|
||||
?? loadResult.BinaryDataTable?.SharedDependenciesTableWithBinaryDataTable?.FirstOrDefault() as MarkupLoadResult;
|
||||
|
||||
_importedUris = new()
|
||||
{
|
||||
@@ -57,7 +57,7 @@ public class Disassembler
|
||||
if (_loadResult.Status == LoadResultStatus.Error)
|
||||
throw new Exception($"Failed to load '{_loadResult.ErrorContextUri}'");
|
||||
|
||||
if (_dataTableLoadResult is not null)
|
||||
if (UseSharedDataTable)
|
||||
{
|
||||
_dataTableLoadResult.FullLoad();
|
||||
if (_dataTableLoadResult.Status == LoadResultStatus.Error)
|
||||
@@ -75,7 +75,7 @@ public class Disassembler
|
||||
foreach (var segment in segments)
|
||||
body.AddRange(segment);
|
||||
|
||||
if (_dataTableLoadResult is not null)
|
||||
if (UseSharedDataTable)
|
||||
body.Add(new SharedDataTableDirective(_dataTableLoadResult.Uri));
|
||||
|
||||
_program = new(body);
|
||||
@@ -86,6 +86,9 @@ public class Disassembler
|
||||
|
||||
public string Write() => Disassemble().ToString();
|
||||
|
||||
[MemberNotNullWhen(true, nameof(_dataTableLoadResult))]
|
||||
private bool UseSharedDataTable => _dataTableLoadResult is not null;
|
||||
|
||||
private IEnumerable<ExportDirective> GetExports()
|
||||
{
|
||||
foreach (var typeSchema in _loadResult.ExportTable)
|
||||
@@ -148,6 +151,9 @@ public class Disassembler
|
||||
|
||||
private IEnumerable<IImportDirective> EnumerateImports()
|
||||
{
|
||||
if (UseSharedDataTable)
|
||||
yield break;
|
||||
|
||||
// Ues _importedUris to keep track of what has already been imported.
|
||||
// Skip self and default UIX namespace.
|
||||
|
||||
@@ -323,7 +329,7 @@ public class Disassembler
|
||||
|
||||
private IEnumerable<ConstantDirective> GetConstants()
|
||||
{
|
||||
if (_dataTableLoadResult is not null)
|
||||
if (UseSharedDataTable)
|
||||
{
|
||||
// Constants have already been disassembled from the shared binary table
|
||||
var asmConstants = _dataTableLoadResult is AsmMarkupLoadResult asmDataTableLoadResult
|
||||
@@ -333,9 +339,9 @@ public class Disassembler
|
||||
foreach (var info in EnumerateConstantInfo(_dataTableLoadResult))
|
||||
{
|
||||
var constantName = asmConstants?[info.Index]?.Name
|
||||
?? $"sharedConst{info.Index:D}";
|
||||
?? info.GenerateDefaultName();
|
||||
|
||||
_constantsTable.Add(info.Index, constantName);
|
||||
_constantsTable[info.Index] = constantName;
|
||||
}
|
||||
|
||||
yield break;
|
||||
@@ -344,7 +350,7 @@ public class Disassembler
|
||||
{
|
||||
foreach (var info in EnumerateConstantInfo(_loadResult))
|
||||
{
|
||||
var constantName = $"const{info.Index:D}";
|
||||
var constantName = info.GenerateDefaultName();
|
||||
_constantsTable[info.Index] = constantName;
|
||||
yield return EncodeConstant(info.Value, constantName, info.Type);
|
||||
}
|
||||
@@ -397,7 +403,7 @@ public class Disassembler
|
||||
{
|
||||
var qualifiedTypeName = GetQualifiedName(typeSchema);
|
||||
|
||||
// ILayout has a number of derived classes with special named instacnes,
|
||||
// ILayout has a number of derived classes with special named instances,
|
||||
// but aren't implemented as canonical instances.
|
||||
if (constantValue is Layout.ILayout constantLayout && Layout.PredefinedLayouts.TryConvertToString(constantLayout, out var constantLayoutString))
|
||||
{
|
||||
@@ -456,5 +462,8 @@ public class Disassembler
|
||||
throw new NotSupportedException($"Unable to encode constant value '{constantValue}' of type '{qualifiedTypeName}'");
|
||||
}
|
||||
|
||||
private record RawConstantInfo(int Index, TypeSchema Type, object Value);
|
||||
private record RawConstantInfo(int Index, TypeSchema Type, object Value)
|
||||
{
|
||||
public string GenerateDefaultName() => $"const{Index:D}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,9 @@ public static class Extensions
|
||||
{
|
||||
public static void FullLoad(this LoadResult result)
|
||||
{
|
||||
if (result.Status is LoadResultStatus.Success)
|
||||
return;
|
||||
|
||||
result.Load(LoadPass.DeclareTypes);
|
||||
result.Load(LoadPass.PopulatePublicModel);
|
||||
result.Load(LoadPass.Full);
|
||||
@@ -73,6 +76,7 @@ public static class Extensions
|
||||
'\t' => @"\t",
|
||||
'\'' => @"\'",
|
||||
'"' => "\"",
|
||||
'\\' => @"\\",
|
||||
_ => null
|
||||
};
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using Sprache;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.Iris.Asm;
|
||||
|
||||
@@ -86,13 +87,49 @@ partial class Lexer
|
||||
if (!encodingMarkerResult.WasSuccessful)
|
||||
{
|
||||
// Support defining constants from string literals
|
||||
var stringLiteralResult = ExpressionInBraces(StringLiteral)(input);
|
||||
input = stringLiteralResult.Remainder;
|
||||
if (!stringLiteralResult.WasSuccessful)
|
||||
return stringLiteralResult.ForType<IDirective>();
|
||||
|
||||
// Skip the opening brace
|
||||
input = input.Advance();
|
||||
if (input.Current != '"')
|
||||
return Result.Failure<IDirective>(input, "Invalid constant", ["Expected a string literal."]);
|
||||
|
||||
input = input.Advance();
|
||||
|
||||
StringBuilder literalBuilder = new();
|
||||
char c;
|
||||
while (true)
|
||||
{
|
||||
c = input.Current;
|
||||
if (c == '\\')
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/lexical-structure#unicode-character-escape-sequences
|
||||
input = input.Advance();
|
||||
c = input.Current switch
|
||||
{
|
||||
'0' => '\0',
|
||||
'b' => '\b',
|
||||
'n' => '\n',
|
||||
'r' => '\r',
|
||||
't' => '\t',
|
||||
_ => input.Current
|
||||
};
|
||||
}
|
||||
|
||||
input = input.Advance();
|
||||
|
||||
if (c == '"')
|
||||
break;
|
||||
|
||||
literalBuilder.Append(c);
|
||||
}
|
||||
|
||||
if (input.Current != ')')
|
||||
return Result.Failure<IDirective>(input, "Invalid constant", ["Missing closed brace."]);
|
||||
|
||||
input = input.Advance();
|
||||
|
||||
persistMode = Markup.MarkupConstantPersistMode.FromString;
|
||||
content = stringLiteralResult.Value[1..^1].Unescape();
|
||||
content = literalBuilder.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -130,10 +130,4 @@ public static partial class Lexer
|
||||
|
||||
return Result.Success(qualifiedName, input);
|
||||
}
|
||||
|
||||
private static Parser<string> ExpressionInBraces(Parser<string> parser, char open = '(', char close = ')') =>
|
||||
from openBrace in Parse.Char(open).Token()
|
||||
from expression in parser.Optional()
|
||||
from closeBrace in Parse.Char(close).Token()
|
||||
select expression.GetOrElse(string.Empty).Trim();
|
||||
}
|
||||
|
||||
@@ -27,23 +27,29 @@ public record Program
|
||||
public Program(IEnumerable<IBodyItem> body)
|
||||
{
|
||||
Body = body.Cached();
|
||||
|
||||
Directives = body.OfType<IDirective>().Cached();
|
||||
DataTableDirective = Directives.OfType<SharedDataTableDirective>().SingleOrDefault();
|
||||
Imports = Directives.OfType<IImportDirective>().Cached();
|
||||
Exports = Directives.OfType<ExportDirective>().Cached();
|
||||
|
||||
Code = body.OfType<ICodeItem>().Cached();
|
||||
}
|
||||
|
||||
public IEnumerable<IBodyItem> Body { get; }
|
||||
public IEnumerable<IBodyItem> Body { get; private set; }
|
||||
|
||||
public IEnumerable<IDirective> Directives { get; }
|
||||
public SharedDataTableDirective DataTableDirective { get; }
|
||||
public IEnumerable<IImportDirective> Imports { get; }
|
||||
public IEnumerable<ExportDirective> Exports { get; }
|
||||
public IEnumerable<IDirective> Directives => Body.OfType<IDirective>();
|
||||
|
||||
public IEnumerable<ICodeItem> Code { get; }
|
||||
public SharedDataTableDirective DataTableDirective => Body.OfType<SharedDataTableDirective>().SingleOrDefault();
|
||||
|
||||
public IEnumerable<IImportDirective> Imports => Directives.OfType<IImportDirective>();
|
||||
|
||||
public IEnumerable<ExportDirective> Exports => Directives.OfType<ExportDirective>();
|
||||
|
||||
public IEnumerable<ICodeItem> Code => Body.OfType<ICodeItem>();
|
||||
|
||||
public void ImportSharedDataTable(Program dataTable)
|
||||
{
|
||||
List<IBodyItem> newBody = Exports.ToList<IBodyItem>();
|
||||
|
||||
newBody.AddRange(dataTable.Directives.Where(d => d is not ExportDirective));
|
||||
newBody.AddRange(Code);
|
||||
|
||||
Body = newBody.Cached();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user