public void changeEdgeType(int direction, StatEdge edge, int newtype) { int oldtype = edge.getType(); if (oldtype == newtype) { return; } if (oldtype == StatEdge.TYPE_EXCEPTION || newtype == StatEdge.TYPE_EXCEPTION) { throw new RuntimeException("Invalid edge type!"); } removeEdgeDirectInternal(direction, edge, oldtype); addEdgeDirectInternal(direction, edge, newtype); if (direction == DIRECTION_FORWARD) { edge.getDestination().changeEdgeType(DIRECTION_BACKWARD, edge, newtype); } edge.setType(newtype); }
public void addSuccessor(StatEdge edge) { addEdgeInternal(DIRECTION_FORWARD, edge); if (edge.closure != null) { edge.closure.getLabelEdges().add(edge); } edge.getDestination().addPredecessor(edge); }
List<Statement> lst = new ArrayList<>(stat.getStats()); Statement first = st.getFirst(); for (StatEdge edge : st.getAllPredecessorEdges()) { st.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, first); first.addPredecessor(edge); Statement last = st.getStats().getLast(); if (last.getAllSuccessorEdges().isEmpty() && i < lst.size() - 1) { last.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, last, lst.get(i + 1))); for (StatEdge edge : last.getAllSuccessorEdges()) { if (i == lst.size() - 1) { if (edge.closure == st) { stat.addLabeledEdge(edge); edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, StatEdge.TYPE_REGULAR); edge.closure.getLabelEdges().remove(edge); edge.closure = null; for (StatEdge edge : st.getAllSuccessorEdges()) { st.removeSuccessor(edge); for (StatEdge edge : new HashSet<>(st.getLabelEdges())) { if (edge.getSource() != last) { last.addLabeledEdge(edge); lst.addAll(i, st.getStats());
public HashSet<Statement> buildContinueSet() { continueSet.clear(); for (Statement st : stats) { continueSet.addAll(st.buildContinueSet()); if (st != first) { continueSet.remove(st.getBasichead()); } } for (StatEdge edge : getEdges(StatEdge.TYPE_CONTINUE, DIRECTION_FORWARD)) { continueSet.add(edge.getDestination().getBasichead()); } if (type == TYPE_DO) { continueSet.remove(first.getBasichead()); } return continueSet; }
private static void addToPostReversePostOrderList(Statement stat, List<Statement> lst, HashSet<Statement> setVisited) { if (setVisited.contains(stat)) { // because of not considered exception edges, s. isExitComponent. Should be rewritten, if possible. return; } setVisited.add(stat); for (StatEdge prededge : stat.getEdges(StatEdge.TYPE_REGULAR | StatEdge.TYPE_EXCEPTION, DIRECTION_BACKWARD)) { Statement pred = prededge.getSource(); if (!setVisited.contains(pred)) { addToPostReversePostOrderList(pred, lst, setVisited); } } lst.add(0, stat); }
Statement head = stat.getFirst(); Statement post = stat.getPost(); VBStyleCollection<Statement, Integer> setNodes = stat.getStats(); for (StatEdge edge : post.getEdges(STATEDGE_DIRECT_ALL, DIRECTION_BACKWARD)) { if (stat.containsStatementStrict(edge.getSource())) { edge.getSource().changeEdgeType(DIRECTION_FORWARD, edge, StatEdge.TYPE_BREAK); stat.addLabeledEdge(edge); for (StatEdge prededge : head.getAllPredecessorEdges()) { stat.containsStatementStrict(prededge.getSource())) { prededge.getSource().changeEdgeType(DIRECTION_FORWARD, prededge, StatEdge.TYPE_CONTINUE); stat.addLabeledEdge(prededge); head.removePredecessor(prededge); prededge.getSource().changeEdgeNode(DIRECTION_FORWARD, prededge, stat); stat.addPredecessor(prededge); Set<Statement> setHandlers = new HashSet<>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); for (Statement node : setNodes) { setHandlers.retainAll(node.getNeighbours(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)); for (StatEdge edge : head.getEdges(StatEdge.TYPE_EXCEPTION, DIRECTION_FORWARD)) { Statement handler = edge.getDestination(); stat.addSuccessor(new StatEdge(stat, handler, edge.getExceptions()));
private static void buildSynchronized(Statement stat) { for (Statement st : stat.getStats()) { buildSynchronized(st); List<Statement> lst = stat.getStats(); for (int i = 0; i < lst.size() - 1; i++) { if (current.isMonitorEnter()) { next = next.getFirst(); if (ca.getFirst().isContainsMonitorExit() && ca.getHandler().isContainsMonitorExit()) { current.removeSuccessor(current.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL).get(0)); for (StatEdge edge : current.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL)) { current.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, nextDirect); nextDirect.addPredecessor(edge); stat.getStats().removeWithKey(current.id); stat.setFirst(stat.getStats().get(0)); current.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, current, ca.getFirst())); ca.getParent().replaceStatement(ca, sync); found = true; break;
public void replaceStatement(Statement oldstat, Statement newstat) { for (StatEdge edge : oldstat.getAllPredecessorEdges()) { oldstat.removePredecessor(edge); edge.getSource().changeEdgeNode(DIRECTION_FORWARD, edge, newstat); newstat.addPredecessor(edge); for (StatEdge edge : oldstat.getAllSuccessorEdges()) { oldstat.removeSuccessor(edge); edge.setSource(newstat); newstat.addSuccessor(edge); stats.addWithKeyAndIndex(statindex, newstat, newstat.id); newstat.setParent(this); newstat.post = oldstat.post; List<StatEdge> lst = new ArrayList<>(oldstat.getLabelEdges()); newstat.addLabeledEdge(edge); if (this == edge.getDestination() || this.containsStatementStrict(edge.getDestination())) { edge.closure = null; this.addLabeledEdge(edge); oldstat.getLabelEdges().clear();
pre.removeSuccessor(pre.getAllSuccessorEdges().get(0)); // single regular edge StatEdge edge = first.getPredecessorEdges(StatEdge.TYPE_BREAK).get(0); Statement source = edge.getSource(); Statement parent = source.getParent(); source.removeSuccessor(edge); source == parent.getFirst()) { IfStatement ifparent = (IfStatement)parent; SequenceStatement block = new SequenceStatement(lst); source.addSuccessor(newedge); ifparent.setIfEdge(newedge); ifparent.setIfstat(block); block.setAllParent(); parent.replaceStatement(source, block); prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, source); source.addPredecessor(prededge); source.addLabeledEdge(prededge); source.addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, source, first));
if (st.getExprents() != null && st.getExprents().isEmpty()) { if (st.getAllSuccessorEdges().isEmpty()) { List<StatEdge> lstBreaks = st.getPredecessorEdges(StatEdge.TYPE_BREAK); for (StatEdge edge : st.getAllPredecessorEdges()) { edge.getSource().removeSuccessor(edge); StatEdge sucedge = st.getAllSuccessorEdges().get(0); if (sucedge.getType() != StatEdge.TYPE_FINALLYEXIT) { st.removeSuccessor(sucedge); for (StatEdge edge : st.getAllPredecessorEdges()) { if (sucedge.getType() != StatEdge.TYPE_REGULAR) { edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, sucedge.getType()); st.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, sucedge.getDestination()); sucedge.getDestination().addPredecessor(edge); sucedge.closure.addLabeledEdge(edge);
private static void eliminateLoop(Statement loop, Statement parentloop) { // move continue edges to the parent loop List<StatEdge> lst = new ArrayList<>(loop.getLabelEdges()); for (StatEdge edge : lst) { loop.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, parentloop); parentloop.addPredecessor(edge); parentloop.addLabeledEdge(edge); } // remove the last break edge, if exists Statement loopcontent = loop.getFirst(); if (!loopcontent.getAllSuccessorEdges().isEmpty()) { loopcontent.removeSuccessor(loopcontent.getAllSuccessorEdges().get(0)); } // replace loop with its content loop.getParent().replaceStatement(loop, loopcontent); } }
if (secondif.getFirst().getExprents().isEmpty()) { firstif.getFirst().removeSuccessor(firstif.getIfEdge()); if (!firstif.containsStatementStrict(edge.getSource())) { firstif.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, secondif); secondif.addPredecessor(edge); parent.getStats().removeWithKey(firstif.id); if (parent.getFirst() == firstif) { parent.setFirst(secondif); if (secondif.getFirst().getExprents().isEmpty() && !firstif.getFirst().getExprents().isEmpty()) { for (StatEdge edge : second.getAllSuccessorEdges()) { second.removeSuccessor(edge); edge.setSource(firstif); firstif.addSuccessor(edge); firstif.getFirst().removeSuccessor(ifedge); second.addSuccessor(new StatEdge(ifedge.getType(), second, ifedge.getDestination(), ifedge.closure)); firstif.getFirst().addSuccessor(newifedge); firstif.setIfstat(second); second.setParent(firstif);
Statement parent = stat.getParent(); if (parent != null && parent.type == Statement.TYPE_IF && stat.type == Statement.TYPE_BASICBLOCK && stat.getExprents().size() == 1) { Exprent exprent = stat.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_EXIT) { ExitExprent exit_exprent = (ExitExprent)exprent; ifbranch.getExprents().size() == 1 && ifbranch.getExprents().get(0).type == Exprent.EXPRENT_EXIT) { ifparent.getFirst().removeSuccessor(ifedge); ifparent.getFirst().removeSuccessor(elseedge); if (!ifbranch.getAllSuccessorEdges().isEmpty()) { ifbranch.removeSuccessor(ifbranch.getAllSuccessorEdges().get(0)); if (!ifparent.getFirst().getExprents().isEmpty()) { elsebranch.getExprents().addAll(0, ifparent.getFirst().getExprents()); ifparent.getParent().replaceStatement(ifparent, elsebranch); ifparent.getParent().setAllParent(); parent.type == Statement.TYPE_SEQUENCE && stat.type == Statement.TYPE_BASICBLOCK && stat.getExprents().size() == 1) { Exprent exprent = stat.getExprents().get(0); if (exprent.type == Exprent.EXPRENT_EXIT) { ExitExprent exit_exprent = (ExitExprent)exprent;
public static boolean splitIrreducibleNode(Statement statement) { Statement splitnode = getCandidateForSplitting(statement); if (splitnode == null) { return false; } StatEdge enteredge = splitnode.getPredecessorEdges(StatEdge.TYPE_REGULAR).iterator().next(); // copy the smallest statement Statement splitcopy = copyStatement(splitnode, null, new HashMap<>()); initCopiedStatement(splitcopy); // insert the copy splitcopy.setParent(statement); statement.getStats().addWithKey(splitcopy, splitcopy.id); // switch input edges for (StatEdge prededge : splitnode.getPredecessorEdges(Statement.STATEDGE_DIRECT_ALL)) { if (prededge.getSource() == enteredge.getSource() || prededge.closure == enteredge.getSource()) { splitnode.removePredecessor(prededge); prededge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, prededge, splitcopy); splitcopy.addPredecessor(prededge); } } // connect successors for (StatEdge succ : splitnode.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL)) { splitcopy.addSuccessor(new StatEdge(succ.getType(), splitcopy, succ.getDestination(), succ.closure)); } return true; }
public static void lowContinueLabels(Statement stat, HashSet<StatEdge> edges) { boolean ok = (stat.type != Statement.TYPE_DO); if (!ok) { DoStatement dostat = (DoStatement)stat; ok = dostat.getLooptype() == DoStatement.LOOP_DO || dostat.getLooptype() == DoStatement.LOOP_WHILE || (dostat.getLooptype() == DoStatement.LOOP_FOR && dostat.getIncExprent() == null); } if (ok) { edges.addAll(stat.getPredecessorEdges(StatEdge.TYPE_CONTINUE)); } if (ok && stat.type == Statement.TYPE_DO) { for (StatEdge edge : edges) { if (stat.containsStatementStrict(edge.getSource())) { edge.getDestination().removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, stat); stat.addPredecessor(edge); stat.addLabeledEdge(edge); } } } for (Statement st : stat.getStats()) { if (st == stat.getFirst()) { lowContinueLabels(st, edges); } else { lowContinueLabels(st, new HashSet<>()); } } }
newstat.setExprents(Arrays.asList(new Exprent[]{asexpr})); if (stat.iftype == IfStatement.IFTYPE_IFELSE || (first.getExprents() != null && !first.getExprents().isEmpty())) { first.removeSuccessor(stat.getIfEdge()); first.removeSuccessor(stat.getElseEdge()); if (first.getExprents() != null && !first.getExprents().isEmpty()) { lstStatements.add(first); sequence.getStats().get(i).addSuccessor(new StatEdge(StatEdge.TYPE_REGULAR, sequence.getStats().get(i), sequence.getStats().get(i + 1))); List<StatEdge> lstSuccs = stmts.getAllSuccessorEdges(); if (!lstSuccs.isEmpty()) { StatEdge endedge = lstSuccs.get(0); newstat.getVarDefinitions().addAll(stat.getVarDefinitions()); parent.replaceStatement(stat, newstat);
List<StatEdge> lstFirstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL); for (int i = 0; i < lstFirstSuccs.size(); i++) { mapEdgeIndex.put(lstFirstSuccs.get(i), i == 0 ? lstFirstSuccs.size() : i); for (StatEdge edge : stat.getPredecessorEdges(StatEdge.TYPE_REGULAR)) { if (edge.getSource() == first) { lst.add(mapEdgeIndex.get(edge)); List<StatEdge> lstExitEdges = first.getSuccessorEdges(StatEdge.TYPE_BREAK | StatEdge.TYPE_CONTINUE); while (!lstExitEdges.isEmpty()) { StatEdge edge = lstExitEdges.get(0); HashSet<Statement> setPreds = new HashSet<>(stat.getNeighbours(StatEdge.TYPE_REGULAR, DIRECTION_BACKWARD)); setPreds.remove(first); List<Exprent> lstv = new ArrayList<>(lst.size()); List<StatEdge> lstSuccs = first.getSuccessorEdges(STATEDGE_DIRECT_ALL); for (Integer in : lst) { int index = in == lstSuccs.size() ? 0 : in; 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);
List<StatEdge> lstSuccs = ifstat.getIfstat().getAllSuccessorEdges(); ifdirect = !lstSuccs.isEmpty() && lstSuccs.get(0).getType() == StatEdge.TYPE_FINALLYEXIT || hasDirectEndEdge(ifstat.getIfstat(), from); Statement last = parent.type == Statement.TYPE_SEQUENCE ? parent.getStats().getLast() : ifstat; noelsestat = (last == ifstat); elsedirect = !last.getAllSuccessorEdges().isEmpty() && last.getAllSuccessorEdges().get(0).getType() == StatEdge.TYPE_FINALLYEXIT || hasDirectEndEdge(last, from); stelse.setAllParent(); ifstat.getFirst().addSuccessor(elseedge); ifstat.setElsestat(stelse); ifstat.setElseEdge(elseedge); stelse.setParent(ifstat); ifstat.getFirst().removeSuccessor(ifedge); ifstat.removeSuccessor(elseedge); ifstat.getFirst().addSuccessor(elseedge); ifstat.getFirst().removeSuccessor(ifedge); ifstat.getStats().removeWithKey(ifbranch.id); ifstat.setIfstat(null); ifstat.getFirst().addSuccessor(elseedge);
private static void removeLastEmptyStatement(DoStatement dostat, Statement stat) { if (stat == dostat.getFirst()) { BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock( DecompilerContext.getCounterContainer().getCounterAndIncrement(CounterContainer.STATEMENT_COUNTER))); bstat.setExprents(new ArrayList<>()); dostat.replaceStatement(stat, bstat); } else { for (StatEdge edge : stat.getAllPredecessorEdges()) { edge.getSource().changeEdgeType(Statement.DIRECTION_FORWARD, edge, StatEdge.TYPE_CONTINUE); stat.removePredecessor(edge); edge.getSource().changeEdgeNode(Statement.DIRECTION_FORWARD, edge, dostat); dostat.addPredecessor(edge); dostat.addLabeledEdge(edge); } // parent is a sequence statement stat.getParent().getStats().removeWithKey(stat.id); } }
public static boolean identifySecondaryFunctions(Statement stat, VarProcessor varProc) { if (stat.getExprents() == null) { Statement ifstat = ifelsestat.getIfstat(); if (ifelsestat.iftype == IfStatement.IFTYPE_IFELSE && ifstat.getExprents() != null && ifstat.getExprents().isEmpty() && (ifstat.getAllSuccessorEdges().isEmpty() || !ifstat.getAllSuccessorEdges().get(0).explicit)) { ifelsestat.setElsestat(null); if (ifelsestat.getAllSuccessorEdges().isEmpty() && !ifstat.getAllSuccessorEdges().isEmpty()) { StatEdge endedge = ifstat.getAllSuccessorEdges().get(0); ifstat.removeSuccessor(endedge); endedge.setSource(ifelsestat); if (endedge.closure != null) { ifelsestat.getParent().addLabeledEdge(endedge); ifelsestat.getFirst().removeSuccessor(ifelsestat.getIfEdge()); List<Object> lstObjects = new ArrayList<>(stat.getExprents() == null ? stat.getSequentialObjects() : stat.getExprents()); Exprent retexpr = identifySecondaryFunctions((Exprent)obj, true, varProc); if (retexpr != null) { if (stat.getExprents() == null) { stat.replaceExprent((Exprent)obj, retexpr); stat.getExprents().set(i, retexpr);