Ejemplo n.º 1
0
        private static void DeleteArea(ControlFlowGraph graph, FinallyProcessor.Area area
                                       )
        {
            BasicBlock start = area.start;
            BasicBlock next  = area.next;

            if (start == next)
            {
                return;
            }
            if (next == null)
            {
                // dummy exit block
                next = graph.GetLast();
            }
            // collect common exception ranges of predecessors and successors
            HashSet <BasicBlock> setCommonExceptionHandlers = new HashSet <BasicBlock>(next.GetSuccExceptions
                                                                                           ());

            foreach (BasicBlock pred in start.GetPreds())
            {
                setCommonExceptionHandlers.RetainAll(pred.GetSuccExceptions());
            }
            bool is_outside_range = false;
            HashSet <BasicBlock> setPredecessors = new HashSet <BasicBlock>(start.GetPreds());

            // replace start with next
            foreach (BasicBlock pred in setPredecessors)
            {
                pred.ReplaceSuccessor(start, next);
            }
            HashSet <BasicBlock>        setBlocks = area.sample;
            HashSet <ExceptionRangeCFG> setCommonRemovedExceptionRanges = null;

            // remove all the blocks inbetween
            foreach (BasicBlock block in setBlocks)
            {
                // artificial basic blocks (those resulted from splitting)
                // can belong to more than one area
                if (graph.GetBlocks().ContainsKey(block.id))
                {
                    if (!block.GetSuccExceptions().ContainsAll(setCommonExceptionHandlers))
                    {
                        is_outside_range = true;
                    }
                    HashSet <ExceptionRangeCFG> setRemovedExceptionRanges = new HashSet <ExceptionRangeCFG
                                                                                         >();
                    foreach (BasicBlock handler in block.GetSuccExceptions())
                    {
                        setRemovedExceptionRanges.Add(graph.GetExceptionRange(handler, block));
                    }
                    if (setCommonRemovedExceptionRanges == null)
                    {
                        setCommonRemovedExceptionRanges = setRemovedExceptionRanges;
                    }
                    else
                    {
                        setCommonRemovedExceptionRanges.RetainAll(setRemovedExceptionRanges);
                    }
                    // shift extern edges on splitted blocks
                    if (block.GetSeq().IsEmpty() && block.GetSuccs().Count == 1)
                    {
                        BasicBlock succs = block.GetSuccs()[0];
                        foreach (BasicBlock pred in new List <BasicBlock>(block.GetPreds()))
                        {
                            if (!setBlocks.Contains(pred))
                            {
                                pred.ReplaceSuccessor(block, succs);
                            }
                        }
                        if (graph.GetFirst() == block)
                        {
                            graph.SetFirst(succs);
                        }
                    }
                    graph.RemoveBlock(block);
                }
            }
            if (is_outside_range)
            {
                // new empty block
                BasicBlock emptyblock = new BasicBlock(++graph.last_id);
                graph.GetBlocks().AddWithKey(emptyblock, emptyblock.id);
                // add to ranges if necessary
                foreach (ExceptionRangeCFG range in setCommonRemovedExceptionRanges)
                {
                    emptyblock.AddSuccessorException(range.GetHandler());
                    range.GetProtectedRange().Add(emptyblock);
                }
                // insert between predecessors and next
                emptyblock.AddSuccessor(next);
                foreach (BasicBlock pred in setPredecessors)
                {
                    pred.ReplaceSuccessor(next, emptyblock);
                }
            }
        }
Ejemplo n.º 2
0
        private bool VerifyFinallyEx(ControlFlowGraph graph, CatchAllStatement fstat, FinallyProcessor.Record
                                     information)
        {
            HashSet <BasicBlock> tryBlocks   = GetAllBasicBlocks(fstat.GetFirst());
            HashSet <BasicBlock> catchBlocks = GetAllBasicBlocks(fstat.GetHandler());
            int finallytype = information.firstCode;
            Dictionary <BasicBlock, bool> mapLast = information.mapLast;
            BasicBlock first        = fstat.GetHandler().GetBasichead().GetBlock();
            bool       skippedFirst = false;

            if (finallytype == 3)
            {
                // empty finally
                RemoveExceptionInstructionsEx(first, 3, finallytype);
                if (mapLast.ContainsKey(first))
                {
                    graph.GetFinallyExits().Add(first);
                }
                return(true);
            }
            else if (first.GetSeq().Length() == 1 && finallytype > 0)
            {
                BasicBlock firstsuc = first.GetSuccs()[0];
                if (catchBlocks.Contains(firstsuc))
                {
                    first        = firstsuc;
                    skippedFirst = true;
                }
            }
            // identify start blocks
            HashSet <BasicBlock> startBlocks = new HashSet <BasicBlock>();

            foreach (BasicBlock block in tryBlocks)
            {
                Sharpen.Collections.AddAll(startBlocks, block.GetSuccs());
            }
            // throw in the try body will point directly to the dummy exit
            // so remove dummy exit
            startBlocks.Remove(graph.GetLast());
            startBlocks.RemoveAll(tryBlocks);
            List <FinallyProcessor.Area> lstAreas = new List <FinallyProcessor.Area>();

            foreach (BasicBlock start in startBlocks)
            {
                FinallyProcessor.Area arr = CompareSubgraphsEx(graph, start, catchBlocks, first,
                                                               finallytype, mapLast, skippedFirst);
                if (arr == null)
                {
                    return(false);
                }
                lstAreas.Add(arr);
            }
            //		try {
            //			DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
            //		} catch(Exception ex){ex.printStackTrace();}
            // delete areas
            foreach (FinallyProcessor.Area area in lstAreas)
            {
                DeleteArea(graph, area);
            }
            //		try {
            //			DotExporter.toDotFile(graph, new File("c:\\Temp\\fern5.dot"), true);
            //		} catch(Exception ex){ex.printStackTrace();}
            // INFO: empty basic blocks may remain in the graph!
            foreach (KeyValuePair <BasicBlock, bool> entry in mapLast)
            {
                BasicBlock last = entry.Key;
                if (entry.Value)
                {
                    RemoveExceptionInstructionsEx(last, 2, finallytype);
                    graph.GetFinallyExits().Add(last);
                }
            }
            RemoveExceptionInstructionsEx(fstat.GetHandler().GetBasichead().GetBlock(), 1, finallytype
                                          );
            return(true);
        }