Skip to content

Commit

Permalink
DONE! Months of work finaly. This thing will extract all the srouce f…
Browse files Browse the repository at this point in the history
…rom Underatle 1.0 and decompile it.
  • Loading branch information
WarlockD committed Apr 21, 2016
1 parent a4ca2a3 commit 12629a2
Show file tree
Hide file tree
Showing 8 changed files with 190 additions and 266 deletions.
385 changes: 161 additions & 224 deletions betteribttest/Dissasembler/BuildFullAst.cs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions betteribttest/Dissasembler/GotoRemoval.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ public void RemoveGotos(ILBlock method)

public static void RemoveRedundantCode(ILBlock method)
{
// Remove dead lables and nops
// Remove dead lables and nops and any popzs left
HashSet<ILLabel> liveLabels = new HashSet<ILLabel>(method.GetSelfAndChildrenRecursive<ILExpression>(e => e.IsBranch()).SelectMany(e => e.GetBranchTargets()));
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>())
{
block.Body = block.Body.Where(n => !n.Match(GMCode.BadOp) && !(n is ILLabel && !liveLabels.Contains((ILLabel)n))).ToList();
block.Body = block.Body.Where(n => !n.Match(GMCode.BadOp) && !n.Match(GMCode.Popz) && !(n is ILLabel && !liveLabels.Contains((ILLabel)n))).ToList();
}

// Remove redundant continue
Expand Down Expand Up @@ -101,7 +101,7 @@ public static void RemoveRedundantCode(ILBlock method)
}

}

