public DecompileCache(ProjectFile pf) { Types = new AssetResolverTypes(pf); GlobalFunctionNames = new Dictionary <GMFunctionEntry, string>(); if (pf.DataHandle.VersionInfo.IsNumberAtLeast(2, 3)) { // Find all function names in global scripts GMChunkCODE code = pf.DataHandle.GetChunk <GMChunkCODE>(); Parallel.ForEach(pf.DataHandle.GetChunk <GMChunkGLOB>().List, scr => { GMCode entry = code.List[scr]; // Find fragments List <Fragment> fragments = Fragments.FindAndProcess(entry, false); // Find blocks in the main fragment that come after another fagment foreach (Block b in fragments[^ 1].Blocks.List) { if (b.AfterFragment && b.Instructions.Count > 2 && b.Instructions[0].Kind == GMCode.Bytecode.Instruction.Opcode.Push && b.Instructions[0].Type1 == GMCode.Bytecode.Instruction.DataType.Int32 && b.Instructions[0].Value == null) { string name = ASTBuilder.GetNameAfterFragment(b); if (name != null) { GMFunctionEntry func = b.Instructions[0].Function.Target; lock (GlobalFunctionNames) GlobalFunctionNames[func] = name; } } } });
ILExpression MakeLeftAssociativeShortCircuit(GMCode code, ILExpression left, ILExpression right) { // Assuming that the inputs are already left associative if (right.Match(code)) { // Find the leftmost logical expression ILExpression current = right; while (current.Arguments[0].Match(code)) { current = current.Arguments[0]; } current.Arguments[0] = new ILExpression(code, null, left, current.Arguments[0]) { InferredType = GM_Type.Bool }; return(right); } else { return(new ILExpression(code, null, left, right) { InferredType = GM_Type.Bool }); } }
public static uint toUInt(this GMCode t, GM_Type type) { byte b = (byte)t; byte bt = (byte)type; return((uint)(b << 24) | (uint)(bt << 16)); }
public static bool MatchLastCount <T>(this IList <T> ast, GMCode code, int count, out List <ILExpression> match) where T : ILNode { do { if (ast.Count == 0 && ast.Count < count) { break; } int i = ast.Count - 1, j = 0; List <ILExpression> ret = new List <ILExpression>(); for (; i >= 0 && j < count; i--, j++) { ILExpression test; if (ast.ElementAtOrDefault(i).Match(code, out test)) { ret.Add(test); } else { break; } } if (j != count) { break; // bad match or not enough match } match = ret; return(true); } while (false); match = default(List <ILExpression>); return(false); }
public static bool isExpression(this GMCode i) { switch (i) { case GMCode.LogicAnd: case GMCode.LogicOr: case GMCode.Neg: case GMCode.Not: case GMCode.Add: case GMCode.Sub: case GMCode.Mul: case GMCode.Div: case GMCode.Mod: case GMCode.And: case GMCode.Or: case GMCode.Xor: case GMCode.Sal: case GMCode.Seq: case GMCode.Sge: case GMCode.Sgt: case GMCode.Sle: case GMCode.Slt: case GMCode.Sne: return(true); default: return(false); } }
public static bool MatchLastAt(this ILBasicBlock bb, int back, GMCode code) { if (bb.Body.ElementAtOrDefault(bb.Body.Count - back).Match(code)) { return(true); } return(false); }
public static bool MatchAt(this ILBasicBlock bb, int index, GMCode code) { if (bb.Body.ElementAtOrDefault(index).Match(code)) { return(true); } return(false); }
protected ILExpression CreateLabeledExpression(GMCode code) { int absolute = GMCodeUtil.getBranchOffset(CurrentRaw) + CurrentPC; ILExpression e = new ILExpression(code, GetLabel(absolute)); e.Extra = (int)(CurrentRaw & 0xFFFF); e.ILRanges.Add(new ILRange(CurrentPC, CurrentPC)); return e; }
protected ILExpression CreateLabeledExpression(GMCode code) { int absolute = GMCodeUtil.getBranchOffset(CurrentRaw) + CurrentPC; ILExpression e = new ILExpression(code, GetLabel(absolute)); e.Extra = (int)(CurrentRaw & 0xFFFF); e.ILRanges.Add(new ILRange(CurrentPC, CurrentPC)); return(e); }
protected ILExpression CreateExpression(GMCode code, GM_Type[] types) { ILExpression e = new ILExpression(code, null); e.Types = types; e.Extra = (int)(CurrentRaw & 0xFFFF); e.AddILRange(CurrentPC); return(e); }
public static bool MatchLastAt <T>(this ILBasicBlock bb, int back, GMCode code, out T operand) { if (bb.Body.ElementAtOrDefault(bb.Body.Count - back).Match(code, out operand)) { return(true); } operand = default(T); return(false); }
public static bool MatchLastAt(this ILBasicBlock bb, int back, GMCode code, out ILExpression arg) { if (bb.Body.ElementAtOrDefault(bb.Body.Count - back).Match(code, out arg)) { return(true); } arg = default(ILExpression); return(false); }
public static bool MatchAt(this ILBasicBlock bb, int index, GMCode code, out IList <ILExpression> args) { if (bb.Body.ElementAtOrDefault(index).Match(code, out args)) { return(true); } args = default(IList <ILExpression>); return(false); }
public static bool MatchAt <T>(this ILBasicBlock bb, int index, GMCode code, out T operand) { if (bb.Body.ElementAtOrDefault(index).Match(code, out operand)) { return(true); } operand = default(T); return(false); }
public static int getOpTreeCount(this GMCode t) { int count; if (opMathOperationCount.TryGetValue(t, out count)) { return(count); } return(0); }
public static string getOpTreeString(this GMCode t) { string ret; if (opMathOperation.TryGetValue(t, out ret)) { return(ret); } return(null); }
protected ILExpression CreateExpression(GMCode code, GM_Type[] types, ILLabel operand) { Debug.Assert(operand != null); ILExpression e = new ILExpression(code, operand); e.Types = types; e.Extra = (int)(CurrentRaw & 0xFFFF); e.AddILRange(CurrentPC); return(e); }
public static bool MatchSingle <T>(this ILBasicBlock bb, GMCode code, out T operand) { if (bb.Body.Count == 2 && bb.Body[0] is ILLabel && bb.Body[1].Match(code, out operand)) { return(true); } operand = default(T); return(false); }
public static bool MatchLastAndBr(this ILBasicBlock bb, GMCode code, out ILExpression arg, out ILLabel brLabel) { if (bb.Body.ElementAtOrDefault(bb.Body.Count - 2).Match(code, out arg) && bb.Body.LastOrDefault().Match(GMCode.B, out brLabel)) { return(true); } arg = default(ILExpression); brLabel = null; return(false); }
public static bool MatchLastAndBr <T>(this ILBasicBlock bb, GMCode code, out T operand, out ILLabel brLabel) { if (bb.Body.ElementAtOrDefault(bb.Body.Count - 2).Match(code, out operand) && bb.Body.LastOrDefault().Match(GMCode.B, out brLabel)) { return(true); } operand = default(T); brLabel = null; return(false); }
public static bool Match <T>(this ILNode node, GMCode code, out T operand) { ILExpression expr = node as ILExpression; if (expr != null && expr.Code == code && expr.Arguments.Count == 0) { operand = (T)expr.Operand; return(true); } operand = default(T); return(false); }
public static bool Match <T>(this ILNode node, GMCode code, out T operand, out ILExpression arg) { IList <ILExpression> args; if (node.Match(code, out operand, out args) && args.Count == 1) { arg = args[0]; return(true); } arg = null; return(false); }
public static bool Match(this ILNode node, GMCode code, out IList <ILExpression> args) { ILExpression expr = node as ILExpression; if (expr != null && expr.Code == code && expr.Operand == null) { args = expr.Arguments; return(true); } args = null; return(false); }
public ILExpression(GMCode code, object operand, params ILExpression[] args) { if (operand is ILExpression) { throw new ArgumentException("operand"); } this.Code = code; this.Operand = operand; this.Arguments = new List <ILExpression>(args); this.ILRanges = new List <ILRange>(1); }
public static int GetPopDelta(this GMCode i) { switch (i) { case GMCode.Popenv: case GMCode.Exit: case GMCode.Conv: break; // we ignore conv case GMCode.Call: case GMCode.Push: case GMCode.Pop: case GMCode.Dup: throw new Exception("Need more info for pop"); case GMCode.Popz: case GMCode.Ret: case GMCode.Bt: case GMCode.Bf: case GMCode.Neg: case GMCode.Not: case GMCode.Pushenv: return(1); case GMCode.Add: case GMCode.Sub: case GMCode.Mul: case GMCode.Div: case GMCode.Mod: case GMCode.And: case GMCode.Or: case GMCode.Xor: case GMCode.Sal: case GMCode.Seq: case GMCode.Sge: case GMCode.Sgt: case GMCode.Sle: case GMCode.Slt: case GMCode.Sne: return(2); case GMCode.Var: case GMCode.Constant: case GMCode.B: return(0); default: throw new Exception("Unkonwn opcode"); } return(0); }
public static bool Match <T>(this ILNode node, GMCode code, out T operand, out IList <ILExpression> args) { ILExpression expr = node as ILExpression; if (expr != null && expr.Code == code) { operand = (T)expr.Operand; args = expr.Arguments; return(true); } operand = default(T); args = null; return(false); }
public static int FindLastIndexOf(this IList <ILNode> ast, GMCode code, int from) { if (ast.Count == 0 || from < 0 || from > (ast.Count - 1)) { return(-1); } for (int i = from; i >= 0; i--) { if (ast[i].Match(code)) { return(i); } } return(-1); }
public static bool MatchSingleAndBr <T>(this ILBasicBlock bb, GMCode code, out T operand, out ILLabel brLabel) { { if (bb.Body.Count == 3 && bb.Body[0] is ILLabel && bb.Body[1].Match(code, out operand) && bb.Body[2].Match(GMCode.B, out brLabel)) { return(true); } } operand = default(T); brLabel = null; return(false); }
static bool IsBranch(GMCode opcode) { switch (opcode) { case GMCode.B: case GMCode.Bf: case GMCode.Bt: case GMCode.Exit: case GMCode.Ret: return(true); default: return(false); } }
public static bool MatchSingleAndBr <T>(this ILBasicBlock bb, GMCode code, out T operand, out IList <ILExpression> args, out ILLabel brLabel) { { if (bb.Body.Count == 3 && bb.Body[0] is ILLabel && bb.Body[1].Match(code, out operand, out args) && bb.Body[2].Match(GMCode.B, out brLabel)) { return(true); } } args = default(List <ILExpression>); brLabel = default(ILLabel); operand = default(T); return(false); }
public static bool IsConditionalStatment(this GMCode code) { switch (code) { case GMCode.Seq: case GMCode.Sne: case GMCode.Sge: case GMCode.Sle: case GMCode.Sgt: case GMCode.Slt: return(true); default: return(false); } }
protected ILExpression CreatePushExpression(GMCode code, GM_Type[] types) { ILExpression e = new ILExpression(code, null); e.Types = types; e.Extra = (int)(CurrentRaw & 0xFFFF); Debug.Assert(e.ILRanges.Count == 0); e.AddILRange(CurrentPC); ILValue v = null; switch (types[0]) { case GM_Type.Var: e.Operand = BuildUnresolvedVar(r.ReadInt32()); break; case GM_Type.Short: { v = new ILValue((short)(CurrentRaw & 0xFFFF)); v.DataOffset = (int)(r.BaseStream.Position - 4); e.Arguments.Add(new ILExpression(GMCode.Constant, v)); } break; default: v = ReadConstant(r, types[0]); e.Arguments.Add(new ILExpression(GMCode.Constant, v)); break; } if (v != null) { v.DataOffset += StartingOffset ; DebugILValueOffset(v); } return e; }
protected ILExpression CreateExpression(GMCode code, GM_Type[] types, ILLabel operand) { Debug.Assert(operand != null); ILExpression e = new ILExpression(code, operand); e.Types = types; e.Extra = (int)(CurrentRaw & 0xFFFF); e.AddILRange(CurrentPC); return e; }
protected ILExpression CreateExpression(GMCode code, GM_Type[] types) { ILExpression e = new ILExpression(code, null); e.Types = types; e.Extra = (int)(CurrentRaw & 0xFFFF); e.AddILRange(CurrentPC); return e; }