// vers.size() == 0 means uninitialized variable, which is impossible private void CreateOrUpdatePhiNode(VarVersionPair phivar, FastSparseSetFactory <int> .FastSparseSet <int> vers, Statement stat) { FastSparseSetFactory <int> .FastSparseSet <int> versCopy = vers.GetCopy(); HashSet <int> phiVers = new HashSet <int>(); // take into account the corresponding mm/pp node if existing int ppvers = phantomppnodes.ContainsKey(phivar) ? phantomppnodes.GetOrNull(phivar ).version : -1; // ssu graph VarVersionNode phinode = ssuversions.nodes.GetWithKey(phivar); List <VarVersionEdge> lstPreds = new List <VarVersionEdge>(phinode.preds); if (lstPreds.Count == 1) { // not yet a phi node VarVersionEdge edge = lstPreds[0]; edge.source.RemoveSuccessor(edge); phinode.RemovePredecessor(edge); } else { foreach (VarVersionEdge edge in lstPreds) { int verssrc = new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version; if (!vers.Contains(verssrc) && verssrc != ppvers) { edge.source.RemoveSuccessor(edge); phinode.RemovePredecessor(edge); } else { versCopy.Remove(verssrc); phiVers.Add(verssrc); } } } List <VarVersionNode> colnodes = new List <VarVersionNode>(); List <VarVersionPair> colpaars = new List <VarVersionPair>(); foreach (int ver in versCopy) { VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(phivar.var , ver)); int tempver = GetNextFreeVersion(phivar.var, stat); VarVersionNode tempnode = new VarVersionNode(phivar.var, tempver); colnodes.Add(tempnode); colpaars.Add(new VarVersionPair(phivar.var, tempver)); VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, tempnode ); prenode.AddSuccessor(edge); tempnode.AddPredecessor(edge); edge = new VarVersionEdge(VarVersionEdge.Edge_General, tempnode, phinode); tempnode.AddSuccessor(edge); phinode.AddPredecessor(edge); phiVers.Add(tempver); } ssuversions.AddNodes(colnodes, colpaars); }
// ***************************************************************************** // private methods // ***************************************************************************** public virtual void SortEdgesAndNodes() { Dictionary <StatEdge, int> mapEdgeIndex = new Dictionary <StatEdge, int>(); List <StatEdge> lstFirstSuccs = first.GetSuccessorEdges(Statedge_Direct_All); for (int i = 0; i < lstFirstSuccs.Count; i++) { Sharpen.Collections.Put(mapEdgeIndex, lstFirstSuccs[i], i == 0 ? lstFirstSuccs.Count : i); } // case values BasicBlockStatement bbstat = (BasicBlockStatement)first; int[] values = ((SwitchInstruction)bbstat.GetBlock().GetLastInstruction()).GetValues (); List <Statement> nodes = new List <Statement>(stats.Count - 1); List <List <int?> > edges = new List <List <int?> >(stats.Count - 1); // collect regular edges for (int i = 1; i < stats.Count; i++) { Statement stat = stats[i]; List <int?> lst = new List <int?>(); foreach (StatEdge edge in stat.GetPredecessorEdges(StatEdge.Type_Regular)) { if (edge.GetSource() == first) { lst.Add(mapEdgeIndex.GetOrNullable(edge)); } } lst.Sort(); nodes.Add(stat); edges.Add(lst); } // collect exit edges List <StatEdge> lstExitEdges = first.GetSuccessorEdges(StatEdge.Type_Break | StatEdge .Type_Continue); while (!(lstExitEdges.Count == 0)) { StatEdge edge = lstExitEdges[0]; List <int?> lst = new List <int?>(); for (int i = lstExitEdges.Count - 1; i >= 0; i--) { StatEdge edgeTemp = lstExitEdges[i]; if (edgeTemp.GetDestination() == edge.GetDestination() && edgeTemp.GetType() == edge .GetType()) { lst.Add(mapEdgeIndex.GetOrNullable(edgeTemp)); lstExitEdges.RemoveAtReturningValue(i); } } lst.Sort(); nodes.Add(null); edges.Add(lst); } // sort edges (bubblesort) for (int i = 0; i < edges.Count - 1; i++) { for (int j = edges.Count - 1; j > i; j--) { if (edges[j - 1][0] > edges[j][0]) { edges[j] = edges[j - 1] = edges[j]; nodes[j] = nodes[j - 1] = nodes[j]; } } } // sort statement cliques for (int index = 0; index < nodes.Count; index++) { Statement stat = nodes[index]; if (stat != null) { HashSet <Statement> setPreds = new HashSet <Statement>(stat.GetNeighbours(StatEdge. Type_Regular, Direction_Backward)); setPreds.Remove(first); if (!(setPreds.Count == 0)) { Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPreds.GetEnumerator()).Next(); // assumption: at most one predecessor node besides the head. May not hold true for obfuscated code. for (int j = 0; j < nodes.Count; j++) { if (j != (index - 1) && nodes[j] == pred) { nodes.Add(j + 1, stat); edges.Add(j + 1, edges[index]); if (j > index) { nodes.RemoveAtReturningValue(index); edges.RemoveAtReturningValue(index); index--; } else { nodes.RemoveAtReturningValue(index + 1); edges.RemoveAtReturningValue(index + 1); } break; } } } } } // translate indices back into edges List <List <StatEdge> > lstEdges = new List <List <StatEdge> >(edges.Count); List <List <Exprent> > lstValues = new List <List <Exprent> >(edges.Count); foreach (List <int?> lst in edges) { List <StatEdge> lste = new List <StatEdge>(lst.Count); List <Exprent> lstv = new List <Exprent>(lst.Count); List <StatEdge> lstSuccs = first.GetSuccessorEdges(Statedge_Direct_All); foreach (int? @in in lst) { int?index = @in == lstSuccs.Count ? 0 : @in; if (!index.HasValue) { continue; } lste.Add(lstSuccs[index.Value]); lstv.Add(index == 0 ? null : new ConstExprent(values[index.Value - 1], false, null)); } lstEdges.Add(lste); lstValues.Add(lstv); } // replace null statements with dummy basic blocks for (int i = 0; i < nodes.Count; i++) { if (nodes[i] == null) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter ))); StatEdge sample_edge = lstEdges[i][0]; bstat.AddSuccessor(new StatEdge(sample_edge.GetType(), bstat, sample_edge.GetDestination (), sample_edge.closure)); foreach (StatEdge edge in lstEdges[i]) { edge.GetSource().ChangeEdgeType(Direction_Forward, edge, StatEdge.Type_Regular); edge.closure.GetLabelEdges().Remove(edge); edge.GetDestination().RemovePredecessor(edge); edge.GetSource().ChangeEdgeNode(Direction_Forward, edge, bstat); bstat.AddPredecessor(edge); } nodes[i] = bstat; stats.AddWithKey(bstat, bstat.id); bstat.SetParent(this); } } caseStatements = nodes; caseEdges = lstEdges; caseValues = lstValues; }
private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr, Statement stat, bool calcLiveVars) { if (expr == null) { return; } VarExprent varassign = null; bool finished = false; switch (expr.type) { case Exprent.Exprent_Assignment: { AssignmentExprent assexpr = (AssignmentExprent)expr; if (assexpr.GetCondType() == AssignmentExprent.Condition_None) { Exprent dest = assexpr.GetLeft(); if (dest.type == Exprent.Exprent_Var) { varassign = (VarExprent)dest; } } break; } case Exprent.Exprent_Function: { FunctionExprent func = (FunctionExprent)expr; switch (func.GetFuncType()) { case FunctionExprent.Function_Iif: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect varmapFalse; if (varmaparr[1] == null) { varmapFalse = new SFormsFastMapDirect(varmaparr[0]); } else { varmapFalse = varmaparr[1]; varmaparr[1] = null; } ProcessExprent(func.GetLstOperands()[1], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null }; ProcessExprent(func.GetLstOperands()[2], varmaparrNeg, stat, calcLiveVars); MergeMaps(varmaparr[0], varmaparrNeg[0]); varmaparr[1] = null; finished = true; break; } case FunctionExprent.Function_Cadd: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[0]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrAnd, stat, calcLiveVars); // false map varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd [1] == null ? 0 : 1]); // true map varmaparr[0] = varmaparrAnd[0]; finished = true; break; } case FunctionExprent.Function_Cor: { ProcessExprent(func.GetLstOperands()[0], varmaparr, stat, calcLiveVars); SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[varmaparr[1] == null ? 0 : 1]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrOr, stat, calcLiveVars); // false map varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1]; // true map varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]); finished = true; break; } } break; } } if (!finished) { List <Exprent> lst = expr.GetAllExprents(); lst.Remove(varassign); foreach (Exprent ex in lst) { ProcessExprent(ex, varmaparr, stat, calcLiveVars); } } SFormsFastMapDirect varmap = varmaparr[0]; // field access if (expr.type == Exprent.Exprent_Field) { int?index; if (mapFieldVars.ContainsKey(expr.id)) { index = mapFieldVars.GetOrNullable(expr.id); } else { index = fieldvarcounter--; Sharpen.Collections.Put(mapFieldVars, expr.id, index); // ssu graph ssuversions.CreateNode(new VarVersionPair(index, 1)); } SetCurrentVar(varmap, index, 1); } else if (expr.type == Exprent.Exprent_Invocation || (expr.type == Exprent.Exprent_Assignment && ((AssignmentExprent)expr).GetLeft().type == Exprent.Exprent_Field) || (expr. type == Exprent.Exprent_New && ((NewExprent)expr).GetNewType().type == ICodeConstants .Type_Object) || expr.type == Exprent.Exprent_Function) { bool ismmpp = true; if (expr.type == Exprent.Exprent_Function) { ismmpp = false; FunctionExprent fexpr = (FunctionExprent)expr; if (fexpr.GetFuncType() >= FunctionExprent.Function_Imm && fexpr.GetFuncType() <= FunctionExprent.Function_Ppi) { if (fexpr.GetLstOperands()[0].type == Exprent.Exprent_Field) { ismmpp = true; } } } if (ismmpp) { varmap.RemoveAllFields(); } } if (varassign != null) { int varindex = varassign.GetIndex(); if (varassign.GetVersion() == 0) { // get next version int nextver = GetNextFreeVersion(varindex, stat); // set version varassign.SetVersion(nextver); // ssu graph ssuversions.CreateNode(new VarVersionPair(varindex, nextver)); SetCurrentVar(varmap, varindex, nextver); } else { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, varassign.GetVersion()), varmap); } SetCurrentVar(varmap, varindex, varassign.GetVersion()); } } else if (expr.type == Exprent.Exprent_Function) { // MM or PP function FunctionExprent func_1 = (FunctionExprent)expr; switch (func_1.GetFuncType()) { case FunctionExprent.Function_Imm: case FunctionExprent.Function_Mmi: case FunctionExprent.Function_Ipp: case FunctionExprent.Function_Ppi: { if (func_1.GetLstOperands()[0].type == Exprent.Exprent_Var) { VarExprent var = (VarExprent)func_1.GetLstOperands()[0]; int varindex = var.GetIndex(); VarVersionPair varpaar = new VarVersionPair(varindex, var.GetVersion()); // ssu graph VarVersionPair phantomver = phantomppnodes.GetOrNull(varpaar); if (phantomver == null) { // get next version int nextver = GetNextFreeVersion(varindex, null); phantomver = new VarVersionPair(varindex, nextver); //ssuversions.createOrGetNode(phantomver); ssuversions.CreateNode(phantomver); VarVersionNode vernode = ssuversions.nodes.GetWithKey(varpaar); FastSparseSetFactory <int> .FastSparseSet <int> vers = factory.SpawnEmptySet(); if (vernode.preds.Count == 1) { vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(vernode.preds.GetEnumerator()).Next().source.version); } else { foreach (VarVersionEdge edge in vernode.preds) { vers.Add(new Sharpen.EnumeratorAdapter <VarVersionEdge>(edge.source.preds.GetEnumerator()).Next().source.version); } } vers.Add(nextver); CreateOrUpdatePhiNode(varpaar, vers, stat); Sharpen.Collections.Put(phantomppnodes, varpaar, phantomver); } if (calcLiveVars) { VarMapToGraph(varpaar, varmap); } SetCurrentVar(varmap, varindex, var.GetVersion()); } break; } } } else if (expr.type == Exprent.Exprent_Var) { VarExprent vardest = (VarExprent)expr; int varindex = vardest.GetIndex(); int current_vers = vardest.GetVersion(); FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex); int cardinality = vers.GetCardinality(); if (cardinality == 1) { // size == 1 if (current_vers != 0) { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap); } SetCurrentVar(varmap, varindex, current_vers); } else { // split last version int usever = GetNextFreeVersion(varindex, stat); // set version vardest.SetVersion(usever); SetCurrentVar(varmap, varindex, usever); // ssu graph int lastver = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next(); VarVersionNode prenode = ssuversions.nodes.GetWithKey(new VarVersionPair(varindex , lastver)); VarVersionNode usenode = ssuversions.CreateNode(new VarVersionPair(varindex, usever )); VarVersionEdge edge = new VarVersionEdge(VarVersionEdge.Edge_General, prenode, usenode ); prenode.AddSuccessor(edge); usenode.AddPredecessor(edge); } } else if (cardinality == 2) { // size > 1 if (current_vers != 0) { if (calcLiveVars) { VarMapToGraph(new VarVersionPair(varindex, current_vers), varmap); } SetCurrentVar(varmap, varindex, current_vers); } else { // split version int usever = GetNextFreeVersion(varindex, stat); // set version vardest.SetVersion(usever); // ssu node ssuversions.CreateNode(new VarVersionPair(varindex, usever)); SetCurrentVar(varmap, varindex, usever); current_vers = usever; } CreateOrUpdatePhiNode(new VarVersionPair(varindex, current_vers), vers, stat); } } }
private static void ProcessEdgesWithNext(Statement stat, Dictionary <Statement, List <StatEdge> > mapEdges, Statement next) { StatEdge statedge = null; List <StatEdge> lstSuccs = stat.GetAllSuccessorEdges(); if (!(lstSuccs.Count == 0)) { statedge = lstSuccs[0]; if (statedge.GetDestination() == next) { statedge.@explicit = false; statedge = null; } else { next = statedge.GetDestination(); } } // no next for a do statement if (stat.type == Statement.Type_Do && ((DoStatement)stat).GetLooptype() == DoStatement .Loop_Do) { next = null; } if (next == null) { if (mapEdges.Count == 1) { List <StatEdge> lstEdges = new Sharpen.EnumeratorAdapter <List <StatEdge> >(mapEdges.Values.GetEnumerator()).Next(); if (lstEdges.Count > 1 && new Sharpen.EnumeratorAdapter <Statement>(mapEdges.Keys.GetEnumerator()).Next().type != Statement .Type_Dummyexit) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } Sharpen.Collections.Put(mapEdges, newedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { newedge }))); } } } else { bool implfound = false; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key == next) { foreach (StatEdge edge in entr.Value) { edge.@explicit = false; } implfound = true; break; } } if ((stat.GetAllSuccessorEdges().Count == 0) && !implfound) { List <StatEdge> lstEdges = null; foreach (KeyValuePair <Statement, List <StatEdge> > entr in mapEdges) { if (entr.Key.type != Statement.Type_Dummyexit && (lstEdges == null || entr.Value. Count > lstEdges.Count)) { lstEdges = entr.Value; } } if (lstEdges != null && lstEdges.Count > 1) { StatEdge edge_example = lstEdges[0]; Statement closure = stat.GetParent(); if (!closure.ContainsStatementStrict(edge_example.closure)) { closure = edge_example.closure; } StatEdge newedge = new StatEdge(edge_example.GetType(), stat, edge_example.GetDestination (), closure); stat.AddSuccessor(newedge); foreach (StatEdge edge in lstEdges) { edge.@explicit = false; } } } mapEdges.Clear(); } if (statedge != null) { Sharpen.Collections.Put(mapEdges, statedge.GetDestination(), new List <StatEdge>(System.Linq.Enumerable.ToList(new [] { statedge }))); } }
private void ProcessExprent(Exprent expr, SFormsFastMapDirect[] varmaparr) { if (expr == null) { return; } VarExprent varassign = null; bool finished = false; switch (expr.type) { case Exprent.Exprent_Assignment: { AssignmentExprent assexpr = (AssignmentExprent)expr; if (assexpr.GetCondType() == AssignmentExprent.Condition_None) { Exprent dest = assexpr.GetLeft(); if (dest.type == Exprent.Exprent_Var) { varassign = (VarExprent)dest; } } break; } case Exprent.Exprent_Function: { FunctionExprent func = (FunctionExprent)expr; switch (func.GetFuncType()) { case FunctionExprent.Function_Iif: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect varmapFalse; if (varmaparr[1] == null) { varmapFalse = new SFormsFastMapDirect(varmaparr[0]); } else { varmapFalse = varmaparr[1]; varmaparr[1] = null; } ProcessExprent(func.GetLstOperands()[1], varmaparr); SFormsFastMapDirect[] varmaparrNeg = new SFormsFastMapDirect[] { varmapFalse, null }; ProcessExprent(func.GetLstOperands()[2], varmaparrNeg); MergeMaps(varmaparr[0], varmaparrNeg[0]); varmaparr[1] = null; finished = true; break; } case FunctionExprent.Function_Cadd: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect[] varmaparrAnd = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[0]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrAnd); // false map varmaparr[1] = MergeMaps(varmaparr[varmaparr[1] == null ? 0 : 1], varmaparrAnd[varmaparrAnd [1] == null ? 0 : 1]); // true map varmaparr[0] = varmaparrAnd[0]; finished = true; break; } case FunctionExprent.Function_Cor: { ProcessExprent(func.GetLstOperands()[0], varmaparr); SFormsFastMapDirect[] varmaparrOr = new SFormsFastMapDirect[] { new SFormsFastMapDirect (varmaparr[varmaparr[1] == null ? 0 : 1]), null }; ProcessExprent(func.GetLstOperands()[1], varmaparrOr); // false map varmaparr[1] = varmaparrOr[varmaparrOr[1] == null ? 0 : 1]; // true map varmaparr[0] = MergeMaps(varmaparr[0], varmaparrOr[0]); finished = true; break; } } break; } } if (finished) { return; } List <Exprent> lst = expr.GetAllExprents(); lst.Remove(varassign); foreach (Exprent ex in lst) { ProcessExprent(ex, varmaparr); } SFormsFastMapDirect varmap = varmaparr[0]; if (varassign != null) { int varindex = varassign.GetIndex(); if (varassign.GetVersion() == 0) { // get next version int nextver = GetNextFreeVersion(varindex); // set version varassign.SetVersion(nextver); SetCurrentVar(varmap, varindex, nextver); } else { SetCurrentVar(varmap, varindex, varassign.GetVersion()); } } else if (expr.type == Exprent.Exprent_Var) { VarExprent vardest = (VarExprent)expr; int varindex = vardest.GetIndex(); FastSparseSetFactory <int> .FastSparseSet <int> vers = varmap.Get(varindex); int cardinality = vers.GetCardinality(); if (cardinality == 1) { // == 1 // set version int it = new Sharpen.EnumeratorAdapter <int>(vers.GetEnumerator()).Next(); vardest.SetVersion(it); } else if (cardinality == 2) { // size > 1 int current_vers = vardest.GetVersion(); VarVersionPair currpaar = new VarVersionPair(varindex, current_vers); if (current_vers != 0 && phi.ContainsKey(currpaar)) { SetCurrentVar(varmap, varindex, current_vers); // update phi node phi.GetOrNull(currpaar).Union(vers); } else { // increase version int nextver = GetNextFreeVersion(varindex); // set version vardest.SetVersion(nextver); SetCurrentVar(varmap, varindex, nextver); // create new phi node Sharpen.Collections.Put(phi, new VarVersionPair(varindex, nextver), vers); } } } }
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; } } }
public static bool IsChoiceStatement(Statement head, List <Statement> lst) { Statement post = null; HashSet <Statement> setDest = head.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Forward); if (setDest.Contains(head)) { return(false); } while (true) { lst.Clear(); bool repeat = false; setDest.Remove(post); foreach (Statement stat in setDest) { if (stat.GetLastBasicType() != Statement.Lastbasictype_General) { if (post == null) { post = stat; repeat = true; break; } else { return(false); } } // preds HashSet <Statement> setPred = stat.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Backward); setPred.Remove(head); if (setPred.Contains(stat)) { return(false); } if (!setPred.All(setDest.Contains) || setPred.Count > 1) { if (post == null) { post = stat; repeat = true; break; } else { return(false); } } else if (setPred.Count == 1) { Statement pred = new Sharpen.EnumeratorAdapter <Statement>(setPred.GetEnumerator()).Next(); while (lst.Contains(pred)) { HashSet <Statement> setPredTemp = pred.GetNeighboursSet(StatEdge.Type_Regular, Statement .Direction_Backward); setPredTemp.Remove(head); if (!(setPredTemp.Count == 0)) { // at most 1 predecessor pred = new Sharpen.EnumeratorAdapter <Statement>(setPredTemp.GetEnumerator()).Next(); if (pred == stat) { return(false); } } else { // loop found break; } } } // succs List <StatEdge> lstEdges = stat.GetSuccessorEdges(Statement.Statedge_Direct_All); if (lstEdges.Count > 1) { HashSet <Statement> setSucc = stat.GetNeighboursSet(Statement.Statedge_Direct_All, Statement.Direction_Forward); setSucc.RetainAll(setDest); if (setSucc.Count > 0) { return(false); } else if (post == null) { post = stat; repeat = true; break; } else { return(false); } } else if (lstEdges.Count == 1) { StatEdge edge = lstEdges[0]; if (edge.GetType() == StatEdge.Type_Regular) { Statement statd = edge.GetDestination(); if (head == statd) { return(false); } if (post != statd && !setDest.Contains(statd)) { if (post != null) { return(false); } else { HashSet <Statement> set = statd.GetNeighboursSet(StatEdge.Type_Regular, Statement. Direction_Backward); if (set.Count > 1) { post = statd; repeat = true; break; } else { return(false); } } } } } lst.Add(stat); } if (!repeat) { break; } } lst.Add(head); lst.Remove(post); lst.Add(0, post); return(true); }
public static bool IsStatementIrreducible(Statement statement) { Dictionary <int, _T989645285> mapNodes = new Dictionary <int, _T989645285>(); // checking exceptions and creating nodes foreach (Statement stat in statement.GetStats()) { if (!(stat.GetSuccessorEdges(StatEdge.Type_Exception).Count == 0)) { return(false); } Sharpen.Collections.Put(mapNodes, stat.id, new _T989645285(stat.id)); } // connecting nodes foreach (Statement stat in statement.GetStats()) { _T989645285 node = mapNodes.GetOrNull(stat.id); foreach (Statement succ in stat.GetNeighbours(StatEdge.Type_Regular, Statement.Direction_Forward )) { _T989645285 nodeSucc = mapNodes.GetOrNull(succ.id); node.succs.Add(nodeSucc); nodeSucc.preds.Add(node); } } // transforming and reducing the graph while (true) { int ttype = 0; _T989645285 node = null; foreach (_T989645285 nd in mapNodes.Values) { if (nd.succs.Contains(nd)) { // T1 ttype = 1; } else if (nd.preds.Count == 1) { // T2 ttype = 2; } if (ttype != 0) { node = nd; break; } } if (node != null) { if (ttype == 1) { node.succs.Remove(node); node.preds.Remove(node); } else { _T989645285 pred = new Sharpen.EnumeratorAdapter <_T989645285>(node.preds.GetEnumerator()).Next(); Sharpen.Collections.AddAll(pred.succs, node.succs); pred.succs.Remove(node); foreach (_T989645285 succ in node.succs) { succ.preds.Remove(node); succ.preds.Add(pred); } Sharpen.Collections.Remove(mapNodes, node.id); } } else { // no transformation applicable return(mapNodes.Count > 1); } } }