Esempio n. 1
0
        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);
        }