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)); }
/** * Given an object of actual type C (o = new C()), returns the method which will be called on an * o.f() invocation. */ public SootMethod resolveConcreteDispatch(SootClass concreteType, SootMethod m) { concreteType.checkLevel(SootClass.HIERARCHY); m.getDeclaringClass().checkLevel(SootClass.HIERARCHY); checkState(); if (concreteType.isInterface()) throw new RuntimeException("class needed!"); Iterator<SootClass> it = getSuperclassesOfIncluding(concreteType).iterator(); String methodSig = m.getSubSignature(); while (it.hasNext()) { SootClass c = it.next(); if (c.declaresMethod(methodSig) && isVisible(c, m)) { return c.getMethod(methodSig); } } throw new RuntimeException( "could not resolve concrete dispatch!\nType: " + concreteType + "\nMethod: " + m); }
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 }