bool BeforeConditionsDebugSainityCheck(ILBlock method) { HashSet <ILBasicBlock> badblocks = new HashSet <ILBasicBlock>(); Dictionary <GMCode, int> badCodes = new Dictionary <GMCode, int>(); foreach (ILBlock block in method.GetSelfAndChildrenRecursive <ILBlock>()) { foreach (ILBasicBlock bb in block.GetSelfAndChildrenRecursive <ILBasicBlock>()) { foreach (ILExpression expr in bb.GetSelfAndChildrenRecursive <ILExpression>()) { if (expr.Operand is UnresolvedVar) { if (!badCodes.ContainsKey(expr.Code)) { badCodes[expr.Code] = 0; } badCodes[expr.Code]++; badblocks.Add(bb); } else if (expr.Code == GMCode.Dup || expr.Code == GMCode.Push || expr.Code == GMCode.Popz || expr.Code == GMCode.CallUnresolved) { if (!badCodes.ContainsKey(expr.Code)) { badCodes[expr.Code] = 0; } badCodes[expr.Code]++; badblocks.Add(bb); } else if ((expr.Code == GMCode.Bt || expr.Code == GMCode.Bf) && expr.Arguments.Count == 0) { if (!badCodes.ContainsKey(expr.Code)) { badCodes[expr.Code] = 0; } badCodes[expr.Code]++; badblocks.Add(bb); } } } } if (badblocks.Count > 0) { ControlFlowLabelMap map = new ControlFlowLabelMap(method, error); ILBlock badmethod = new ILBlock(); error.DebugSave(method, "bad_block_dump.txt"); // HashSet<ILBasicBlock> callies = new HashSet<ILBasicBlock>(); try { foreach (var bb in badblocks.ToList()) { badblocks.UnionWith(bb.GetChildren() .OfType <ILExpression>() .Where(x => x.Operand is ILLabel) .Select(x => x.Operand as ILLabel) .Select(x => map.LabelToBasicBlock(x))); var p = map.LabelToParrents(bb.EntryLabel()); p.Add(bb.GotoLabel()); // Debug.Assert(p.Count == 1); badblocks.UnionWith(p.Select(x => map.LabelToBasicBlock(x))); // badblocks.Add(map.LabelToBasicBlock(p[0])); } badmethod.Body = badblocks.OrderBy(b => b.GotoLabelName()).Select(b => (ILNode)b).ToList(); } catch (Exception e) { // we cannot build a map, so just copy bad blocks error.Error("Cannot build a map of the method, probery missing Label Exception: {0}", e.Message); badmethod.Body = method.Body; } string dfilename = error.MakeDebugFileName("bad_blocks.txt"); using (StreamWriter sw = new StreamWriter(dfilename)) { sw.WriteLine("Time : {0}", DateTime.Now); sw.WriteLine("Filename: {0}", dfilename); sw.WriteLine("Code File: {0}", error.CodeName); foreach (var kp in badCodes) { sw.WriteLine("Code: \"{0}\" Count: {1}", kp.Key, kp.Value); } sw.WriteLine(); sw.WriteLine(badmethod.ToString()); } error.Message("Saved '{0}'", dfilename); error.FatalError("Before graph sanity check failed, look at bad_block_dump.txt"); return(true); } return(false); }