Fix export tables and remove static Load method

This commit is contained in:
Yoshi Askharoun
2024-02-10 21:38:18 -06:00
parent 93fa998caa
commit 97001fbd29
4 changed files with 69 additions and 55 deletions
+1 -1
View File
@@ -23,7 +23,7 @@ internal class AsmMarkupLoadResult : MarkupLoadResult
_resource = resource;
if (uri != resource.Uri)
_uriUnderlying = resource.Uri;
_loader = AsmMarkupLoader.Load(this, resource);
_loader = new AsmMarkupLoader(this, resource);
}
public AsmMarkupLoadResult(string uri)
+63 -53
View File
@@ -13,7 +13,6 @@ namespace Microsoft.Iris.Asm;
internal class AsmMarkupLoader
{
private string _asmSource;
private Program _program;
private LoadPass _currentValidationPass;
private readonly AsmMarkupLoadResult _loadResult;
private bool _usingSharedBinaryDataTable;
@@ -23,18 +22,9 @@ internal class AsmMarkupLoader
private readonly Dictionary<string, LoadResult> _importedNamespaces = new();
private readonly HashSet<string> _referencedNamespaces = new();
protected AsmMarkupLoader(AsmMarkupLoadResult loadResult)
internal unsafe AsmMarkupLoader(AsmMarkupLoadResult loadResult, Resource resource)
{
_loadResult = loadResult;
_objectSection = new(_program, _loadResult);
}
public bool HasErrors { get; protected set; }
internal static unsafe AsmMarkupLoader Load(AsmMarkupLoadResult loadResult, Resource resource)
{
AsmMarkupLoader owner = new(loadResult);
if (resource.Status != ResourceStatus.Available)
throw new InvalidOperationException("Resource must be available for reading");
@@ -44,18 +34,19 @@ internal class AsmMarkupLoader
int sourceStartOffset = 0;
if (resource.Length >= 4 && *data == 0xEF && *(data + 1) == 0xBB && *(data + 2) == 0xBF)
sourceStartOffset = 3;
_asmSource = Encoding.UTF8.GetString(data + sourceStartOffset, (int)(resource.Length - sourceStartOffset));
owner._asmSource = Encoding.UTF8.GetString(data + sourceStartOffset, (int)(resource.Length - sourceStartOffset));
var parseResult = Lexer.Program.TryParse(owner._asmSource);
var parseResult = Lexer.Program.TryParse(_asmSource);
if (parseResult.WasSuccessful)
owner._program = parseResult.Value;
Program = parseResult.Value;
else
owner.MarkHasErrors();
return owner;
MarkHasErrors();
}
public bool HasErrors { get; protected set; }
private Program Program { get; set; }
public LoadResult FindDependency(string prefix)
{
if (prefix == null)
@@ -110,10 +101,15 @@ internal class AsmMarkupLoader
var parseResult = Lexer.Program.TryParse(_asmSource);
if (parseResult.WasSuccessful)
_program = parseResult.Value;
{
Program = parseResult.Value;
_objectSection = new(Program, _loadResult);
}
else
{
foreach (var errors in parseResult.Expectations)
ReportError(errors, -1, -1);
}
if (_loadResult.BinaryDataTable != null)
{
@@ -125,7 +121,7 @@ internal class AsmMarkupLoader
_importTables = new SourceMarkupImportTables();
}
foreach (var nsImport in _program.Directives.OfType<NamespaceImport>())
foreach (var nsImport in Program.Directives.OfType<NamespaceImport>())
{
LoadResult loadResult;
if (nsImport.Uri == "Me")
@@ -158,7 +154,7 @@ internal class AsmMarkupLoader
}
}
if (_program != null && currentPass != LoadPass.Done)
if (Program != null && currentPass != LoadPass.Done)
{
//foreach (ValidateClass validateClass in _program.ClassList)
// validateClass.Validate(_currentValidationPass);
@@ -171,7 +167,7 @@ internal class AsmMarkupLoader
if (_currentValidationPass == LoadPass.Full)
{
foreach (var nsImport in _program.Directives.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}'");
@@ -186,7 +182,7 @@ internal class AsmMarkupLoader
}
else if (_currentValidationPass == LoadPass.PopulatePublicModel)
{
if (_program == null)
if (Program == null)
return;
//foreach (ValidateClass validateClass in _parseResult.ClassList)
@@ -216,7 +212,10 @@ internal class AsmMarkupLoader
ByteCodeReader reader = null;
if (!HasErrors)
{
reader = _objectSection.Encode();
UpdateExportOffsets();
}
if (!_usingSharedBinaryDataTable)
{
@@ -232,7 +231,7 @@ internal class AsmMarkupLoader
_loadResult.SetDependenciesTable(PrepareDependenciesTable());
if (!MarkupSystem.TrackAdditionalMetadata)
_program = null;
Program = null;
//foreach (DisposableObject validateObject in _validateObjects)
// validateObject.Dispose(this);
@@ -241,7 +240,7 @@ internal class AsmMarkupLoader
private TypeSchema[] PrepareExportTable()
{
var exportDirectives = _program.Directives.OfType<ExportDirective>().ToArray();
var exportDirectives = Program.Directives.OfType<ExportDirective>().ToArray();
var exports = new TypeSchema[exportDirectives.Length];
for (int i = 0; i < exportDirectives.Length; i++)
@@ -251,41 +250,17 @@ internal class AsmMarkupLoader
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);
// The offsets aren't known until the object section has been encoded,
// so we have to defer setting them until the Full load pass.
exports[i] = exportedTypeSchema;
}
return exports;
}
private LoadResult[] PrepareDependenciesTable()
{
// TODO
@@ -298,6 +273,41 @@ internal class AsmMarkupLoader
return [];
}
private void UpdateExportOffsets()
{
var exportDirectives = Program.Directives.OfType<ExportDirective>().ToArray();
uint[] GetOffsets(string prefix) => _objectSection.LabelOffsetMap
.Where(kvp => kvp.Key.StartsWith(prefix))
.Select(kvp => kvp.Value)
.ToArray();
for (int i = 0; i < _loadResult.ExportTable.Length; i++)
{
var exportedTypeSchema = (MarkupTypeSchema)_loadResult.ExportTable[i];
var exportDirective = exportDirectives[i];
// Set all offsets
if (_objectSection.LabelOffsetMap.TryGetValue(exportDirective.InitializePropertiesLabel, out var propOffset))
exportedTypeSchema.SetInitializePropertiesOffset(propOffset);
if (_objectSection.LabelOffsetMap.TryGetValue(exportDirective.InitializeContentLabel, out var contOffset))
exportedTypeSchema.SetInitializeContentOffset(contOffset);
if (_objectSection.LabelOffsetMap.TryGetValue(exportDirective.InitializeLocalsInputLabel, out var loclOffset))
exportedTypeSchema.SetInitializeLocalsInputOffset(loclOffset);
var evaliOffsets = GetOffsets(exportDirective.InitialEvaluateOffsetsLabelPrefix);
exportedTypeSchema.SetInitialEvaluateOffsets(evaliOffsets);
var evalfOffsets = GetOffsets(exportDirective.FinalEvaluateOffsetsLabelPrefix);
exportedTypeSchema.SetFinalEvaluateOffsets(evalfOffsets);
var rfshOffsets = GetOffsets(exportDirective.FinalEvaluateOffsetsLabelPrefix);
exportedTypeSchema.SetRefreshListenerGroupOffsets(rfshOffsets);
}
}
public void ReportError(string error, int line, int column)
{
MarkHasErrors();
+3
View File
@@ -38,12 +38,15 @@ public class Disassembler
yield return new ExportDirective(labelPrefix, markupTypeSchema.ListenerCount, baseName);
var propOffset = markupTypeSchema.InitializePropertiesOffset;
if (propOffset != uint.MaxValue)
InsertLabel(propOffset, ExportDirective.GetInitializePropertiesLabel(labelPrefix));
var loclOffset = markupTypeSchema.InitializeLocalsInputOffset;
if (loclOffset != uint.MaxValue)
InsertLabel(loclOffset, ExportDirective.GetInitializeLocalsInputLabel(labelPrefix));
var contOffset = markupTypeSchema.InitializeContentOffset;
if (contOffset != uint.MaxValue)
InsertLabel(contOffset, ExportDirective.GetInitializeContentLabel(labelPrefix));
if (markupTypeSchema.InitialEvaluateOffsets != null)
+2 -1
View File
@@ -10,7 +10,7 @@ public class ObjectSection
{
readonly IEnumerable<IBodyItem> _body;
readonly MarkupLoadResult _loadResult;
readonly Dictionary<string, uint> _labelOffsetMap = new();
Dictionary<string, uint> _labelOffsetMap;
public ObjectSection(IEnumerable<IBodyItem> body, MarkupLoadResult loadResult)
{
@@ -28,6 +28,7 @@ public class ObjectSection
public ByteCodeReader Encode()
{
ByteCodeWriter writer = new();
_labelOffsetMap = new();
foreach (var bodyItem in _body)
{