Skip to content

Commit

Permalink
static GMS2_3 for optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
Jacky720 committed Feb 23, 2023
1 parent 76bbafc commit 86ddbaf
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 34 deletions.
46 changes: 23 additions & 23 deletions UndertaleModLib/Compiler/AssemblyWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public List<UndertaleInstruction> Finish()
for (int i = 1; i < locals.Locals.Count; i++)
{
string localName = locals.Locals[i].Name.Content;
if (compileContext.GMS2_3 != true)
if (CompileContext.GMS2_3 != true)
locals.Locals[i].Index = (uint)i;
if (!compileContext.LocalVars.ContainsKey(localName))
{
Expand All @@ -142,7 +142,7 @@ bool hasLocal(string name)
string name = l.Key;
if (!hasLocal(name))
{
if (variables != null && compileContext?.GMS2_3 == true)
if (variables != null && CompileContext.GMS2_3 == true)
{
UndertaleVariable def = variables.DefineLocal(compileContext.OriginalReferencedLocalVars, 0, name, compileContext.Data.Strings, compileContext.Data);
if (def != null)
Expand Down Expand Up @@ -192,7 +192,7 @@ bool hasLocal(string name)

if (patch.VarType == VariableType.Normal)
patch.Target.TypeInst = InstanceType.Local;
else if (compileContext.GMS2_3)
else if (CompileContext.GMS2_3)
patch.InstType = InstanceType.Self;
}
}
Expand All @@ -217,7 +217,7 @@ bool hasLocal(string name)
// 2.3 variable fix
// Definitely needs at least some change when ++/-- support is added,
// since that does use instance type global
if (compileContext.GMS2_3 &&
if (CompileContext.GMS2_3 &&
patch.VarType == VariableType.Array &&
realInstType == InstanceType.Global)
realInstType = InstanceType.Self;
Expand Down Expand Up @@ -252,7 +252,7 @@ bool hasLocal(string name)
{
patch.Target.ArgumentsCount = (ushort)patch.ArgCount;
def = compileContext.Data.Functions.ByName(patch.Name);
if (compileContext.GMS2_3)
if (CompileContext.GMS2_3)
{
if (def != null && def.Autogenerated)
def = null;
Expand Down Expand Up @@ -870,7 +870,7 @@ private static void AssembleStatement(CodeWriter cw, Parser.Statement s, int rem
Patch endPatch = Patch.Start();
Patch popEnvPatch = Patch.Start();
// Hacky override for @@Other@@ and @@This@@ usage- will likely expand to whatever other cases it turns out the compiler uses.
if (cw.compileContext.GMS2_3 &&
if (CompileContext.GMS2_3 &&
s.Children[0].Kind == Parser.Statement.StatementKind.ExprConstant &&
((InstanceType)s.Children[0].Constant.valueNumber).In(InstanceType.Other, InstanceType.Self))
{
Expand All @@ -887,7 +887,7 @@ private static void AssembleStatement(CodeWriter cw, Parser.Statement s, int rem
var type = cw.typeStack.Pop();
if (type != DataType.Int32)
{
if (cw.compileContext.GMS2_3 && type == DataType.Variable)
if (CompileContext.GMS2_3 && type == DataType.Variable)
cw.Emit(Opcode.PushI, DataType.Int16).Value = (short)-9; // stacktop conversion
else
cw.Emit(Opcode.Conv, type, DataType.Int32);
Expand Down Expand Up @@ -1020,7 +1020,7 @@ private static void AssembleStatement(CodeWriter cw, Parser.Statement s, int rem
// returns and it's necessary to preserve 1:1 compilation
// But this workaround causes issue https://github.com/krzys-h/UndertaleModTool/issues/900
// So it would be fixed by cutting the "remaining" check here and removing the extra from decompilation.
if (!(cw.compileContext.GMS2_3 && remaining == 1))
if (!(CompileContext.GMS2_3 && remaining == 1))
AssembleExit(cw);
}
break;
Expand Down Expand Up @@ -1659,14 +1659,14 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
}

// Special array access- instance type needs to be pushed beforehand
if (cw.compileContext.GMS2_3 && (cw.compileContext.BuiltInList.GlobalArray.ContainsKey(e.Children[0].Text) || cw.compileContext.BuiltInList.GlobalNotArray.ContainsKey(e.Children[0].Text)))
if (CompileContext.GMS2_3 && (cw.compileContext.BuiltInList.GlobalArray.ContainsKey(e.Children[0].Text) || cw.compileContext.BuiltInList.GlobalNotArray.ContainsKey(e.Children[0].Text)))
cw.Emit(Opcode.PushI, DataType.Int16).Value = (short)(e.Children[0].Text == "argument" ? InstanceType.Arg : InstanceType.Builtin); // hack x2
else
cw.Emit(Opcode.PushI, DataType.Int16).Value = (short)e.Children[0].ID;
// Pushing array (incl. 2D) but not popping
AssembleArrayPush(cw, e.Children[0], !duplicate);

if (cw.compileContext.GMS2_3 && e.Children[0].Children.Count > 2)
if (CompileContext.GMS2_3 && e.Children[0].Children.Count > 2)
{
for (int i = 2; i < e.Children[0].Children.Count; i++)
{
Expand All @@ -1676,7 +1676,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
}
if (duplicate)
{
if (cw.compileContext.GMS2_3 && e.Children[0].Children.Count != 1)
if (CompileContext.GMS2_3 && e.Children[0].Children.Count != 1)
{
cw.Emit(Opcode.Dup, DataType.Int32).Extra = 4;
cw.Emit(Opcode.Break, DataType.Int16).Value = (short)-8; // savearef
Expand All @@ -1689,7 +1689,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
cw.Emit(Opcode.Dup, DataType.Int32).Extra = 1;
}
}
if (cw.compileContext.GMS2_3 && e.Children[0].Children.Count > 1)
if (CompileContext.GMS2_3 && e.Children[0].Children.Count > 1)
{
cw.Emit(Opcode.Break, DataType.Int16).Value = (short)-2; // pushaf
}
Expand Down Expand Up @@ -1717,7 +1717,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
case -1:
if (cw.compileContext.BuiltInList.GlobalArray.ContainsKey(name) || cw.compileContext.BuiltInList.GlobalNotArray.ContainsKey(name))
{
if (cw.compileContext.GMS2_3 &&
if (CompileContext.GMS2_3 &&
name.In(
"argument0", "argument1", "argument2", "argument3",
"argument4", "argument5", "argument6", "argument7",
Expand All @@ -1740,7 +1740,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
{
Target = cw.EmitRef(useNoSpecificType ? Opcode.Push : Opcode.PushBltn, DataType.Variable),
Name = name,
InstType = (cw.compileContext.GMS2_3 && !useNoSpecificType) ? InstanceType.Builtin : InstanceType.Self,
InstType = (CompileContext.GMS2_3 && !useNoSpecificType) ? InstanceType.Builtin : InstanceType.Self,
VarType = VariableType.Normal
});
}
Expand Down Expand Up @@ -1789,7 +1789,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
else
{
AssembleExpression(cw, e.Children[0]);
if (cw.compileContext.GMS2_3 && cw.typeStack.Peek() == DataType.Variable)
if (CompileContext.GMS2_3 && cw.typeStack.Peek() == DataType.Variable)
{
cw.typeStack.Pop();
cw.Emit(Opcode.PushI, DataType.Int16).Value = (short)-9; // stacktop conversion
Expand Down Expand Up @@ -1831,7 +1831,7 @@ private static void AssembleVariablePush(CodeWriter cw, Parser.Statement e, out
{
if (duplicate && next + 1 >= e.Children.Count)
{
cw.Emit(Opcode.Dup, DataType.Int32).Extra = (byte)(cw.compileContext.GMS2_3 ? 4 : 0);
cw.Emit(Opcode.Dup, DataType.Int32).Extra = (byte)(CompileContext.GMS2_3 ? 4 : 0);
}
cw.varPatches.Add(new VariablePatch()
{
Expand Down Expand Up @@ -1895,7 +1895,7 @@ private static void AssembleArrayPush(CodeWriter cw, Parser.Statement a, bool ar
// 2D index
if (a.Children.Count != 1)
{
if (!cw.compileContext.GMS2_3)
if (!CompileContext.GMS2_3)
{
// These instructions are hardcoded. Honestly it seems pretty
// inefficient because these could be easily combined into
Expand Down Expand Up @@ -1930,7 +1930,7 @@ private static void AssembleArrayPush(CodeWriter cw, Parser.Statement a, bool ar
cw.typeStack.Push(DataType.Int32);
}

if (!cw.compileContext.GMS2_3)
if (!CompileContext.GMS2_3)
{
cw.Emit(Opcode.Break, DataType.Int16).Value = (short)-1; // chkindex
cw.Emit(Opcode.Add, DataType.Int32, DataType.Int32);
Expand Down Expand Up @@ -1968,7 +1968,7 @@ private static void AssembleStoreVariable(CodeWriter cw, Parser.Statement s, Dat
if (!skip)
{
// Convert to variable in 2.3
if (cw.compileContext.GMS2_3 && typeToStore != DataType.Variable)
if (CompileContext.GMS2_3 && typeToStore != DataType.Variable)
{
cw.Emit(Opcode.Conv, typeToStore, DataType.Variable);
typeToStore = DataType.Variable;
Expand All @@ -1977,7 +1977,7 @@ private static void AssembleStoreVariable(CodeWriter cw, Parser.Statement s, Dat
AssembleArrayPush(cw, s.Children[0]);
}

if (cw.compileContext.GMS2_3 && s.Children[0].Children.Count != 1)
if (CompileContext.GMS2_3 && s.Children[0].Children.Count != 1)
{
if (duplicate)
{
Expand Down Expand Up @@ -2013,7 +2013,7 @@ private static void AssembleStoreVariable(CodeWriter cw, Parser.Statement s, Dat
int id = s.Children[0].ID;
if (id >= 100000)
id -= 100000;
if (cw.compileContext.GMS2_3 && (cw.compileContext.BuiltInList.GlobalArray.ContainsKey(s.Children[0].Text) || cw.compileContext.BuiltInList.GlobalNotArray.ContainsKey(s.Children[0].Text)))
if (CompileContext.GMS2_3 && (cw.compileContext.BuiltInList.GlobalArray.ContainsKey(s.Children[0].Text) || cw.compileContext.BuiltInList.GlobalNotArray.ContainsKey(s.Children[0].Text)))
{
if (s.Children[0].Text.In(
"argument0", "argument1", "argument2", "argument3",
Expand Down Expand Up @@ -2056,13 +2056,13 @@ private static void AssembleStoreVariable(CodeWriter cw, Parser.Statement s, Dat
if (!skip)
{
// Convert to variable in 2.3
if (cw.compileContext.GMS2_3 && typeToStore != DataType.Variable && s.Children.Last().Children.Count != 0)
if (CompileContext.GMS2_3 && typeToStore != DataType.Variable && s.Children.Last().Children.Count != 0)
{
cw.Emit(Opcode.Conv, typeToStore, DataType.Variable);
typeToStore = DataType.Variable;
}
AssembleExpression(cw, s.Children[0]);
if (cw.compileContext.GMS2_3 && cw.typeStack.Peek() == DataType.Variable)
if (CompileContext.GMS2_3 && cw.typeStack.Peek() == DataType.Variable)
{
cw.typeStack.Pop();
cw.Emit(Opcode.PushI, DataType.Int16).Value = (short)-9; // stacktop conversion
Expand Down
5 changes: 1 addition & 4 deletions UndertaleModLib/Compiler/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class CompileContext
public Dictionary<string, VariableInfo> userDefinedVariables = new Dictionary<string, VariableInfo>();
public bool ensureFunctionsDefined = true;
public bool ensureVariablesDefined = true;
public bool GMS2_3;
public static bool GMS2_3;
public int LastCompiledArgumentCount = 0;
public Dictionary<string, string> LocalVars = new Dictionary<string, string>();
public Dictionary<string, string> GlobalVars = new Dictionary<string, string>();
Expand All @@ -35,9 +35,6 @@ public class CompileContext
public CompileContext(UndertaleData data, UndertaleCode oldCode)
{
Data = data;
GMS2_3 = Data.IsVersionAtLeast(2, 3); // IsVersionAtLeast is relatively expensive, only do it once
// actually that might still be rather slow on batch edits
// but who imports 100 scripts at once?
OriginalCode = oldCode;
OriginalReferencedLocalVars = OriginalCode?.FindReferencedLocalVars();
}
Expand Down
2 changes: 1 addition & 1 deletion UndertaleModLib/Compiler/Lexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ private static Token ReadIdentifier(CodeReader cr)
"return" => new Token(Token.TokenKind.KeywordReturn, cr.GetPositionInfo(index)),
"default" => new Token(Token.TokenKind.KeywordDefault, cr.GetPositionInfo(index)),
"struct" => new Token(Token.TokenKind.KeywordStruct, cr.GetPositionInfo(index)),
"function" when cr.compileContext.GMS2_3 => new Token(Token.TokenKind.KeywordFunction, cr.GetPositionInfo(index)),
"function" when CompileContext.GMS2_3 => new Token(Token.TokenKind.KeywordFunction, cr.GetPositionInfo(index)),
"for" => new Token(Token.TokenKind.KeywordFor, cr.GetPositionInfo(index)),
"case" => new Token(Token.TokenKind.KeywordCase, cr.GetPositionInfo(index)),
"switch" => new Token(Token.TokenKind.KeywordSwitch, cr.GetPositionInfo(index)),
Expand Down
11 changes: 5 additions & 6 deletions UndertaleModLib/Decompiler/Decompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,12 @@ public class DecompileContext
public GlobalDecompileContext GlobalContext;
public UndertaleCode TargetCode;
public UndertaleGameObject Object;
public bool GMS2_3;
public static bool GMS2_3;

public DecompileContext(GlobalDecompileContext globalContext, UndertaleCode code, bool computeObject = true)
{
GlobalContext = globalContext;
TargetCode = code;
GMS2_3 = globalContext.Data.IsVersionAtLeast(2, 3); // IsVersionAtLeast is relatively expensive, only do it once

if (code.ParentEntry != null)
throw new InvalidOperationException("This code block represents a function nested inside " + code.ParentEntry.Name + " - decompile that instead");
Expand Down Expand Up @@ -1080,7 +1079,7 @@ public override string ToString(DecompileContext context)
{
if (AssetTypeResolver.return_types.ContainsKey(context.TargetCode.Name.Content))
Value.DoTypePropagation(context, AssetTypeResolver.return_types[context.TargetCode.Name.Content]);
if (context.GlobalContext.Data != null && !context.GMS2_3)
if (context.GlobalContext.Data != null && !DecompileContext.GMS2_3)
{
// We might be decompiling a legacy script - resolve it's name
UndertaleScript script = context.GlobalContext.Data.Scripts.FirstOrDefault(x => x.Code == context.TargetCode);
Expand Down Expand Up @@ -1774,7 +1773,7 @@ public override string ToString(DecompileContext context)
string name = Var.Name.Content;
if (ArrayIndices != null)
{
if (context?.GMS2_3 == true)
if (DecompileContext.GMS2_3 == true)
{
if (name == "argument" && context.DecompilingStruct && context.ArgumentReplacements != null && ArrayIndices.Count == 1)
{
Expand Down Expand Up @@ -2124,7 +2123,7 @@ internal static void DecompileFromBlock(DecompileContext context, Dictionary<uin
break;

case UndertaleInstruction.Opcode.PushEnv:
if (context.GMS2_3 == true)
if (DecompileContext.GMS2_3 == true)
{
Expression expr = stack.Pop();

Expand Down Expand Up @@ -2451,7 +2450,7 @@ static string FindActualNameForAnonymousCodeObject(DecompileContext context, Und

case UndertaleInstruction.Opcode.Break:
// GMS 2.3 sub-opcodes
if (context.GMS2_3 == true)
if (DecompileContext.GMS2_3 == true)
{
switch ((short)instr.Value)
{
Expand Down
Loading

0 comments on commit 86ddbaf

Please sign in to comment.