[WIP] Implement more of AsmMarkupLoader

This commit is contained in:
Yoshi Askharoun
2024-02-10 19:19:40 -06:00
parent 69fd6b71a2
commit c8b5091fd9
5 changed files with 185 additions and 26 deletions
+162 -12
View File
@@ -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;
}
}
+18 -10
View File
@@ -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);