From 6bc1880f2c2a8ebac8729b70e89a314b0cad58f5 Mon Sep 17 00:00:00 2001 From: Yoshi Askharoun Date: Mon, 12 Feb 2024 23:14:53 -0600 Subject: [PATCH] More constant operand work in assembler --- libs/MicrosoftIris | 2 +- libs/UIX.Asm/AsmMarkupLoader.cs | 28 ++++++++++++++++++++++------ libs/UIX.Asm/Lexer.Directives.cs | 5 ++++- libs/UIX.Asm/ObjectSection.cs | 22 ++++++++++++---------- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/libs/MicrosoftIris b/libs/MicrosoftIris index 23d2087..cc9c1e4 160000 --- a/libs/MicrosoftIris +++ b/libs/MicrosoftIris @@ -1 +1 @@ -Subproject commit 23d20873cf581863aa28df9da83f7ef7ecc20223 +Subproject commit cc9c1e4bb5b5630e0151609c7e0e7a18086866c1 diff --git a/libs/UIX.Asm/AsmMarkupLoader.cs b/libs/UIX.Asm/AsmMarkupLoader.cs index cf9d38b..3f77f53 100644 --- a/libs/UIX.Asm/AsmMarkupLoader.cs +++ b/libs/UIX.Asm/AsmMarkupLoader.cs @@ -20,6 +20,7 @@ internal class AsmMarkupLoader private ObjectSection _objectSection; private readonly Dictionary _importedNamespaces = new(); + private readonly Dictionary _constants = new(); private readonly HashSet _referencedNamespaces = new(); internal unsafe AsmMarkupLoader(AsmMarkupLoadResult loadResult, Resource resource) @@ -51,6 +52,8 @@ internal class AsmMarkupLoader { if (prefix == null) return MarkupSystem.UIXGlobal; + if (prefix == "me") + return _loadResult; return _importedNamespaces[prefix]; } @@ -155,7 +158,13 @@ internal class AsmMarkupLoader if (_currentValidationPass == LoadPass.Full) { - foreach (var nsImport in Program.Directives.OfType()) + foreach (var typeImport in Program.Imports.OfType()) + { + var typeSchema = ResolveTypeFromQualifiedName(typeImport.QualifiedName); + _importTables.ImportedTypes.Add(typeSchema); + } + + foreach (var nsImport in Program.Imports.OfType()) { if (!_referencedNamespaces.Contains(nsImport.Name)) ErrorManager.ReportWarning(nsImport.Line, nsImport.Column, $"Unreferenced namespace '{nsImport.Name}'"); @@ -228,20 +237,27 @@ internal class AsmMarkupLoader { var propName = attr.Name.LocalName; var prop = constantTypeSchema.FindProperty(propName); - prop.SetValue(ref constantValue, attr.Value); - } - ReportError($"'{constant.TypeName}' cannot be constructed from a string, and UIXA does not yet support XML construction.", constant); - continue; + var propConvertResult = prop.PropertyType.TypeConverter(attr.Value, stringTypeSchema, out var propValue); + if (propConvertResult.Failed) + { + ReportError($"Failed to set {constantTypeSchema.Name}.{propName}", constant); + continue; + } + + prop.SetValue(ref constantValue, propValue); + } } var mode = constantTypeSchema.SupportsBinaryEncoding ? MarkupConstantPersistMode.Binary : MarkupConstantPersistMode.FromString; - constantsTable.Add(constantTypeSchema, constantValue, mode); + var constantIndex = (ushort)constantsTable.Add(constantTypeSchema, constantValue, mode); + _constants.Add(constant.Name, constantIndex); } + _objectSection.Constants = _constants; reader = _objectSection.Encode(); UpdateExportOffsets(); } diff --git a/libs/UIX.Asm/Lexer.Directives.cs b/libs/UIX.Asm/Lexer.Directives.cs index 4837541..f8ec17e 100644 --- a/libs/UIX.Asm/Lexer.Directives.cs +++ b/libs/UIX.Asm/Lexer.Directives.cs @@ -67,7 +67,10 @@ partial class Lexer return Result.Failure(input, "Invalid constant directive", ["Expected valid XML"]); var xmlElem = System.Xml.Linq.XElement.Parse($"{xmlPartResult.Value}/>"); - QualifiedTypeName typeName = new(xmlElem.Name.NamespaceName, xmlElem.Name.LocalName); + var xmlPrefix = xmlElem.Name.NamespaceName == string.Empty + ? null : xmlElem.Name.NamespaceName; + + QualifiedTypeName typeName = new(xmlPrefix, xmlElem.Name.LocalName); var content = xmlElem.ToString(System.Xml.Linq.SaveOptions.DisableFormatting); directive = new ConstantDirective(constNameResult.Value, typeName, content) diff --git a/libs/UIX.Asm/ObjectSection.cs b/libs/UIX.Asm/ObjectSection.cs index 81332df..953aa44 100644 --- a/libs/UIX.Asm/ObjectSection.cs +++ b/libs/UIX.Asm/ObjectSection.cs @@ -8,29 +8,26 @@ namespace Microsoft.Iris.Asm; public class ObjectSection { - readonly IEnumerable _body; + readonly Program _program; readonly MarkupLoadResult _loadResult; Dictionary _labelOffsetMap; - public ObjectSection(IEnumerable body, MarkupLoadResult loadResult) + public ObjectSection(Program program, MarkupLoadResult loadResult) { - _body = body; + _program = program; _loadResult = loadResult; } - public ObjectSection(Program program, MarkupLoadResult loadResult) - : this(program.Body, loadResult) - { - } - public IReadOnlyDictionary LabelOffsetMap => _labelOffsetMap; + public IReadOnlyDictionary Constants { get; set; } + public ByteCodeReader Encode() { ByteCodeWriter writer = new(); _labelOffsetMap = new(); - foreach (var bodyItem in _body) + foreach (var bodyItem in _program.Body) { var offset = writer.DataSize; @@ -50,7 +47,12 @@ public class ObjectSection foreach (var operand in instruction.Operands) { - switch (operand.Value) + object operandValue = operand.Value; + + if (operand is OperandReference operandRef) + operandValue = Constants[operandRef.ConstantName]; + + switch (operandValue) { case OperationType opType: writer.WriteByte((byte)opType);