diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Symbols/SymbolTable.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Symbols/SymbolTable.cs index c526dfbe3..9f36147ca 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Symbols/SymbolTable.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Symbols/SymbolTable.cs @@ -16,7 +16,7 @@ namespace LegendaryExplorerCore.UnrealScript.Analysis.Symbols public class SymbolTable { - public class OperatorDefinitions + private class OperatorDefinitions { public readonly CaseInsensitiveDictionary> PrefixOperators = new(); public readonly CaseInsensitiveDictionary> InfixOperators = new(); @@ -49,28 +49,32 @@ public static bool IsPrimitive(VariableType vt) => private readonly OperatorDefinitions Operators; public List InFixOperatorSymbols => Operators.InFixOperatorSymbols; - private SymbolTable() + public readonly MEGame Game; + + private SymbolTable(MEGame game) { Operators = new OperatorDefinitions(); ScopeNames = new LinkedList(); Scopes = new LinkedList(); Cache = new CaseInsensitiveDictionary(); Types = new CaseInsensitiveDictionary(); + Game = game; } - private SymbolTable(LinkedList scopeNames, LinkedList scopes, CaseInsensitiveDictionary cache, CaseInsensitiveDictionary types, OperatorDefinitions ops) + private SymbolTable(LinkedList scopeNames, LinkedList scopes, CaseInsensitiveDictionary cache, CaseInsensitiveDictionary types, OperatorDefinitions ops, MEGame game) { Operators = ops; ScopeNames = scopeNames; Scopes = scopes; Cache = cache; Types = types; + Game = game; } public static SymbolTable CreateIntrinsicTable(Class objectClass, MEGame game) { const EClassFlags intrinsicClassFlags = EClassFlags.Intrinsic; - var table = new SymbolTable(); + var table = new SymbolTable(game); #region CORE @@ -883,7 +887,8 @@ public SymbolTable Clone() new LinkedList(Scopes.Select(dict => new ASTNodeDict(dict))), new CaseInsensitiveDictionary(Cache.ToDictionary(kvp => kvp.Key, kvp => new ASTNodeDict(kvp.Value))), new CaseInsensitiveDictionary(Types), - Operators); + Operators, + Game); } } diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Visitors/ClassValidationVisitor.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Visitors/ClassValidationVisitor.cs index 4db62880f..0b773a602 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Visitors/ClassValidationVisitor.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Analysis/Visitors/ClassValidationVisitor.cs @@ -643,7 +643,7 @@ public bool VisitNode(Function node) if (node.ReturnValueDeclaration is not null) { //if the return type is > 64 bytes, it can't be allocated on the stack. - node.RetValNeedsDestruction = node.ReturnValueDeclaration.Flags.Has(EPropertyFlags.NeedCtorLink) || node.ReturnType.Size > 64; + node.RetValNeedsDestruction = node.ReturnValueDeclaration.Flags.Has(EPropertyFlags.NeedCtorLink) || node.ReturnType.Size(Symbols.Game) > 64; } } return Success; diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Compiling/ByteCodeCompilerVisitor.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Compiling/ByteCodeCompilerVisitor.cs index 9e0d0c732..8bf0520f9 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Compiling/ByteCodeCompilerVisitor.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Compiling/ByteCodeCompilerVisitor.cs @@ -493,7 +493,7 @@ public bool VisitNode(Goto node) public bool VisitNode(ExpressionOnlyStatement node) { - if (GetAffector(node.Value) is Function func && func.RetValNeedsDestruction) + if (GetAffector(node.Value) is {RetValNeedsDestruction: true} func) { WriteOpCode(OpCodes.EatReturnValue); WriteObjectRef(ResolveReturnValue(func)); @@ -1389,7 +1389,7 @@ private void EmitVariableSize(Expression expr) { null => 0, { PropertyType: EPropertyType.StringRef } => 0, - _ => (byte)exprType.Size + _ => (byte)exprType.Size(Game) }); return; } diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/StaticArrayType.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/StaticArrayType.cs index 38804991e..0c5b4b15c 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/StaticArrayType.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/StaticArrayType.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using LegendaryExplorerCore.Packages; using LegendaryExplorerCore.UnrealScript.Analysis.Visitors; using LegendaryExplorerCore.UnrealScript.Utilities; @@ -30,7 +31,7 @@ public override IEnumerable ChildNodes } } - public override int Size => (ElementType?.Size ?? 0) * Length; + public override int Size(MEGame game) => (ElementType?.Size(game) ?? 0) * Length; public bool Equals(StaticArrayType other) { diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/Struct.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/Struct.cs index cbda79551..543117222 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/Struct.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/Struct.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using LegendaryExplorerCore.Gammtek.Extensions; +using LegendaryExplorerCore.Packages; using LegendaryExplorerCore.Unreal.BinaryConverters; using LegendaryExplorerCore.UnrealScript.Analysis.Visitors; using LegendaryExplorerCore.UnrealScript.Utilities; @@ -74,16 +75,13 @@ public string GetInheritanceString() return str; } - public override int Size + public override int Size(MEGame game) { - get - { - (int structSize, _) = GetSizeAndAlign(); - return structSize; - } + (int structSize, _) = GetSizeAndAlign(game); + return structSize; } - private (int structSize, int structAlign) GetSizeAndAlign() + private (int structSize, int structAlign) GetSizeAndAlign(MEGame game) { int structSize = 0; int structAlign = 4; @@ -92,7 +90,7 @@ public override int Size foreach (VariableDeclaration varDecl in VariableDeclarations) { VariableType cur = varDecl.VarType; - int varSize = cur.Size; + int varSize = cur.Size(game); int varAlign = 4; if (cur is StaticArrayType staticArrayType) { @@ -121,17 +119,37 @@ public override int Size } else if (cur.PropertyType == EPropertyType.String) { - varSize = 12 * varDecl.ArrayLength; //TODO: verify this + if (game.IsLEGame()) + { + varSize = 16 * varDecl.ArrayLength; + varAlign = 8; + } + else + { + varSize = 12 * varDecl.ArrayLength; //TODO: verify this + } } else if (cur is DynamicArrayType) { - varSize = 12; //TODO: verify this + if (game.IsLEGame()) + { + varSize = 16; + varAlign = 8; + } + else + { + varSize = 12; + } } else if (cur is Struct curStruct) { - (varSize, varAlign) = curStruct.GetSizeAndAlign(); + (varSize, varAlign) = curStruct.GetSizeAndAlign(game); varSize *= varDecl.ArrayLength; } + else if (cur.PropertyType is EPropertyType.Object or EPropertyType.Delegate && game.IsLEGame()) + { + varAlign = 8; + } structSize = structSize.Align(varAlign) + varSize; diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableDeclaration.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableDeclaration.cs index 039e51802..e78af48cc 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableDeclaration.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableDeclaration.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using LegendaryExplorerCore.Packages; using LegendaryExplorerCore.Unreal; using LegendaryExplorerCore.UnrealScript.Analysis.Visitors; using LegendaryExplorerCore.UnrealScript.Utilities; @@ -41,7 +42,7 @@ public override IEnumerable ChildNodes } } - public int GetSize() => VarType?.Size ?? 0; + public int GetSize(MEGame game) => VarType?.Size(game) ?? 0; public string FilePath { get; init; } public int UIndex { get; set; } diff --git a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableType.cs b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableType.cs index 99e645243..fd71ca2ed 100644 --- a/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableType.cs +++ b/LegendaryExplorer/LegendaryExplorerCore/UnrealScript/Language/Tree/VariableType.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using LegendaryExplorerCore.Packages; using LegendaryExplorerCore.UnrealScript.Analysis.Visitors; using LegendaryExplorerCore.UnrealScript.Utilities; @@ -13,17 +14,17 @@ public class VariableType : ASTNode, IHasFileReference public EPropertyType PropertyType; - public virtual int Size => PropertyType switch + public virtual int Size(MEGame game) => PropertyType switch { EPropertyType.None => 0, EPropertyType.Byte => 1, EPropertyType.Int => 4, EPropertyType.Bool => 4, EPropertyType.Float => 4, - EPropertyType.Object => 4, + EPropertyType.Object => game.IsLEGame() ? 8 : 4, EPropertyType.Name => 8, - EPropertyType.Delegate => 12, - EPropertyType.Interface => 8, + EPropertyType.Delegate => game.IsLEGame() ? 16 : 12, + EPropertyType.Interface => game.IsLEGame() ? 16 : 8, EPropertyType.Struct => 0, EPropertyType.Vector => 12, EPropertyType.Rotator => 12, diff --git a/SharedProjects/Piccolo/Piccolo.csproj b/SharedProjects/Piccolo/Piccolo.csproj index 8f61c0cad..e35182ff6 100644 --- a/SharedProjects/Piccolo/Piccolo.csproj +++ b/SharedProjects/Piccolo/Piccolo.csproj @@ -1,7 +1,6 @@  - - net48;net5.0-windows + net5.0-windows Library 9.0 false