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.Data;
|
||||
using Microsoft.Iris.Library;
|
||||
using Microsoft.Iris.Markup;
|
||||
using Microsoft.Iris.Session;
|
||||
using Sprache;
|
||||
@@ -19,11 +18,16 @@ internal class AsmMarkupLoader
|
||||
private readonly AsmMarkupLoadResult _loadResult;
|
||||
private bool _usingSharedBinaryDataTable;
|
||||
private SourceMarkupImportTables _importTables;
|
||||
private ObjectSection _objectSection;
|
||||
|
||||
private readonly Dictionary<string, LoadResult> _importedNamespaces = 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; }
|
||||
|
||||
@@ -48,9 +52,42 @@ internal class AsmMarkupLoader
|
||||
owner._program = parseResult.Value;
|
||||
else
|
||||
owner.MarkHasErrors();
|
||||
|
||||
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()
|
||||
{
|
||||
if (HasErrors)
|
||||
@@ -88,7 +125,7 @@ internal class AsmMarkupLoader
|
||||
_importTables = new SourceMarkupImportTables();
|
||||
}
|
||||
|
||||
foreach (var nsImport in _program.Imports.OfType<NamespaceImport>())
|
||||
foreach (var nsImport in _program.Directives.OfType<NamespaceImport>())
|
||||
{
|
||||
LoadResult loadResult;
|
||||
if (nsImport.Uri == "Me")
|
||||
@@ -97,7 +134,7 @@ internal class AsmMarkupLoader
|
||||
loadResult = MarkupSystem.ResolveLoadResult(nsImport.Uri, _loadResult.IslandReferences);
|
||||
|
||||
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)
|
||||
MarkHasErrors();
|
||||
if (MarkupSystem.CompileMode)
|
||||
@@ -106,7 +143,7 @@ internal class AsmMarkupLoader
|
||||
if (loadResult != null)
|
||||
{
|
||||
_importedNamespaces[nsImport.Name] = loadResult;
|
||||
//TrackImportedLoadResult(loadResult);
|
||||
TrackImportedLoadResult(loadResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +171,7 @@ internal class AsmMarkupLoader
|
||||
|
||||
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))
|
||||
ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'");
|
||||
@@ -144,7 +181,7 @@ internal class AsmMarkupLoader
|
||||
|
||||
if (_currentValidationPass == LoadPass.DeclareTypes)
|
||||
{
|
||||
//_loadResult.SetExportTable(PrepareExportTable());
|
||||
_loadResult.SetExportTable(PrepareExportTable());
|
||||
//_loadResult.SetAliasTable(PrepareAliasTable());
|
||||
}
|
||||
else if (_currentValidationPass == LoadPass.PopulatePublicModel)
|
||||
@@ -173,13 +210,13 @@ internal class AsmMarkupLoader
|
||||
MarkupLineNumberTable lineNumberTable = new();
|
||||
MarkupConstantsTable constantsTable = _loadResult.BinaryDataTable?.ConstantsTable ?? new();
|
||||
|
||||
_loadResult.SetLineNumberTable(lineNumberTable);
|
||||
_loadResult.SetDataMappingsTable(PrepareDataMappingTable());
|
||||
_loadResult.ValidationComplete();
|
||||
|
||||
ByteCodeReader reader = null;
|
||||
ObjectSection objectSection = new(_program, _loadResult);
|
||||
if (!HasErrors)
|
||||
reader = objectSection.Encode();
|
||||
reader = _objectSection.Encode();
|
||||
|
||||
if (!_usingSharedBinaryDataTable)
|
||||
{
|
||||
@@ -188,7 +225,6 @@ internal class AsmMarkupLoader
|
||||
}
|
||||
|
||||
lineNumberTable.PrepareForRuntimeUse();
|
||||
_loadResult.SetLineNumberTable(lineNumberTable);
|
||||
|
||||
if (reader != null)
|
||||
_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()
|
||||
{
|
||||
return null;
|
||||
// TODO
|
||||
return [];
|
||||
}
|
||||
|
||||
private MarkupDataMapping[] PrepareDataMappingTable()
|
||||
{
|
||||
return null;
|
||||
// TODO
|
||||
return [];
|
||||
}
|
||||
|
||||
public void ReportError(string error, int line, int column)
|
||||
@@ -218,4 +303,69 @@ internal class AsmMarkupLoader
|
||||
MarkHasErrors();
|
||||
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
|
||||
{
|
||||
readonly IEnumerable<Instruction> _instructions;
|
||||
readonly IEnumerable<IBodyItem> _body;
|
||||
readonly MarkupLoadResult _loadResult;
|
||||
|
||||
public ObjectSection(IEnumerable<Instruction> instructions, MarkupLoadResult loadResult)
|
||||
{
|
||||
_instructions = instructions;
|
||||
_loadResult = loadResult;
|
||||
}
|
||||
readonly Dictionary<string, uint> _labelOffsetMap = new();
|
||||
|
||||
public ObjectSection(IEnumerable<IBodyItem> body, MarkupLoadResult loadResult)
|
||||
: this(body.OfType<Instruction>(), loadResult)
|
||||
{
|
||||
_body = body;
|
||||
_loadResult = loadResult;
|
||||
}
|
||||
|
||||
public ObjectSection(Program program, MarkupLoadResult loadResult)
|
||||
@@ -27,14 +23,26 @@ public class ObjectSection
|
||||
{
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<string, uint> LabelOffsetMap => _labelOffsetMap;
|
||||
|
||||
public ByteCodeReader Encode()
|
||||
{
|
||||
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
|
||||
_loadResult.LineNumberTable.AddRecord(writer.DataSize, instruction.Line, instruction.Column);
|
||||
_loadResult.LineNumberTable.AddRecord(offset, instruction.Line, instruction.Column);
|
||||
|
||||
var opCode = instruction.OpCode;
|
||||
writer.WriteByte(opCode);
|
||||
|
||||
Reference in New Issue
Block a user