public ILBlock Build(ILBlock method, Dictionary <string, ILVariable> locals, ErrorContext error) { if (method == null) { throw new ArgumentNullException("method"); } if (error == null) { throw new ArgumentNullException("error"); } if (locals == null) { throw new ArgumentNullException("locals"); } this.error = error; this.locals = locals; error.CheckDebugThenSave(method, "raw.txt", true); // Not sure I need this pass now // WE doo now, This converts popenv to either breaks or branchs. This is needed // as if you return from a pushenv, a popenv break is called FixAllPushesAndPopenv(method.Body); // makes sure all pushes have no operands and are all expressions for latter matches Optimize.RemoveRedundantCode(method); foreach (var block in method.GetSelfAndChildrenRecursive <ILBlock>()) { Optimize.SplitToBasicBlocks(block, true); } error.CheckDebugThenSave(method, "basic_blocks.txt"); bool modified = false; bool debug_once = true; foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>()) { do { modified = false; do // Does all the internal things to a blocks for other passes to be easyer { modified = false; modified |= block.RunOptimization(MatchVariablePush); // checks pushes for instance or indexs for vars modified |= block.RunOptimization(SimpleAssignments); modified |= block.RunOptimization(AssignValueTo); modified |= block.RunOptimization(ComplexAssignments); // basicly self increment, this SHOULDN'T cross block boundrys modified |= block.RunOptimization(SimplifyBranches); // Any resolved pushes are put into a branch argument modified |= block.RunOptimization(CombineCall); // Any resolved pushes are put into a branch argument modified |= block.RunOptimization(CombineExpressions); modified |= block.RunOptimization(FixTempReturnValues); } while (modified); if (Context.Debug) { if (debug_once) { error.CheckDebugThenSave(method, "basic_blocks_resolved.txt"); debug_once = false; } } // modified |= block.RunOptimization(new SimpleControlFlow(method,error).DetectSwitch); // modified |= block.RunOptimization(new SimpleControlFlow(method, error).DetectSwitchAndConvertToBranches); modified |= block.RunOptimization(new SimpleControlFlow(method, error).DetectSwitch_GenerateSwitch); modified |= block.RunOptimization(MultiDimenionArray); modified |= block.RunOptimization(Optimize.SimplifyBoolTypes); modified |= block.RunOptimization(Optimize.SimplifyLogicNot); modified |= block.RunOptimization(PushEnviromentFix); // match all with's with expressions modified |= block.RunOptimization(new SimpleControlFlow(method, error).SimplifyShortCircuit); modified |= block.RunOptimization(new SimpleControlFlow(method, error).SimplifyTernaryOperator); modified |= block.RunOptimization(new SimpleControlFlow(method, error).MatchRepeatStructure); modified |= block.RunOptimization(new SimpleControlFlow(method, error).JoinBasicBlocks); // somewhere, so bug, is leaving an empty block, I think because of switches // It screws up the flatten block check for some reason modified |= block.RunOptimization(new SimpleControlFlow(method, error).RemoveRedundentBlocks); // want to run this at the end to fix return stuff } while (modified); } error.CheckDebugThenSave(method, "before_loops.txt"); if (BeforeConditionsDebugSainityCheck(method)) { return(null); // sainity check, evething must be ready for this } foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>()) { new LoopsAndConditions(error).FindLoops(block); } error.CheckDebugThenSave(method, "before_conditions.txt"); foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>()) { new LoopsAndConditions(error).FindConditions(block); } error.CheckDebugThenSave(method, "before_flatten.txt"); FlattenBasicBlocks(method); error.CheckDebugThenSave(method, "before_gotos.txt"); Optimize.RemoveRedundantCode(method); new GotoRemoval().RemoveGotos(method); error.CheckDebugThenSave(method, "before_if.txt"); // This is cleaned up in ILSpy latter when its converted to another ast structure, but I clean it up here // cause I don't convert it and mabye not converting all bt's to bf's dosn't // FixIfStatements(method); Optimize.RemoveRedundantCode(method); new GotoRemoval().RemoveGotos(method); error.CheckDebugThenSave(method, "final.txt"); if (AfterLoopsAndConditions(method)) { return(null); // another sanity check } return(method); }