protected void internalTransform(Body body, String phaseName, Map options) { if (Options.v().verbose()) G.v().out.println("[" + body.getMethod().getName() + "] Tightening trap boundaries..."); Chain trapChain = body.getTraps(); Chain unitChain = body.getUnits(); if (trapChain.size() > 0) { ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body); for (Iterator trapIt = trapChain.iterator(); trapIt.hasNext(); ) { Trap trap = (Trap) trapIt.next(); Unit firstTrappedUnit = trap.getBeginUnit(); Unit firstTrappedThrower = null; Unit firstUntrappedUnit = trap.getEndUnit(); Unit lastTrappedUnit = (Unit) unitChain.getPredOf(firstUntrappedUnit); Unit lastTrappedThrower = null; for (Unit u = firstTrappedUnit; u != null && u != firstUntrappedUnit; u = (Unit) unitChain.getSuccOf(u)) { if (mightThrowTo(graph, u, trap)) { firstTrappedThrower = u; break; } } if (firstTrappedThrower != null) { for (Unit u = lastTrappedUnit; u != null; u = (Unit) unitChain.getPredOf(u)) { if (mightThrowTo(graph, u, trap)) { lastTrappedThrower = u; break; } } } if (firstTrappedThrower != null && firstTrappedUnit != firstTrappedThrower) { trap.setBeginUnit(firstTrappedThrower); } if (lastTrappedThrower == null) { lastTrappedThrower = firstTrappedUnit; } if (lastTrappedUnit != lastTrappedThrower) { trap.setEndUnit((Unit) unitChain.getSuccOf(lastTrappedThrower)); } } } }
void doWeave( SootMethod method, LocalGeneratorEx lg, AdviceApplication adviceappl, Residue residue, WeavingContext wc) { AdviceInliner.v().addShadowMethod(method); ShadowPoints shadowpoints = adviceappl.shadowmatch.sp; AbstractAdviceDecl advicedecl = adviceappl.advice; Body b = method.getActiveBody(); Chain units = b.getUnits().getNonPatchingChain(); // end of shadow Stmt endshadow = shadowpoints.getEnd(); NopStmt nop2 = Jimple.v().newNopStmt(); GotoStmt goto1 = Jimple.v().newGotoStmt(nop2); if (advicedecl instanceof CflowSetup) { Tagger.tagStmt(goto1, InstructionKindTag.CFLOW_EXIT); } else if (advicedecl instanceof PerCflowSetup) { Tagger.tagStmt(goto1, InstructionKindTag.PERCFLOW_EXIT); } else if (advicedecl instanceof DeclareSoft) { Tagger.tagStmt(goto1, InstructionKindTag.EXCEPTION_SOFTENER); } else if (advicedecl instanceof DeclareMessage) { Tagger.tagStmt(goto1, InstructionKindTag.DECLARE_MESSAGE); } else { Tagger.tagStmt(goto1, InstructionKindTag.AFTER_THROWING_HANDLER); } Tagger.tagStmt(goto1, new InstructionSourceTag(advicedecl.sourceId)); Tagger.tagStmt(goto1, new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); units.insertBefore(nop2, endshadow); units.insertBefore(goto1, nop2); // have ... // goto1: goto nop2; // nop2: nop; // endshadow: nop; RefType catchType = getCatchType(); Local exception = lg.generateLocal(catchType, "exception"); bindException(wc, advicedecl, exception); CaughtExceptionRef exceptRef = Jimple.v().newCaughtExceptionRef(); IdentityStmt idStmt = Jimple.v().newIdentityStmt(exception, exceptRef); units.insertAfter(idStmt, goto1); ThrowStmt throwStmt = Jimple.v().newThrowStmt(exception); throwStmt.addTag(new ThrowCreatedByCompilerTag()); if (advicedecl instanceof CflowSetup) { Tagger.tagStmt(throwStmt, InstructionKindTag.CFLOW_EXIT); } else if (advicedecl instanceof PerCflowSetup) { Tagger.tagStmt(throwStmt, InstructionKindTag.PERCFLOW_EXIT); } else if (advicedecl instanceof DeclareSoft) { Tagger.tagStmt(throwStmt, InstructionKindTag.EXCEPTION_SOFTENER); } else if (advicedecl instanceof DeclareMessage) { Tagger.tagStmt(throwStmt, InstructionKindTag.DECLARE_MESSAGE); } else { Tagger.tagStmt(throwStmt, InstructionKindTag.AFTER_THROWING_HANDLER); } Tagger.tagStmt(throwStmt, new InstructionSourceTag(advicedecl.sourceId)); Tagger.tagStmt(throwStmt, new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); // store shadow/source tag for this residue in weaving context if (advicedecl instanceof CflowSetup) { wc.setKindTag(InstructionKindTag.CFLOW_TEST); } if (advicedecl instanceof PerCflowSetup) { wc.setKindTag(InstructionKindTag.CFLOW_TEST); } wc.setShadowTag(new InstructionShadowTag(adviceappl.shadowmatch.shadowId)); wc.setSourceTag(new InstructionSourceTag(adviceappl.advice.sourceId)); Stmt endresidue = residue.codeGen(method, lg, units, idStmt, throwStmt, true, wc); // have ... // java.lang.Exception exception; // // goto1: goto nop2; // idStmt: exception := @caughtexception // nop2: nop; // endshadow: nop; units.insertAfter(throwStmt, endresidue); Chain invokestmts = advicedecl.makeAdviceExecutionStmts(adviceappl, lg, wc); for (Iterator stmtlist = invokestmts.iterator(); stmtlist.hasNext(); ) { Stmt nextstmt = (Stmt) stmtlist.next(); units.insertBefore(nextstmt, throwStmt); } if (method.getName().equals("<clinit>")) // have to handle case of ExceptionInInitialzerError { // if (exception instanceof java.lang.ExceptionInIntializerError) // throw (exception); debug("Adding extra check in clinit"); Local isInitError = lg.generateLocal(soot.BooleanType.v(), "isInitError"); Stmt assignbool = Jimple.v() .newAssignStmt( isInitError, Jimple.v() .newInstanceOfExpr( exception, RefType.v("java.lang.ExceptionInInitializerError"))); Stmt ifstmt = Jimple.v().newIfStmt(Jimple.v().newNeExpr(isInitError, IntConstant.v(0)), throwStmt); // ThrowStmt throwInitError = Jimple.v().newThrowStmt(exception); // units.insertAfter(throwInitError, idStmt); units.insertAfter(ifstmt, idStmt); units.insertAfter(assignbool, idStmt); } Stmt beginshadow = shadowpoints.getBegin(); Stmt begincode = (Stmt) units.getSuccOf(beginshadow); // have ... // java.lang.Exception exception; // <AspectType> theAspect; // // beginshadow: nop // begincode: <some statement> // .... <stuff in between> // goto1: goto nop2; // idStmt: exception := @caughtexception; // assignStmt: theAspect = new AspectOf(); // .... invoke statements .... // throwStmt: throw exception; // nop2: nop; // endshadow: nop; Chain traps = b.getTraps(); Trap t = traps.size() > 0 ? (Trap) traps.getFirst() : null; // assume no exception ranges overlap with this one; make sure // we go after any that would be enclosed within this one. while (t != null && (units.follows(t.getBeginUnit(), begincode) || (t.getBeginUnit() == begincode && units.follows(idStmt, t.getEndUnit())))) t = (Trap) traps.getSuccOf(t); Trap newt = Jimple.v().newTrap(catchType.getSootClass(), begincode, idStmt, idStmt); if (t == null) traps.addLast(newt); else traps.insertBefore(newt, t); // added // catch java.lang.Throwable // from begincode upto idStmt handlewith idStmt } // method doWeave