00001 package edu.ksu.cis.bandera.jjjc.optimizer;
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 import java.io.*;
00036 import java.util.*;
00037
00038 import edu.ksu.cis.bandera.jjjc.node.*;
00039 import edu.ksu.cis.bandera.jjjc.analysis.*;
00040 import edu.ksu.cis.bandera.jjjc.codegenerator.*;
00041
00042 import ca.mcgill.sable.soot.*;
00043 import ca.mcgill.sable.soot.jimple.*;
00044
00045 public final class BooleanExpression extends DepthFirstAdapter {
00046 private JIJCCodeGenerator codeGenerator;
00047 private boolean foundComplement = false;
00048 private Vector currentStmts;
00049 private Jimple jimple = Jimple.v();
00050 private Value currentValue;
00051 private Stmt trueBranch;
00052 private Stmt falseBranch;
00053 private boolean switchedBranch = false;
00054
00055
00056
00057
00058 public BooleanExpression(JIJCCodeGenerator codeGenerator, Stmt trueBranch, Stmt falseBranch) {
00059 this.codeGenerator = codeGenerator;
00060 this.trueBranch = trueBranch;
00061 this.falseBranch = falseBranch;
00062 currentStmts = codeGenerator.getCurrentStmts();
00063 }
00064
00065
00066
00067
00068 public void caseAArrayAccessExp(AArrayAccessExp node) {
00069 Stmt prevTrueBranch = codeGenerator.trueBranch;
00070 Stmt prevFalseBranch = codeGenerator.falseBranch;
00071 codeGenerator.trueBranch = trueBranch;
00072 codeGenerator.falseBranch = falseBranch;
00073 node.apply(codeGenerator);
00074 codeGenerator.trueBranch = prevTrueBranch;
00075 codeGenerator.falseBranch = prevFalseBranch;
00076 currentValue = codeGenerator.getCurrentValue();
00077 if (foundComplement)
00078 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00079 else
00080 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00081 }
00082
00083
00084
00085
00086 public void caseAAssignmentExp(AAssignmentExp node) {
00087 Stmt prevTrueBranch = codeGenerator.trueBranch;
00088 Stmt prevFalseBranch = codeGenerator.falseBranch;
00089 codeGenerator.trueBranch = trueBranch;
00090 codeGenerator.falseBranch = falseBranch;
00091 node.apply(codeGenerator);
00092 codeGenerator.trueBranch = prevTrueBranch;
00093 codeGenerator.falseBranch = prevFalseBranch;
00094 currentValue = codeGenerator.getCurrentValue();
00095 if (foundComplement)
00096 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00097 else
00098 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00099 }
00100
00101
00102
00103
00104 public void caseABinaryExp(ABinaryExp node) {
00105 PBinaryOperator op = node.getBinaryOperator();
00106 if (op instanceof AOrBinaryOperator) {
00107 Stmt prevFalseBranch = falseBranch;
00108 falseBranch = jimple.newNopStmt();
00109 node.getFirst().apply(this);
00110 currentStmts.add(falseBranch);
00111 falseBranch = prevFalseBranch;
00112 node.getSecond().apply(this);
00113 } else
00114 if (op instanceof AAndBinaryOperator) {
00115 Stmt lastStmt = jimple.newNopStmt();
00116 node.getFirst().replaceBy(new AUnaryExp(new AComplementUnaryOperator(new TComplement()), (PExp) node.getFirst().clone()));
00117 PushComplement.push(node.getFirst());
00118 node.getFirst().apply(new BooleanExpression(codeGenerator, falseBranch, lastStmt));
00119 currentStmts.addElement(lastStmt);
00120 node.getSecond().apply(this);
00121 } else {
00122 Stmt prevTrueBranch = codeGenerator.trueBranch;
00123 Stmt prevFalseBranch = codeGenerator.falseBranch;
00124 codeGenerator.trueBranch = trueBranch;
00125 codeGenerator.falseBranch = falseBranch;
00126 node.apply(codeGenerator);
00127 codeGenerator.trueBranch = prevTrueBranch;
00128 codeGenerator.falseBranch = prevFalseBranch;
00129 }
00130 }
00131
00132
00133
00134
00135 public void caseAFalseBooleanLiteral(AFalseBooleanLiteral node) {
00136 currentStmts.addElement(jimple.newGotoStmt(falseBranch));
00137 }
00138
00139
00140
00141
00142 public void caseAFieldAccessExp(AFieldAccessExp node) {
00143 Stmt prevTrueBranch = codeGenerator.trueBranch;
00144 Stmt prevFalseBranch = codeGenerator.falseBranch;
00145 codeGenerator.trueBranch = trueBranch;
00146 codeGenerator.falseBranch = falseBranch;
00147 node.apply(codeGenerator);
00148 codeGenerator.trueBranch = prevTrueBranch;
00149 codeGenerator.falseBranch = prevFalseBranch;
00150 currentValue = codeGenerator.getCurrentValue();
00151 if (foundComplement)
00152 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00153 else
00154 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00155 }
00156
00157
00158
00159
00160 public void caseAInstanceofExp(AInstanceofExp node) {
00161 Stmt prevTrueBranch = codeGenerator.trueBranch;
00162 Stmt prevFalseBranch = codeGenerator.falseBranch;
00163 codeGenerator.trueBranch = trueBranch;
00164 codeGenerator.falseBranch = falseBranch;
00165 node.apply(codeGenerator);
00166 codeGenerator.trueBranch = prevTrueBranch;
00167 codeGenerator.falseBranch = prevFalseBranch;
00168 Value currentValue = codeGenerator.getCurrentValue();
00169
00170 if (foundComplement) {
00171 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00172 } else {
00173 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00174 }
00175 }
00176
00177
00178
00179
00180 public void caseANameExp(ANameExp node) {
00181 Stmt prevTrueBranch = codeGenerator.trueBranch;
00182 Stmt prevFalseBranch = codeGenerator.falseBranch;
00183 codeGenerator.trueBranch = trueBranch;
00184 codeGenerator.falseBranch = falseBranch;
00185 node.apply(codeGenerator);
00186 codeGenerator.trueBranch = prevTrueBranch;
00187 codeGenerator.falseBranch = prevFalseBranch;
00188 currentValue = codeGenerator.getCurrentValue();
00189 if (foundComplement)
00190 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00191 else
00192 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00193 }
00194
00195
00196
00197
00198 public void caseANameMethodInvocationExp(ANameMethodInvocationExp node) {
00199 Stmt prevTrueBranch = codeGenerator.trueBranch;
00200 Stmt prevFalseBranch = codeGenerator.falseBranch;
00201 codeGenerator.trueBranch = trueBranch;
00202 codeGenerator.falseBranch = falseBranch;
00203 node.apply(codeGenerator);
00204 codeGenerator.trueBranch = prevTrueBranch;
00205 codeGenerator.falseBranch = prevFalseBranch;
00206 currentValue = codeGenerator.getCurrentValue();
00207 if (foundComplement)
00208 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00209 else
00210 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00211 }
00212
00213
00214
00215
00216 public void caseAPrimaryMethodInvocationExp(APrimaryMethodInvocationExp node) {
00217 Stmt prevTrueBranch = codeGenerator.trueBranch;
00218 Stmt prevFalseBranch = codeGenerator.falseBranch;
00219 codeGenerator.trueBranch = trueBranch;
00220 codeGenerator.falseBranch = falseBranch;
00221 node.apply(codeGenerator);
00222 codeGenerator.trueBranch = prevTrueBranch;
00223 codeGenerator.falseBranch = prevFalseBranch;
00224 currentValue = codeGenerator.getCurrentValue();
00225 if (foundComplement)
00226 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00227 else
00228 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00229 }
00230
00231
00232
00233
00234 public void caseAQuestionExp(AQuestionExp node) {
00235 Stmt prevTrueBranch = codeGenerator.trueBranch;
00236 Stmt prevFalseBranch = codeGenerator.falseBranch;
00237 codeGenerator.trueBranch = trueBranch;
00238 codeGenerator.falseBranch = falseBranch;
00239 node.apply(codeGenerator);
00240 codeGenerator.trueBranch = prevTrueBranch;
00241 codeGenerator.falseBranch = prevFalseBranch;
00242 currentValue = codeGenerator.getCurrentValue();
00243 if (foundComplement)
00244 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00245 else
00246 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00247 }
00248
00249
00250
00251
00252 public void caseASuperMethodInvocationExp(ASuperMethodInvocationExp node) {
00253 Stmt prevTrueBranch = codeGenerator.trueBranch;
00254 Stmt prevFalseBranch = codeGenerator.falseBranch;
00255 codeGenerator.trueBranch = trueBranch;
00256 codeGenerator.falseBranch = falseBranch;
00257 node.apply(codeGenerator);
00258 codeGenerator.trueBranch = prevTrueBranch;
00259 codeGenerator.falseBranch = prevFalseBranch;
00260 currentValue = codeGenerator.getCurrentValue();
00261 if (foundComplement)
00262 currentStmts.addElement(jimple.newIfStmt(jimple.newEqExpr(currentValue, IntConstant.v(0)), trueBranch));
00263 else
00264 currentStmts.addElement(jimple.newIfStmt(jimple.newNeExpr(currentValue, IntConstant.v(0)), trueBranch));
00265 }
00266
00267
00268
00269
00270 public void caseATrueBooleanLiteral(ATrueBooleanLiteral node) {
00271 currentStmts.addElement(jimple.newGotoStmt(trueBranch));
00272 }
00273
00274
00275
00276
00277 public void caseAUnaryExp(AUnaryExp node) {
00278 PExp exp = node.getExp();
00279 if ("!".equals(node.getUnaryOperator().toString().trim())) {
00280 foundComplement = !foundComplement;
00281 exp.apply(this);
00282 foundComplement = !foundComplement;
00283 } else {
00284 Stmt prevTrueBranch = codeGenerator.trueBranch;
00285 Stmt prevFalseBranch = codeGenerator.falseBranch;
00286 codeGenerator.trueBranch = trueBranch;
00287 codeGenerator.falseBranch = falseBranch;
00288 exp.apply(codeGenerator);
00289 codeGenerator.trueBranch = prevTrueBranch;
00290 codeGenerator.falseBranch = prevFalseBranch;
00291 }
00292 }
00293 }