// Remove redundant return at the end of method
if (method.Body.Count > 0 && (method.Body.Last().Match(GMCode.Ret)|| method.Body.Last().Match(GMCode.Exit) )&& ((ILExpression)method.Body.Last()).Arguments.Count == 0)
{
Expand Down
3 changes: 2 additions & 1 deletion betteribttest/Dissasembler/LoopAndConditions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ List<ILNode> FindLoops(HashSet<ControlFlowNode> scope, ControlFlowNode entryPoin
ILLabel trueLabel;
ILLabel falseLabel;
// It has to be just brtrue - any preceding code would introduce goto
if (basicBlock.MatchSingleAndBr(GMCode.Bf, out falseLabel, out condExpr, out trueLabel) ||
if (basicBlock.MatchSingleAndBr(GMCode.Bf, out falseLabel, out condExpr, out trueLabel) ||
// basicBlock.MatchSingleAndBr(GMCode.Bt, out trueLabel, out condExpr, out falseLabel) ||
basicBlock.MatchSingleAndBr(GMCode.Pushenv, out falseLabel, out condExpr, out trueLabel)) // built it the same way
{
bool ispushEnv = (basicBlock.Body.ElementAt(basicBlock.Body.Count - 2) as ILExpression).Code == GMCode.Pushenv;
Expand Down
1 change: 1 addition & 0 deletions betteribttest/Dissasembler/Optimize.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ public static void RemoveRedundantCode(ILBlock method)
else if (body[i].Match(GMCode.BadOp))
{
// Ignore nop

}
else {
ILLabel label = body[i] as ILLabel;
Expand Down
7 changes: 5 additions & 2 deletions betteribttest/Dissasembler/PaternMatching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,11 @@ 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;
if(expr.Operand is T)
{
operand = (T)expr.Operand;
return true;
}
}
operand = default(T);
return false;
Expand Down
46 changes: 11 additions & 35 deletions betteribttest/FlowAnalysis/StackAnalysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,15 +377,14 @@ public ILBlock Build(SortedList<int, Instruction> code, bool optimize, GMContext

ILBlock method = new ILBlock();
method.Body = ast;
method.DebugSave("raw_body.txt");
if (context.Debug) method.DebugSave("raw_body.txt");
betteribttest.Dissasembler.Optimize.RemoveRedundantCode(method);
foreach(var block in method.GetSelfAndChildrenRecursive<ILBlock>())
Optimize.SplitToBasicBlocks(block);
#if DEBUG
// DebugBasicBlocks(method);
method.DebugSave("basic_blocks.txt");
if(context.Debug) method.DebugSave("basic_blocks.txt");

new BuildFullAst(method, context).ProcessAllExpressions(method);
method.DebugSave("basic_blocks2.txt");
if(context.Debug) method.DebugSave("basic_blocks2.txt");
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>())
{
bool modified;
Expand All @@ -401,52 +400,29 @@ public ILBlock Build(SortedList<int, Instruction> code, bool optimize, GMContext
modified |= block.RunOptimization(Optimize.SimplifyLogicNot);
} while (modified);
}
method.DebugSave("basic_blocks3.txt");

#else
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>())
{
bool modified;
do
{
modified = false;

// modified |= block.RunOptimization(new SimpleControlFlow(method, context).SwitchDetection);
modified |= block.RunOptimization(ProcessExpressions);
modified |= block.RunOptimization(new SimpleControlFlow(method, context).PushEnviromentFix);
modified |= block.RunOptimization(new SimpleControlFlow(method, context).SimplifyShortCircuit);
modified |= block.RunOptimization(new SimpleControlFlow(method, context).SimplifyTernaryOperator);


modified |= block.RunOptimization(new SimpleControlFlow(method, context).JoinBasicBlocks);
modified |= block.RunOptimization(Optimize.SimplifyLogicNot);
} while (modified);
}
#endif
method.DebugSave("before_loop.txt");
if (context.Debug) method.DebugSave("before_loop.txt");
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>())
{
new LoopsAndConditions().FindLoops(block);
}
method.DebugSave("before_conditions.txt");
if (context.Debug) method.DebugSave("before_conditions.txt");
foreach (ILBlock block in method.GetSelfAndChildrenRecursive<ILBlock>())
{
new LoopsAndConditions().FindConditions(block);
}

FlattenBasicBlocks(method);
method.DebugSave("before_gotos.txt");
if (context.Debug) method.DebugSave("before_gotos.txt");
Optimize.RemoveRedundantCode(method);
new GotoRemoval().RemoveGotos(method);
Optimize.RemoveRedundantCode(method);
// Debug.Assert(context.CurrentScript != "gml_Script_scr_phonename");
new GotoRemoval().RemoveGotos(method);
//List<ByteCode> body = StackAnalysis(method);
GotoRemoval.RemoveRedundantCode(method);

// We don't have a fancy
new GotoRemoval().RemoveGotos(method);

GotoRemoval.RemoveRedundantCode(method);
new GotoRemoval().RemoveGotos(method);

if (context.Debug) method.DebugSave("final.cpp");
return method;

}
Expand Down
1 change: 1 addition & 0 deletions betteribttest/GMContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class GMContext
public List<string> InstanceList;
public List<string> scriptList;
public string CurrentScript = null;
public bool Debug = false;
public string LookupString(int index, bool escape = false)
{
index &= 0x1FFFFF;
Expand Down
7 changes: 6 additions & 1 deletion betteribttest/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,10 @@ static void Main(string[] args)
InstanceList = cr.objList.Select(x => x.Name).ToList();
scriptList = cr.scriptIndex.Select(x => x.script_name).ToList();
FunctionReplacement();
GMContext context = new GMContext() { cr = cr, InstanceList = InstanceList, scriptList = scriptList };
GMContext context = new GMContext() { cr = cr, InstanceList = InstanceList, scriptList = scriptList, Debug = false };
bool doAsm = false;
bool all = false;

string toSearch = null;
int pos = 1;
while(pos < args.Length)
Expand All @@ -296,6 +297,10 @@ static void Main(string[] args)
toSearch = args.ElementAtOrDefault(pos);
pos++;
break;
case "-debug":
pos++;
context.Debug = true;
break;
case "-all":
all = true;
pos++;
Expand Down

0 comments on commit 12629a2

Please sign in to comment.