/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. * * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */ aspect Statements { public void Stmt.jimplify2(Body b) { } public void Block.jimplify2(Body b) { for(int i = 0; i < getNumStmt(); i++) getStmt(i).jimplify2(b); } public void EmptyStmt.jimplify2(Body b) { } syn lazy soot.jimple.Stmt LabeledStmt.label() = newLabel(); syn lazy soot.jimple.Stmt LabeledStmt.end_label() = newLabel(); public void LabeledStmt.jimplify2(Body b) { b.setLine(this); b.addLabel(label()); getStmt().jimplify2(b); b.addLabel(end_label()); } public void ExprStmt.jimplify2(Body b) { b.setLine(this); soot.Value value = getExpr().eval(b); if(value instanceof soot.jimple.InvokeExpr) { b.add(b.newInvokeStmt((soot.jimple.InvokeExpr)value, this)); } } syn lazy DefaultCase SwitchStmt.defaultCase() { for(int i= 0; i < getBlock().getNumStmt(); i++) { if(getBlock().getStmt(i) instanceof DefaultCase) return (DefaultCase)getBlock().getStmt(i); } return null; } syn lazy soot.jimple.Stmt SwitchStmt.end_label() = newLabel(); public void SwitchStmt.jimplify2(Body b) { soot.jimple.Stmt cond_label = newLabel(); soot.jimple.Stmt switch_label = newLabel(); b.setLine(this); b.add(b.newGotoStmt(cond_label, this)); getBlock().jimplify2(b); if(canCompleteNormally()) { b.setLine(this); b.add(b.newGotoStmt(end_label(), this)); } b.addLabel(cond_label); soot.Value expr = asImmediate(b, getExpr().eval(b)); TreeMap map = new TreeMap(); for(int i= 0; i < getBlock().getNumStmt(); i++) { if(getBlock().getStmt(i) instanceof ConstCase) { ConstCase ca = (ConstCase)getBlock().getStmt(i); map.put(new Integer(ca.getValue().constant().intValue()), ca); } } long low = map.isEmpty() ? 0 : ((Integer)map.firstKey()).intValue(); long high = map.isEmpty() ? 0 : ((Integer)map.lastKey()).intValue(); long tableSwitchSize = 8L + (high - low + 1L) * 4L; long lookupSwitchSize = 4L + map.size() * 8L; b.addLabel(switch_label); soot.jimple.Stmt defaultStmt = defaultCase() != null ? defaultCase().label() : end_label(); if(tableSwitchSize < lookupSwitchSize) { ArrayList targets = new ArrayList(); for(long i = low; i <= high; i++) { ConstCase ca = (ConstCase)map.get(new Integer((int)i)); if(ca != null) targets.add(ca.label()); else targets.add(defaultStmt); } b.setLine(this); b.add(b.newTableSwitchStmt(expr, (int)low, (int)high, targets, defaultStmt, this)); } else { ArrayList targets = new ArrayList(); ArrayList values = new ArrayList(); for(Iterator iter = map.values().iterator(); iter.hasNext(); ) { ConstCase ca = (ConstCase)iter.next(); targets.add(ca.label()); values.add(IntType.emitConstant(ca.getValue().constant().intValue())); } b.setLine(this); b.add(b.newLookupSwitchStmt(expr, values, targets, defaultStmt, this)); } b.addLabel(end_label()); } syn lazy soot.jimple.Stmt Case.label() = newLabel(); public void Case.jimplify2(Body b) { b.addLabel(label()); } syn lazy soot.jimple.Stmt IfStmt.else_branch_label() = newLabel(); syn lazy soot.jimple.Stmt IfStmt.then_branch_label() = newLabel(); public void IfStmt.jimplify2(Body b) { soot.jimple.Stmt endBranch = newLabel(); if(getCondition().isConstant()) { if(getCondition().isTrue()) getThen().jimplify2(b); else if(getCondition().isFalse() && hasElse()) getElse().jimplify2(b); } else { soot.jimple.Stmt elseBranch = else_branch_label(); soot.jimple.Stmt thenBranch = then_branch_label(); getCondition().emitEvalBranch(b); b.addLabel(thenBranch); getThen().jimplify2(b); if(getThen().canCompleteNormally() && hasElse()) { b.setLine(this); b.add(b.newGotoStmt(endBranch, this)); } b.addLabel(elseBranch); if(hasElse()) getElse().jimplify2(b); } if(getThen().canCompleteNormally() && hasElse()) b.addLabel(endBranch); } syn lazy soot.jimple.Stmt WhileStmt.cond_label() = newLabel(); syn lazy soot.jimple.Stmt WhileStmt.end_label() = newLabel(); syn lazy soot.jimple.Stmt WhileStmt.stmt_label() = newLabel(); public void WhileStmt.jimplify2(Body b) { b.addLabel(cond_label()); getCondition().emitEvalBranch(b); b.addLabel(stmt_label()); if(getCondition().canBeTrue()) { getStmt().jimplify2(b); if(getStmt().canCompleteNormally()) { b.setLine(this); b.add(b.newGotoStmt(cond_label(), this)); } } if(canCompleteNormally()) b.addLabel(end_label()); } syn lazy soot.jimple.Stmt DoStmt.begin_label() = newLabel(); syn lazy soot.jimple.Stmt DoStmt.cond_label() = newLabel(); syn lazy soot.jimple.Stmt DoStmt.end_label() = newLabel(); public void DoStmt.jimplify2(Body b) { b.addLabel(begin_label()); getStmt().jimplify2(b); b.addLabel(cond_label()); getCondition().emitEvalBranch(b); if(canCompleteNormally()) b.addLabel(end_label()); } syn lazy soot.jimple.Stmt ForStmt.cond_label() = newLabel(); syn lazy soot.jimple.Stmt ForStmt.begin_label() = newLabel(); syn lazy soot.jimple.Stmt ForStmt.update_label() = newLabel(); syn lazy soot.jimple.Stmt ForStmt.end_label() = newLabel(); public void ForStmt.jimplify2(Body b) { for (int i=0; i