mirror of
https://github.com/ZuneDev/ZuneUIXTools.git
synced 2026-07-27 13:11:59 -07:00
[WIP] Implement more of AsmMarkupLoader
This commit is contained in:
+162
-12
@@ -1,6 +1,5 @@
|
|||||||
using Microsoft.Iris.Asm.Models;
|
using Microsoft.Iris.Asm.Models;
|
||||||
using Microsoft.Iris.Data;
|
using Microsoft.Iris.Data;
|
||||||
using Microsoft.Iris.Library;
|
|
||||||
using Microsoft.Iris.Markup;
|
using Microsoft.Iris.Markup;
|
||||||
using Microsoft.Iris.Session;
|
using Microsoft.Iris.Session;
|
||||||
using Sprache;
|
using Sprache;
|
||||||
@@ -19,11 +18,16 @@ internal class AsmMarkupLoader
|
|||||||
private readonly AsmMarkupLoadResult _loadResult;
|
private readonly AsmMarkupLoadResult _loadResult;
|
||||||
private bool _usingSharedBinaryDataTable;
|
private bool _usingSharedBinaryDataTable;
|
||||||
private SourceMarkupImportTables _importTables;
|
private SourceMarkupImportTables _importTables;
|
||||||
|
private ObjectSection _objectSection;
|
||||||
|
|
||||||
private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
|
private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
|
||||||
private readonly HashSet<string> _referencedNamespaces = new();
|
private readonly HashSet<string> _referencedNamespaces = new();
|
||||||
|
|
||||||
protected AsmMarkupLoader(AsmMarkupLoadResult loadResult) => _loadResult = loadResult;
|
protected AsmMarkupLoader(AsmMarkupLoadResult loadResult)
|
||||||
|
{
|
||||||
|
_loadResult = loadResult;
|
||||||
|
_objectSection = new(_program, _loadResult);
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasErrors { get; protected set; }
|
public bool HasErrors { get; protected set; }
|
||||||
|
|
||||||
@@ -48,9 +52,42 @@ internal class AsmMarkupLoader
|
|||||||
owner._program = parseResult.Value;
|
owner._program = parseResult.Value;
|
||||||
else
|
else
|
||||||
owner.MarkHasErrors();
|
owner.MarkHasErrors();
|
||||||
|
|
||||||
return owner;
|
return owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LoadResult FindDependency(string prefix)
|
||||||
|
{
|
||||||
|
if (prefix == null)
|
||||||
|
return MarkupSystem.UIXGlobal;
|
||||||
|
|
||||||
|
return _importedNamespaces[prefix];
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeSchema ResolveTypeFromQualifiedName(string qualifiedName)
|
||||||
|
{
|
||||||
|
if (qualifiedName == null)
|
||||||
|
throw new ArgumentNullException(nameof(qualifiedName));
|
||||||
|
|
||||||
|
string typeName;
|
||||||
|
LoadResult result;
|
||||||
|
|
||||||
|
int idx = qualifiedName.IndexOf(':');
|
||||||
|
if (idx <= 0)
|
||||||
|
{
|
||||||
|
typeName = qualifiedName[..idx];
|
||||||
|
result = FindDependency(qualifiedName[..idx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typeName = qualifiedName;
|
||||||
|
result = _loadResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ExportTable.Where(e => e.Name == typeName).FirstOrDefault()
|
||||||
|
?? throw new Exception($"No type with the name '{typeName}' was exported from {result.Uri}");
|
||||||
|
}
|
||||||
|
|
||||||
public void MarkHasErrors()
|
public void MarkHasErrors()
|
||||||
{
|
{
|
||||||
if (HasErrors)
|
if (HasErrors)
|
||||||
@@ -88,7 +125,7 @@ internal class AsmMarkupLoader
|
|||||||
_importTables = new SourceMarkupImportTables();
|
_importTables = new SourceMarkupImportTables();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var nsImport in _program.Imports.OfType<NamespaceImport>())
|
foreach (var nsImport in _program.Directives.OfType<NamespaceImport>())
|
||||||
{
|
{
|
||||||
LoadResult loadResult;
|
LoadResult loadResult;
|
||||||
if (nsImport.Uri == "Me")
|
if (nsImport.Uri == "Me")
|
||||||
@@ -97,7 +134,7 @@ internal class AsmMarkupLoader
|
|||||||
loadResult = MarkupSystem.ResolveLoadResult(nsImport.Uri, _loadResult.IslandReferences);
|
loadResult = MarkupSystem.ResolveLoadResult(nsImport.Uri, _loadResult.IslandReferences);
|
||||||
|
|
||||||
if (loadResult == null || loadResult is ErrorLoadResult)
|
if (loadResult == null || loadResult is ErrorLoadResult)
|
||||||
ReportError($"Unable to load '{nsImport.Uri}' (xmlns prefix '{nsImport.Name}')", -1, -1);
|
ReportError($"Unable to load '{nsImport.Uri}' (xmlns prefix '{nsImport.Name}')", nsImport);
|
||||||
else if (loadResult.Status == LoadResultStatus.Error)
|
else if (loadResult.Status == LoadResultStatus.Error)
|
||||||
MarkHasErrors();
|
MarkHasErrors();
|
||||||
if (MarkupSystem.CompileMode)
|
if (MarkupSystem.CompileMode)
|
||||||
@@ -106,7 +143,7 @@ internal class AsmMarkupLoader
|
|||||||
if (loadResult != null)
|
if (loadResult != null)
|
||||||
{
|
{
|
||||||
_importedNamespaces[nsImport.Name] = loadResult;
|
_importedNamespaces[nsImport.Name] = loadResult;
|
||||||
//TrackImportedLoadResult(loadResult);
|
TrackImportedLoadResult(loadResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -134,7 +171,7 @@ internal class AsmMarkupLoader
|
|||||||
|
|
||||||
if (_currentValidationPass == LoadPass.Full)
|
if (_currentValidationPass == LoadPass.Full)
|
||||||
{
|
{
|
||||||
foreach (var nsImport in _program.Imports.OfType<NamespaceImport>())
|
foreach (var nsImport in _program.Directives.OfType<NamespaceImport>())
|
||||||
{
|
{
|
||||||
if (!_referencedNamespaces.Contains(nsImport.Name))
|
if (!_referencedNamespaces.Contains(nsImport.Name))
|
||||||
ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'");
|
ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'");
|
||||||
@@ -144,7 +181,7 @@ internal class AsmMarkupLoader
|
|||||||
|
|
||||||
if (_currentValidationPass == LoadPass.DeclareTypes)
|
if (_currentValidationPass == LoadPass.DeclareTypes)
|
||||||
{
|
{
|
||||||
//_loadResult.SetExportTable(PrepareExportTable());
|
_loadResult.SetExportTable(PrepareExportTable());
|
||||||
//_loadResult.SetAliasTable(PrepareAliasTable());
|
//_loadResult.SetAliasTable(PrepareAliasTable());
|
||||||
}
|
}
|
||||||
else if (_currentValidationPass == LoadPass.PopulatePublicModel)
|
else if (_currentValidationPass == LoadPass.PopulatePublicModel)
|
||||||
@@ -173,13 +210,13 @@ internal class AsmMarkupLoader
|
|||||||
MarkupLineNumberTable lineNumberTable = new();
|
MarkupLineNumberTable lineNumberTable = new();
|
||||||
MarkupConstantsTable constantsTable = _loadResult.BinaryDataTable?.ConstantsTable ?? new();
|
MarkupConstantsTable constantsTable = _loadResult.BinaryDataTable?.ConstantsTable ?? new();
|
||||||
|
|
||||||
|
_loadResult.SetLineNumberTable(lineNumberTable);
|
||||||
_loadResult.SetDataMappingsTable(PrepareDataMappingTable());
|
_loadResult.SetDataMappingsTable(PrepareDataMappingTable());
|
||||||
_loadResult.ValidationComplete();
|
_loadResult.ValidationComplete();
|
||||||
|
|
||||||
ByteCodeReader reader = null;
|
ByteCodeReader reader = null;
|
||||||
ObjectSection objectSection = new(_program, _loadResult);
|
|
||||||
if (!HasErrors)
|
if (!HasErrors)
|
||||||
reader = objectSection.Encode();
|
reader = _objectSection.Encode();
|
||||||
|
|
||||||
if (!_usingSharedBinaryDataTable)
|
if (!_usingSharedBinaryDataTable)
|
||||||
{
|
{
|
||||||
@@ -188,7 +225,6 @@ internal class AsmMarkupLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
lineNumberTable.PrepareForRuntimeUse();
|
lineNumberTable.PrepareForRuntimeUse();
|
||||||
_loadResult.SetLineNumberTable(lineNumberTable);
|
|
||||||
|
|
||||||
if (reader != null)
|
if (reader != null)
|
||||||
_loadResult.SetObjectSection(reader);
|
_loadResult.SetObjectSection(reader);
|
||||||
@@ -203,14 +239,63 @@ internal class AsmMarkupLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeSchema[] PrepareExportTable()
|
||||||
|
{
|
||||||
|
var exportDirectives = _program.Directives.OfType<ExportDirective>().ToArray();
|
||||||
|
var exports = new TypeSchema[exportDirectives.Length];
|
||||||
|
|
||||||
|
for (int i = 0; i < exportDirectives.Length; i++)
|
||||||
|
{
|
||||||
|
ExportDirective exportDirective = exportDirectives[i];
|
||||||
|
|
||||||
|
var markupType = (MarkupType)Enum.Parse(typeof(MarkupType), exportDirective.BaseTypeName);
|
||||||
|
var exportedTypeSchema = MarkupTypeSchema.Build(markupType, _loadResult, exportDirective.LabelPrefix);
|
||||||
|
|
||||||
|
// Set all offsets
|
||||||
|
var propOffset = _objectSection.LabelOffsetMap[exportDirective.InitializePropertiesLabel];
|
||||||
|
exportedTypeSchema.SetInitializePropertiesOffset(propOffset);
|
||||||
|
|
||||||
|
var contOffset = _objectSection.LabelOffsetMap[exportDirective.InitializeContentLabel];
|
||||||
|
exportedTypeSchema.SetInitializeContentOffset(contOffset);
|
||||||
|
|
||||||
|
var loclOffset = _objectSection.LabelOffsetMap[exportDirective.InitializeLocalsInputLabel];
|
||||||
|
exportedTypeSchema.SetInitializeLocalsInputOffset(loclOffset);
|
||||||
|
|
||||||
|
var evaliOffsets = _objectSection.LabelOffsetMap
|
||||||
|
.Where(kvp => kvp.Key.StartsWith(exportDirective.InitialEvaluateOffsetsLabelPrefix))
|
||||||
|
.Select(kvp => kvp.Value)
|
||||||
|
.ToArray();
|
||||||
|
exportedTypeSchema.SetInitialEvaluateOffsets(evaliOffsets);
|
||||||
|
|
||||||
|
var evalfOffsets = _objectSection.LabelOffsetMap
|
||||||
|
.Where(kvp => kvp.Key.StartsWith(exportDirective.FinalEvaluateOffsetsLabelPrefix))
|
||||||
|
.Select(kvp => kvp.Value)
|
||||||
|
.ToArray();
|
||||||
|
exportedTypeSchema.SetFinalEvaluateOffsets(evalfOffsets);
|
||||||
|
|
||||||
|
var rfshOffsets = _objectSection.LabelOffsetMap
|
||||||
|
.Where(kvp => kvp.Key.StartsWith(exportDirective.RefreshGroupOffsetsLabelPrefix))
|
||||||
|
.Select(kvp => kvp.Value)
|
||||||
|
.ToArray();
|
||||||
|
exportedTypeSchema.SetRefreshListenerGroupOffsets(rfshOffsets);
|
||||||
|
|
||||||
|
exportedTypeSchema.SetListenerCount(exportDirective.ListenerCount);
|
||||||
|
|
||||||
|
exports[i] = exportedTypeSchema;
|
||||||
|
}
|
||||||
|
|
||||||
|
return exports;
|
||||||
|
}
|
||||||
private LoadResult[] PrepareDependenciesTable()
|
private LoadResult[] PrepareDependenciesTable()
|
||||||
{
|
{
|
||||||
return null;
|
// TODO
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
private MarkupDataMapping[] PrepareDataMappingTable()
|
private MarkupDataMapping[] PrepareDataMappingTable()
|
||||||
{
|
{
|
||||||
return null;
|
// TODO
|
||||||
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReportError(string error, int line, int column)
|
public void ReportError(string error, int line, int column)
|
||||||
@@ -218,4 +303,69 @@ internal class AsmMarkupLoader
|
|||||||
MarkHasErrors();
|
MarkHasErrors();
|
||||||
ErrorManager.ReportError(line, column, error);
|
ErrorManager.ReportError(line, column, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ReportError(string error, IAsmItem item)
|
||||||
|
=> ReportError(error, item.Line, item.Column);
|
||||||
|
|
||||||
|
public void TrackImportedLoadResult(LoadResult loadResult)
|
||||||
|
{
|
||||||
|
if (loadResult == MarkupSystem.UIXGlobal)
|
||||||
|
return;
|
||||||
|
for (int index = 0; index < _importTables.ImportedLoadResults.Count; ++index)
|
||||||
|
{
|
||||||
|
if ((LoadResult)_importTables.ImportedLoadResults[index] == loadResult)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_importTables.ImportedLoadResults.Add(loadResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedType(TypeSchema type)
|
||||||
|
{
|
||||||
|
TrackImportedLoadResult(type.Owner);
|
||||||
|
return TrackImportedSchema(_importTables.ImportedTypes, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedConstructor(ConstructorSchema constructor)
|
||||||
|
{
|
||||||
|
int num = TrackImportedSchema(_importTables.ImportedConstructors, constructor);
|
||||||
|
TrackImportedType(constructor.Owner);
|
||||||
|
foreach (TypeSchema parameterType in constructor.ParameterTypes)
|
||||||
|
TrackImportedType(parameterType);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedProperty(PropertySchema property)
|
||||||
|
{
|
||||||
|
int num = TrackImportedSchema(_importTables.ImportedProperties, property);
|
||||||
|
TrackImportedType(property.Owner);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedMethod(MethodSchema method)
|
||||||
|
{
|
||||||
|
int num = TrackImportedSchema(_importTables.ImportedMethods, method);
|
||||||
|
TrackImportedType(method.Owner);
|
||||||
|
foreach (TypeSchema parameterType in method.ParameterTypes)
|
||||||
|
TrackImportedType(parameterType);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedEvent(EventSchema evt)
|
||||||
|
{
|
||||||
|
int num = TrackImportedSchema(_importTables.ImportedEvents, evt);
|
||||||
|
TrackImportedType(evt.Owner);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int TrackImportedSchema(Vector importList, object schema)
|
||||||
|
{
|
||||||
|
for (int index = 0; index < importList.Count; ++index)
|
||||||
|
{
|
||||||
|
if (importList[index] == schema)
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
int count = importList.Count;
|
||||||
|
importList.Add(schema);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,18 +8,14 @@ namespace Microsoft.Iris.Asm;
|
|||||||
|
|
||||||
public class ObjectSection
|
public class ObjectSection
|
||||||
{
|
{
|
||||||
readonly IEnumerable<Instruction> _instructions;
|
readonly IEnumerable<IBodyItem> _body;
|
||||||
readonly MarkupLoadResult _loadResult;
|
readonly MarkupLoadResult _loadResult;
|
||||||
|
readonly Dictionary<string, uint> _labelOffsetMap = new();
|
||||||
public ObjectSection(IEnumerable<Instruction> instructions, MarkupLoadResult loadResult)
|
|
||||||
{
|
|
||||||
_instructions = instructions;
|
|
||||||
_loadResult = loadResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectSection(IEnumerable<IBodyItem> body, MarkupLoadResult loadResult)
|
public ObjectSection(IEnumerable<IBodyItem> body, MarkupLoadResult loadResult)
|
||||||
: this(body.OfType<Instruction>(), loadResult)
|
|
||||||
{
|
{
|
||||||
|
_body = body;
|
||||||
|
_loadResult = loadResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectSection(Program program, MarkupLoadResult loadResult)
|
public ObjectSection(Program program, MarkupLoadResult loadResult)
|
||||||
@@ -27,14 +23,26 @@ public class ObjectSection
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<string, uint> LabelOffsetMap => _labelOffsetMap;
|
||||||
|
|
||||||
public ByteCodeReader Encode()
|
public ByteCodeReader Encode()
|
||||||
{
|
{
|
||||||
ByteCodeWriter writer = new();
|
ByteCodeWriter writer = new();
|
||||||
|
|
||||||
foreach (var instruction in _instructions)
|
foreach (var bodyItem in _body)
|
||||||
{
|
{
|
||||||
|
var offset = writer.DataSize;
|
||||||
|
|
||||||
|
if (bodyItem is Label label)
|
||||||
|
{
|
||||||
|
_labelOffsetMap[label.Name] = offset;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (bodyItem is not Instruction instruction)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Add entry to line number table
|
// Add entry to line number table
|
||||||
_loadResult.LineNumberTable.AddRecord(writer.DataSize, instruction.Line, instruction.Column);
|
_loadResult.LineNumberTable.AddRecord(offset, instruction.Line, instruction.Column);
|
||||||
|
|
||||||
var opCode = instruction.OpCode;
|
var opCode = instruction.OpCode;
|
||||||
writer.WriteByte(opCode);
|
writer.WriteByte(opCode);
|
||||||
|
|||||||
@@ -44,10 +44,11 @@ main:
|
|||||||
Assert.Equal(9, ast.Body.Count());
|
Assert.Equal(9, ast.Body.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Theory]
|
||||||
public async Task Assemble()
|
[InlineData("testA")]
|
||||||
|
public async Task Assemble(string fileNameWithoutExtension)
|
||||||
{
|
{
|
||||||
using TempFile tempFile = new("testA.uixa", ".uixa");
|
using TempFile tempFile = new($"{fileNameWithoutExtension}.uixa", ".uixa");
|
||||||
await tempFile.InitAsync();
|
await tempFile.InitAsync();
|
||||||
|
|
||||||
CompilerInput[] compilerInputs = [
|
CompilerInput[] compilerInputs = [
|
||||||
|
|||||||
Binary file not shown.
+1
-1
@@ -12,7 +12,7 @@
|
|||||||
<Children>
|
<Children>
|
||||||
<Text Name="MainBlock" Color="Red"
|
<Text Name="MainBlock" Color="Red"
|
||||||
Content="Howdy from Microsoft.Iris!"/>
|
Content="Howdy from Microsoft.Iris!"/>
|
||||||
<me:Alt/>
|
<me:Alt/>
|
||||||
</Children>
|
</Children>
|
||||||
</Panel>
|
</Panel>
|
||||||
</Content>
|
</Content>
|
||||||
|
|||||||
Reference in New Issue
Block a user