private static bool SplitExceptionRange(ExceptionRangeCFG range, HashSet <BasicBlock > setEntries, ControlFlowGraph graph, GenericDominatorEngine engine) { foreach (BasicBlock entry in setEntries) { List <BasicBlock> lstSubrangeBlocks = GetReachableBlocksRestricted(entry, range, engine); if (!(lstSubrangeBlocks.Count == 0) && lstSubrangeBlocks.Count < range.GetProtectedRange ().Count) { // add new range ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.GetHandler (), range.GetExceptionTypes()); graph.GetExceptions().Add(subRange); // shrink the original range lstSubrangeBlocks.ForEach(block => range.GetProtectedRange().Remove(block)); return(true); } else { // should not happen DecompilerContext.GetLogger().WriteMessage("Inconsistency found while splitting protected range" , IFernflowerLogger.Severity.Warn); } } return(false); }
public static void RemoveCircularRanges(ControlFlowGraph graph) { GenericDominatorEngine engine = new GenericDominatorEngine(new _IIGraph_215(graph )); engine.Initialize(); List <ExceptionRangeCFG> lstRanges = graph.GetExceptions(); for (int i = lstRanges.Count - 1; i >= 0; i--) { ExceptionRangeCFG range = lstRanges[i]; BasicBlock handler = range.GetHandler(); List <BasicBlock> rangeList = range.GetProtectedRange(); if (rangeList.Contains(handler)) { // TODO: better removing strategy List <BasicBlock> lstRemBlocks = GetReachableBlocksRestricted(range.GetHandler(), range, engine); if (lstRemBlocks.Count < rangeList.Count || rangeList.Count == 1) { foreach (BasicBlock block in lstRemBlocks) { block.RemoveSuccessorException(handler); rangeList.Remove(block); } } if ((rangeList.Count == 0)) { lstRanges.RemoveAtReturningValue(i); } } } }
private static void InsertBlockBefore(ControlFlowGraph graph, BasicBlock oldblock , BasicBlock newblock) { List <BasicBlock> lstTemp = new List <BasicBlock>(); Sharpen.Collections.AddAll(lstTemp, oldblock.GetPreds()); Sharpen.Collections.AddAll(lstTemp, oldblock.GetPredExceptions()); // replace predecessors foreach (BasicBlock pred in lstTemp) { pred.ReplaceSuccessor(oldblock, newblock); } // copy exception edges and extend protected ranges foreach (BasicBlock hd in oldblock.GetSuccExceptions()) { newblock.AddSuccessorException(hd); ExceptionRangeCFG range = graph.GetExceptionRange(hd, oldblock); range.GetProtectedRange().Add(newblock); } // replace handler foreach (ExceptionRangeCFG range in graph.GetExceptions()) { if (range.GetHandler() == oldblock) { range.SetHandler(newblock); } } newblock.AddSuccessor(oldblock); graph.GetBlocks().AddWithKey(newblock, newblock.id); if (graph.GetFirst() == oldblock) { graph.SetFirst(newblock); } }
public static void RemoveEmptyRanges(ControlFlowGraph graph) { List <ExceptionRangeCFG> lstRanges = graph.GetExceptions(); for (int i = lstRanges.Count - 1; i >= 0; i--) { ExceptionRangeCFG range = lstRanges[i]; bool isEmpty = true; foreach (BasicBlock block in range.GetProtectedRange()) { if (!block.GetSeq().IsEmpty()) { isEmpty = false; break; } } if (isEmpty) { foreach (BasicBlock block in range.GetProtectedRange()) { block.RemoveSuccessorException(range.GetHandler()); } lstRanges.RemoveAtReturningValue(i); } } }
public static void InsertDummyExceptionHandlerBlocks(ControlFlowGraph graph, int bytecode_version) { Dictionary <BasicBlock, HashSet <ExceptionRangeCFG> > mapRanges = new Dictionary <BasicBlock , HashSet <ExceptionRangeCFG> >(); foreach (ExceptionRangeCFG range in graph.GetExceptions()) { mapRanges.ComputeIfAbsent(range.GetHandler(), (BasicBlock k) => new HashSet <ExceptionRangeCFG >()).Add(range); } foreach (KeyValuePair <BasicBlock, HashSet <ExceptionRangeCFG> > ent in mapRanges) { BasicBlock handler = ent.Key; HashSet <ExceptionRangeCFG> ranges = ent.Value; if (ranges.Count == 1) { continue; } foreach (ExceptionRangeCFG range in ranges) { // add some dummy instructions to prevent optimizing away the empty block SimpleInstructionSequence seq = new SimpleInstructionSequence(); seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants .Group_General, bytecode_version, new int[] { 0 }), -1); seq.AddInstruction(Instruction.Create(ICodeConstants.opc_pop, false, ICodeConstants .Group_General, bytecode_version, null), -1); BasicBlock dummyBlock = new BasicBlock(++graph.last_id); dummyBlock.SetSeq(seq); graph.GetBlocks().AddWithKey(dummyBlock, dummyBlock.id); // only exception predecessors from this range considered List <BasicBlock> lstPredExceptions = new List <BasicBlock>(handler.GetPredExceptions ()); lstPredExceptions = lstPredExceptions.Intersect(range.GetProtectedRange()).ToList(); // replace predecessors foreach (BasicBlock pred in lstPredExceptions) { pred.ReplaceSuccessor(handler, dummyBlock); } // replace handler range.SetHandler(dummyBlock); // add common exception edges HashSet <BasicBlock> commonHandlers = new HashSet <BasicBlock>(handler.GetSuccExceptions ()); foreach (BasicBlock pred in lstPredExceptions) { commonHandlers.IntersectWith(pred.GetSuccExceptions()); } // TODO: more sanity checks? foreach (BasicBlock commonHandler in commonHandlers) { ExceptionRangeCFG commonRange = graph.GetExceptionRange(commonHandler, handler); dummyBlock.AddSuccessorException(commonHandler); commonRange.GetProtectedRange().Add(dummyBlock); } dummyBlock.AddSuccessor(handler); } } }
internal Range(BasicBlock handler, string uniqueStr, HashSet <BasicBlock> protectedRange , ExceptionRangeCFG rangeCFG) { this.handler = handler; this.uniqueStr = uniqueStr; this.protectedRange = protectedRange; this.rangeCFG = rangeCFG; }
private static HashSet <BasicBlock> GetRangeEntries(ExceptionRangeCFG range) { HashSet <BasicBlock> setEntries = new HashSet <BasicBlock>(); HashSet <BasicBlock> setRange = new HashSet <BasicBlock>(range.GetProtectedRange()); foreach (BasicBlock block in range.GetProtectedRange()) { HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(block.GetPreds()); setPreds.ExceptWith(setRange); if (!(setPreds.Count == 0)) { setEntries.Add(block); } } return(setEntries); }
private static RootStatement GraphToStatement(ControlFlowGraph graph) { VBStyleCollection <Statement, int> stats = new VBStyleCollection <Statement, int>(); VBStyleCollection <BasicBlock, int> blocks = graph.GetBlocks(); foreach (BasicBlock block in blocks) { stats.AddWithKey(new BasicBlockStatement(block), block.id); } BasicBlock firstblock = graph.GetFirst(); // head statement Statement firstst = stats.GetWithKey(firstblock.id); // dummy exit statement DummyExitStatement dummyexit = new DummyExitStatement(); Statement general; if (stats.Count > 1 || firstblock.IsSuccessor(firstblock)) { // multiple basic blocks or an infinite loop of one block general = new GeneralStatement(firstst, stats, null); } else { // one straightforward basic block RootStatement root = new RootStatement(firstst, dummyexit); firstst.AddSuccessor(new StatEdge(StatEdge.Type_Break, firstst, dummyexit, root)); return(root); } foreach (BasicBlock block in blocks) { Statement stat = stats.GetWithKey(block.id); foreach (BasicBlock succ in block.GetSuccs()) { Statement stsucc = stats.GetWithKey(succ.id); int type; if (stsucc == firstst) { type = StatEdge.Type_Continue; } else if (graph.GetFinallyExits().Contains(block)) { type = StatEdge.Type_Finallyexit; stsucc = dummyexit; } else if (succ.id == graph.GetLast().id) { type = StatEdge.Type_Break; stsucc = dummyexit; } else { type = StatEdge.Type_Regular; } stat.AddSuccessor(new StatEdge(type, stat, (type == StatEdge.Type_Continue) ? general : stsucc, (type == StatEdge.Type_Regular) ? null : general)); } // exceptions edges foreach (BasicBlock succex in block.GetSuccExceptions()) { Statement stsuccex = stats.GetWithKey(succex.id); ExceptionRangeCFG range = graph.GetExceptionRange(succex, block); if (!range.IsCircular()) { stat.AddSuccessor(new StatEdge(stat, stsuccex, range.GetExceptionTypes())); } } } general.BuildContinueSet(); general.BuildMonitorFlags(); return(new RootStatement(general, dummyexit)); }
private static List <BasicBlock> GetReachableBlocksRestricted(BasicBlock start, ExceptionRangeCFG range, GenericDominatorEngine engine) { List <BasicBlock> lstRes = new List <BasicBlock>(); LinkedList <BasicBlock> stack = new LinkedList <BasicBlock>(); HashSet <BasicBlock> setVisited = new HashSet <BasicBlock>(); stack.AddFirst(start); while (!(stack.Count == 0)) { BasicBlock block = Sharpen.Collections.RemoveFirst(stack); setVisited.Add(block); if (range.GetProtectedRange().Contains(block) && engine.IsDominator(block, start)) { lstRes.Add(block); List <BasicBlock> lstSuccs = new List <BasicBlock>(block.GetSuccs()); Sharpen.Collections.AddAll(lstSuccs, block.GetSuccExceptions()); foreach (BasicBlock succ in lstSuccs) { if (!setVisited.Contains(succ)) { stack.AddLast(succ); } } } } return(lstRes); }
private static bool RemoveEmptyBlock(ControlFlowGraph graph, BasicBlock block, bool merging) { bool deletedRanges = false; if (block.GetSeq().IsEmpty()) { if (block.GetSuccs().Count > 1) { if (block.GetPreds().Count > 1) { // ambiguous block throw new Exception("ERROR: empty block with multiple predecessors and successors found" ); } else if (!merging) { throw new Exception("ERROR: empty block with multiple successors found"); } } HashSet <BasicBlock> setExits = new HashSet <BasicBlock>(graph.GetLast().GetPreds() ); if ((block.GetPredExceptions().Count == 0) && (!setExits.Contains(block) || block .GetPreds().Count == 1)) { if (setExits.Contains(block)) { BasicBlock pred = block.GetPreds()[0]; // FIXME: flag in the basic block if (pred.GetSuccs().Count != 1 || (!pred.GetSeq().IsEmpty() && pred.GetSeq().GetLastInstr ().group == ICodeConstants.Group_Switch)) { return(false); } } HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(block.GetPreds()); HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>(block.GetSuccs()); // collect common exception ranges of predecessors and successors HashSet <BasicBlock> setCommonExceptionHandlers = null; for (int i = 0; i < 2; ++i) { foreach (BasicBlock pred in i == 0 ? setPreds : setSuccs) { if (setCommonExceptionHandlers == null) { setCommonExceptionHandlers = new HashSet <BasicBlock>(pred.GetSuccExceptions()); } else { setCommonExceptionHandlers.IntersectWith(pred.GetSuccExceptions()); } } } // check the block to be in each of the common ranges if (setCommonExceptionHandlers != null && !(setCommonExceptionHandlers.Count == 0)) { foreach (BasicBlock handler in setCommonExceptionHandlers) { if (!block.GetSuccExceptions().Contains(handler)) { return(false); } } } // remove ranges consisting of this one block List <ExceptionRangeCFG> lstRanges = graph.GetExceptions(); for (int i = lstRanges.Count - 1; i >= 0; i--) { ExceptionRangeCFG range = lstRanges[i]; List <BasicBlock> lst = range.GetProtectedRange(); if (lst.Count == 1 && lst[0] == block) { if (DecompilerContext.GetOption(IFernflowerPreferences.Remove_Empty_Ranges)) { block.RemoveSuccessorException(range.GetHandler()); lstRanges.RemoveAtReturningValue(i); deletedRanges = true; } else { return(false); } } } // connect remaining nodes if (merging) { BasicBlock pred = block.GetPreds()[0]; pred.RemoveSuccessor(block); List <BasicBlock> lstSuccs = new List <BasicBlock>(block.GetSuccs()); foreach (BasicBlock succ in lstSuccs) { block.RemoveSuccessor(succ); pred.AddSuccessor(succ); } } else { foreach (BasicBlock pred in setPreds) { foreach (BasicBlock succ in setSuccs) { pred.ReplaceSuccessor(block, succ); } } } // finally exit edges HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits(); if (setFinallyExits.Contains(block)) { setFinallyExits.Remove(block); setFinallyExits.Add(new Sharpen.EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator()).Next()); } // replace first if necessary if (graph.GetFirst() == block) { if (setSuccs.Count != 1) { throw new Exception("multiple or no entry blocks!"); } else { graph.SetFirst(new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next()); } } // remove this block graph.RemoveBlock(block); if (deletedRanges) { RemoveDeadBlocks(graph); } } } return(deletedRanges); }
public static void IncorporateValueReturns(ControlFlowGraph graph) { foreach (BasicBlock block in graph.GetBlocks()) { InstructionSequence seq = block.GetSeq(); int len = seq.Length(); if (len > 0 && len < 3) { bool ok = false; if (seq.GetLastInstr().opcode >= ICodeConstants.opc_ireturn && seq.GetLastInstr() .opcode <= ICodeConstants.opc_return) { if (len == 1) { ok = true; } else if (seq.GetLastInstr().opcode != ICodeConstants.opc_return) { switch (seq.GetInstr(0).opcode) { case ICodeConstants.opc_iload: case ICodeConstants.opc_lload: case ICodeConstants.opc_fload: case ICodeConstants.opc_dload: case ICodeConstants.opc_aload: case ICodeConstants.opc_aconst_null: case ICodeConstants.opc_bipush: case ICodeConstants.opc_sipush: case ICodeConstants.opc_lconst_0: case ICodeConstants.opc_lconst_1: case ICodeConstants.opc_fconst_0: case ICodeConstants.opc_fconst_1: case ICodeConstants.opc_fconst_2: case ICodeConstants.opc_dconst_0: case ICodeConstants.opc_dconst_1: case ICodeConstants.opc_ldc: case ICodeConstants.opc_ldc_w: case ICodeConstants.opc_ldc2_w: { ok = true; break; } } } } if (ok) { if (!(block.GetPreds().Count == 0)) { HashSet <BasicBlock> setPredHandlersUnion = new HashSet <BasicBlock>(); HashSet <BasicBlock> setPredHandlersIntersection = new HashSet <BasicBlock>(); bool firstpred = true; foreach (BasicBlock pred in block.GetPreds()) { if (firstpred) { Sharpen.Collections.AddAll(setPredHandlersIntersection, pred.GetSuccExceptions()); firstpred = false; } else { setPredHandlersIntersection.IntersectWith(pred.GetSuccExceptions()); } Sharpen.Collections.AddAll(setPredHandlersUnion, pred.GetSuccExceptions()); } // add exception ranges from predecessors setPredHandlersIntersection.ExceptWith(block.GetSuccExceptions()); BasicBlock predecessor = block.GetPreds()[0]; foreach (BasicBlock handler in setPredHandlersIntersection) { ExceptionRangeCFG range = graph.GetExceptionRange(handler, predecessor); range.GetProtectedRange().Add(block); block.AddSuccessorException(handler); } // remove redundant ranges HashSet <BasicBlock> setRangesToBeRemoved = new HashSet <BasicBlock>(block.GetSuccExceptions ()); setRangesToBeRemoved.ExceptWith(setPredHandlersUnion); foreach (BasicBlock handler in setRangesToBeRemoved) { ExceptionRangeCFG range = graph.GetExceptionRange(handler, block); if (range.GetProtectedRange().Count > 1) { range.GetProtectedRange().Remove(block); block.RemoveSuccessorException(handler); } } } if (block.GetPreds().Count == 1 && (block.GetPredExceptions().Count == 0)) { BasicBlock bpred = block.GetPreds()[0]; if (bpred.GetSuccs().Count == 1) { // add exception ranges of predecessor foreach (BasicBlock succ in bpred.GetSuccExceptions()) { if (!block.GetSuccExceptions().Contains(succ)) { ExceptionRangeCFG range = graph.GetExceptionRange(succ, bpred); range.GetProtectedRange().Add(block); block.AddSuccessorException(succ); } } // remove superfluous ranges from successors foreach (BasicBlock succ in new HashSet <BasicBlock>(block.GetSuccExceptions())) { if (!bpred.GetSuccExceptions().Contains(succ)) { ExceptionRangeCFG range = graph.GetExceptionRange(succ, block); if (range.GetProtectedRange().Count > 1) { range.GetProtectedRange().Remove(block); block.RemoveSuccessorException(succ); } } } } } } } } }
public static void ExtendSynchronizedRangeToMonitorexit(ControlFlowGraph graph) { while (true) { bool range_extended = false; foreach (ExceptionRangeCFG range in graph.GetExceptions()) { HashSet <BasicBlock> setPreds = new HashSet <BasicBlock>(); foreach (BasicBlock block in range.GetProtectedRange()) { Sharpen.Collections.AddAll(setPreds, block.GetPreds()); } setPreds.ExceptWith(range.GetProtectedRange()); if (setPreds.Count != 1) { continue; } // multiple predecessors, obfuscated range var setPredsEnumerator = new EnumeratorAdapter <BasicBlock>(setPreds.GetEnumerator()); BasicBlock predBlock = setPredsEnumerator.Next(); InstructionSequence predSeq = predBlock.GetSeq(); if (predSeq.IsEmpty() || predSeq.GetLastInstr().opcode != ICodeConstants.opc_monitorenter) { continue; } // not a synchronized range bool monitorexit_in_range = false; HashSet <BasicBlock> setProtectedBlocks = new HashSet <BasicBlock>(); Sharpen.Collections.AddAll(setProtectedBlocks, range.GetProtectedRange()); setProtectedBlocks.Add(range.GetHandler()); foreach (BasicBlock block in setProtectedBlocks) { InstructionSequence blockSeq = block.GetSeq(); for (int i = 0; i < blockSeq.Length(); i++) { if (blockSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit) { monitorexit_in_range = true; break; } } if (monitorexit_in_range) { break; } } if (monitorexit_in_range) { continue; } // protected range already contains monitorexit HashSet <BasicBlock> setSuccs = new HashSet <BasicBlock>(); foreach (BasicBlock block in range.GetProtectedRange()) { Sharpen.Collections.AddAll(setSuccs, block.GetSuccs()); } setSuccs.ExceptWith(range.GetProtectedRange()); if (setSuccs.Count != 1) { continue; } // non-unique successor BasicBlock succBlock = new Sharpen.EnumeratorAdapter <BasicBlock>(setSuccs.GetEnumerator()).Next(); InstructionSequence succSeq = succBlock.GetSeq(); int succ_monitorexit_index = -1; for (int i = 0; i < succSeq.Length(); i++) { if (succSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit) { succ_monitorexit_index = i; break; } } if (succ_monitorexit_index < 0) { continue; } // monitorexit not found in the single successor block BasicBlock handlerBlock = range.GetHandler(); if (handlerBlock.GetSuccs().Count != 1) { continue; } // non-unique handler successor BasicBlock succHandler = handlerBlock.GetSuccs()[0]; InstructionSequence succHandlerSeq = succHandler.GetSeq(); if (succHandlerSeq.IsEmpty() || succHandlerSeq.GetLastInstr().opcode != ICodeConstants .opc_athrow) { continue; } // not a standard synchronized range int handler_monitorexit_index = -1; for (int i = 0; i < succHandlerSeq.Length(); i++) { if (succHandlerSeq.GetInstr(i).opcode == ICodeConstants.opc_monitorexit) { handler_monitorexit_index = i; break; } } if (handler_monitorexit_index < 0) { continue; } // monitorexit not found in the handler successor block // checks successful, prerequisites satisfied, now extend the range if (succ_monitorexit_index < succSeq.Length() - 1) { // split block SimpleInstructionSequence seq = new SimpleInstructionSequence(); for (int counter = 0; counter < succ_monitorexit_index; counter++) { seq.AddInstruction(succSeq.GetInstr(0), -1); succSeq.RemoveInstruction(0); } // build a separate block BasicBlock newblock = new BasicBlock(++graph.last_id); newblock.SetSeq(seq); // insert new block foreach (BasicBlock block in succBlock.GetPreds()) { block.ReplaceSuccessor(succBlock, newblock); } newblock.AddSuccessor(succBlock); graph.GetBlocks().AddWithKey(newblock, newblock.id); succBlock = newblock; } // copy exception edges and extend protected ranges (successor block) BasicBlock rangeExitBlock = succBlock.GetPreds()[0]; for (int j = 0; j < rangeExitBlock.GetSuccExceptions().Count; j++) { BasicBlock hd = rangeExitBlock.GetSuccExceptions()[j]; succBlock.AddSuccessorException(hd); ExceptionRangeCFG rng = graph.GetExceptionRange(hd, rangeExitBlock); rng.GetProtectedRange().Add(succBlock); } // copy instructions (handler successor block) InstructionSequence handlerSeq = handlerBlock.GetSeq(); for (int counter = 0; counter < handler_monitorexit_index; counter++) { handlerSeq.AddInstruction(succHandlerSeq.GetInstr(0), -1); succHandlerSeq.RemoveInstruction(0); } range_extended = true; break; } if (!range_extended) { break; } } }
private bool CompareBasicBlocksEx(ControlFlowGraph graph, BasicBlock pattern, BasicBlock sample, int type, int finallytype, List <int[]> lstStoreVars) { InstructionSequence seqPattern = pattern.GetSeq(); InstructionSequence seqSample = sample.GetSeq(); if (type != 0) { seqPattern = seqPattern.Clone(); if ((type & 1) > 0) { // first if (finallytype > 0) { seqPattern.RemoveInstruction(0); } } if ((type & 2) > 0) { // last if (finallytype == 0 || finallytype == 2) { seqPattern.RemoveLast(); } if (finallytype == 2) { seqPattern.RemoveLast(); } } } if (seqPattern.Length() > seqSample.Length()) { return(false); } for (int i = 0; i < seqPattern.Length(); i++) { Instruction instrPattern = seqPattern.GetInstr(i); Instruction instrSample = seqSample.GetInstr(i); // compare instructions with respect to jumps if (!EqualInstructions(instrPattern, instrSample, lstStoreVars)) { return(false); } } if (seqPattern.Length() < seqSample.Length()) { // split in two blocks SimpleInstructionSequence seq = new SimpleInstructionSequence(); LinkedList <int> oldOffsets = new LinkedList <int>(); for (int i = seqSample.Length() - 1; i >= seqPattern.Length(); i--) { seq.AddInstruction(0, seqSample.GetInstr(i), -1); oldOffsets.AddFirst(sample.GetOldOffset(i)); seqSample.RemoveInstruction(i); } BasicBlock newblock = new BasicBlock(++graph.last_id); newblock.SetSeq(seq); Sharpen.Collections.AddAll(newblock.GetInstrOldOffsets(), oldOffsets); List <BasicBlock> lstTemp = new List <BasicBlock>(sample.GetSuccs()); // move successors foreach (BasicBlock suc in lstTemp) { sample.RemoveSuccessor(suc); newblock.AddSuccessor(suc); } sample.AddSuccessor(newblock); graph.GetBlocks().AddWithKey(newblock, newblock.id); HashSet <BasicBlock> setFinallyExits = graph.GetFinallyExits(); if (setFinallyExits.Contains(sample)) { setFinallyExits.Remove(sample); setFinallyExits.Add(newblock); } // copy exception edges and extend protected ranges for (int j = 0; j < sample.GetSuccExceptions().Count; j++) { BasicBlock hd = sample.GetSuccExceptions()[j]; newblock.AddSuccessorException(hd); ExceptionRangeCFG range = graph.GetExceptionRange(hd, sample); range.GetProtectedRange().Add(newblock); } } return(true); }
private static void InsertSemaphore(ControlFlowGraph graph, HashSet <BasicBlock> setTry , BasicBlock head, BasicBlock handler, int var, FinallyProcessor.Record information , int bytecode_version) { HashSet <BasicBlock> setCopy = new HashSet <BasicBlock>(setTry); int finallytype = information.firstCode; Dictionary <BasicBlock, bool> mapLast = information.mapLast; // first and last statements RemoveExceptionInstructionsEx(handler, 1, finallytype); foreach (KeyValuePair <BasicBlock, bool> entry in mapLast) { BasicBlock last = entry.Key; if (entry.Value) { RemoveExceptionInstructionsEx(last, 2, finallytype); graph.GetFinallyExits().Add(last); } } // disable semaphore at statement exit points foreach (BasicBlock block in setTry) { List <BasicBlock> lstSucc = block.GetSuccs(); foreach (BasicBlock dest in lstSucc) { // break out if (dest != graph.GetLast() && !setCopy.Contains(dest)) { // disable semaphore SimpleInstructionSequence seq = new SimpleInstructionSequence(); seq.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants .Group_General, bytecode_version, new int[] { 0 }), -1); seq.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants .Group_General, bytecode_version, new int[] { var }), -1); // build a separate block BasicBlock newblock = new BasicBlock(++graph.last_id); newblock.SetSeq(seq); // insert between block and dest block.ReplaceSuccessor(dest, newblock); newblock.AddSuccessor(dest); setCopy.Add(newblock); graph.GetBlocks().AddWithKey(newblock, newblock.id); // exception ranges // FIXME: special case synchronized // copy exception edges and extend protected ranges for (int j = 0; j < block.GetSuccExceptions().Count; j++) { BasicBlock hd = block.GetSuccExceptions()[j]; newblock.AddSuccessorException(hd); ExceptionRangeCFG range = graph.GetExceptionRange(hd, block); range.GetProtectedRange().Add(newblock); } } } } // enable semaphore at the statement entrance SimpleInstructionSequence seq_1 = new SimpleInstructionSequence(); seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants .Group_General, bytecode_version, new int[] { 1 }), -1); seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants .Group_General, bytecode_version, new int[] { var }), -1); BasicBlock newhead = new BasicBlock(++graph.last_id); newhead.SetSeq(seq_1); InsertBlockBefore(graph, head, newhead); // initialize semaphor with false seq_1 = new SimpleInstructionSequence(); seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_bipush, false, ICodeConstants .Group_General, bytecode_version, new int[] { 0 }), -1); seq_1.AddInstruction(Instruction.Create(ICodeConstants.opc_istore, false, ICodeConstants .Group_General, bytecode_version, new int[] { var }), -1); BasicBlock newheadinit = new BasicBlock(++graph.last_id); newheadinit.SetSeq(seq_1); InsertBlockBefore(graph, newhead, newheadinit); setCopy.Add(newhead); setCopy.Add(newheadinit); foreach (BasicBlock hd in new HashSet <BasicBlock>(newheadinit.GetSuccExceptions() )) { ExceptionRangeCFG range = graph.GetExceptionRange(hd, newheadinit); if (setCopy.ContainsAll(range.GetProtectedRange())) { newheadinit.RemoveSuccessorException(hd); range.GetProtectedRange().Remove(newheadinit); } } }