/** * Utility method used in the construction of {@link UnitGraph}s, to be called only after the * unitToPreds and unitToSuccs maps have been built. * * <p><code>UnitGraph</code> provides an implementation of <code>buildHeadsAndTails()</code> which * defines the graph's set of heads to include the first {@link Unit} in the graph's body, * together with any other <tt>Unit</tt> which has no predecessors. It defines the graph's set of * tails to include all <tt>Unit</tt>s with no successors. Subclasses of <code>UnitGraph</code> * may override this method to change the criteria for classifying a node as a head or tail. */ protected void buildHeadsAndTails() { List tailList = new ArrayList(); List headList = new ArrayList(); for (Iterator unitIt = unitChain.iterator(); unitIt.hasNext(); ) { Unit s = (Unit) unitIt.next(); List succs = (List) unitToSuccs.get(s); if (succs.size() == 0) { tailList.add(s); } List preds = (List) unitToPreds.get(s); if (preds.size() == 0) { headList.add(s); } } // Add the first Unit, even if it is the target of // a branch. Unit entryPoint = (Unit) unitChain.getFirst(); if (!headList.contains(entryPoint)) { headList.add(entryPoint); } tails = Collections.unmodifiableList(tailList); heads = Collections.unmodifiableList(headList); }
public void staticBlockInlining(SootClass sootClass) { this.sootClass = sootClass; // retrieve the clinit method if any for sootClass if (!sootClass.declaresMethod("void <clinit>()")) { System.out.println("no clinit"); return; } SootMethod clinit = sootClass.getMethod("void <clinit>()"); // System.out.println(clinit); // retireve the active body if (!clinit.hasActiveBody()) throw new RuntimeException("method " + clinit.getName() + " has no active body!"); Body clinitBody = clinit.getActiveBody(); Chain units = ((DavaBody) clinitBody).getUnits(); if (units.size() != 1) { throw new RuntimeException("DavaBody AST doesn't have single root."); } ASTNode AST = (ASTNode) units.getFirst(); if (!(AST instanceof ASTMethodNode)) throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode"); AST.apply(new MethodCallFinder(this)); }
public ASTMethodNode inline(SootMethod maybeInline) { // check if this method should be inlined if (sootClass != null) { // 1, method should belong to the same class as the clinit method if (sootClass.declaresMethod(maybeInline.getSubSignature())) { // System.out.println("The method invoked is from the same class"); // 2, method should be static if (Modifier.isStatic(maybeInline.getModifiers())) { // decided to inline // send the ASTMethod node of the TO BE INLINED METHOD // retireve the active body if (!maybeInline.hasActiveBody()) throw new RuntimeException("method " + maybeInline.getName() + " has no active body!"); Body bod = maybeInline.getActiveBody(); Chain units = ((DavaBody) bod).getUnits(); if (units.size() != 1) { throw new RuntimeException("DavaBody AST doesn't have single root."); } ASTNode ASTtemp = (ASTNode) units.getFirst(); if (!(ASTtemp instanceof ASTMethodNode)) throw new RuntimeException("Starting node of DavaBody AST is not an ASTMethodNode"); // restricting to methods which do not have any variables declared ASTMethodNode toReturn = (ASTMethodNode) ASTtemp; ASTStatementSequenceNode declarations = toReturn.getDeclarations(); if (declarations.getStatements().size() == 0) { // inline only if there are no declarations in the method inlined System.out.println("No declarations in the method. we can inline this method"); return toReturn; } } } } return null; // meaning dont inline }
/** Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>. */ private void printStatementsInBody( Body body, java.io.PrintWriter out, LabeledUnitPrinter up, UnitGraph unitGraph) { Chain units = body.getUnits(); Iterator unitIt = units.iterator(); Unit currentStmt = null, previousStmt; while (unitIt.hasNext()) { previousStmt = currentStmt; currentStmt = (Unit) unitIt.next(); // Print appropriate header. { // Put an empty line if the previous node was a branch node, the current node is a join node // or the previous statement does not have body statement as a successor, or if // body statement has a label on it if (currentStmt != units.getFirst()) { if (unitGraph.getSuccsOf(previousStmt).size() != 1 || unitGraph.getPredsOf(currentStmt).size() != 1 || up.labels().containsKey(currentStmt)) { up.newline(); } else { // Or if the previous node does not have body statement as a successor. List succs = unitGraph.getSuccsOf(previousStmt); if (succs.get(0) != currentStmt) { up.newline(); } } } if (up.labels().containsKey(currentStmt)) { up.unitRef(currentStmt, true); up.literal(":"); up.newline(); } if (up.references().containsKey(currentStmt)) { up.unitRef(currentStmt, false); } } up.startUnit(currentStmt); currentStmt.toString(up); up.endUnit(currentStmt); up.literal(";"); up.newline(); // only print them if not generating attributes files // because they mess up line number // if (!addJimpleLn()) { if (Options.v().print_tags_in_output()) { Iterator tagIterator = currentStmt.getTags().iterator(); while (tagIterator.hasNext()) { Tag t = (Tag) tagIterator.next(); up.noIndent(); up.literal("/*"); up.literal(t.toString()); up.literal("*/"); up.newline(); } /*Iterator udIt = currentStmt.getUseAndDefBoxes().iterator(); while (udIt.hasNext()) { ValueBox temp = (ValueBox)udIt.next(); Iterator vbtags = temp.getTags().iterator(); while (vbtags.hasNext()) { Tag t = (Tag) vbtags.next(); up.noIndent(); up.literal("VB Tag: "+t.toString()); up.newline(); } }*/ } } out.print(up.toString()); if (addJimpleLn()) { setJimpleLnNum(up.getPositionTagger().getEndLn()); } // Print out exceptions { Iterator trapIt = body.getTraps().iterator(); if (trapIt.hasNext()) { out.println(); incJimpleLnNum(); } while (trapIt.hasNext()) { Trap trap = (Trap) trapIt.next(); out.println( " catch " + Scene.v().quotedNameOf(trap.getException().getName()) + " from " + up.labels().get(trap.getBeginUnit()) + " to " + up.labels().get(trap.getEndUnit()) + " with " + up.labels().get(trap.getHandlerUnit()) + ";"); incJimpleLnNum(); } } }