00001 package edu.ksu.cis.bandera.jjjc.decompiler;
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 ca.mcgill.sable.soot.*;
00036 import ca.mcgill.sable.soot.jimple.*;
00037 import ca.mcgill.sable.util.*;
00038 import java.util.*;
00039 import edu.ksu.cis.bandera.jjjc.*;
00040 import ca.mcgill.sable.util.Iterator;
00041 import ca.mcgill.sable.util.LinkedList;
00042 import edu.ksu.cis.bandera.jext.*;
00043 import edu.ksu.cis.bandera.abstraction.*;
00044 import edu.ksu.cis.bandera.abstraction.util.*;
00045
00046
00047
00048
00049
00050
00051
00052
00053 public class DecompilerValueSwitch extends AbstractBanderaValueSwitch {
00054 private static DecompilerValueSwitch walker = new DecompilerValueSwitch();
00055 private Vector res = new Vector();
00056 private static boolean ifstmt = false;
00057 public DecompilerValueSwitch()
00058 {
00059 }
00060 public void caseAddExpr(AddExpr v)
00061 {
00062 res.add("(");
00063 evaluate(v.getOp1());
00064 res.add(" ");
00065 res.add("+");
00066 res.add(" ");
00067 evaluate(v.getOp2());
00068 res.add(")");
00069 }
00070 public void caseAndExpr(AndExpr v)
00071 {
00072 res.add("(");
00073 evaluate(v.getOp1());
00074 res.add(" ");
00075 res.add("&");
00076 res.add(" ");
00077 evaluate(v.getOp2());
00078 res.add(")");
00079 }
00080 public void caseArrayRef(ArrayRef v)
00081 {
00082 evaluate(v.getBase());
00083 res.add("[");
00084 evaluate(v.getIndex());
00085 res.add("]");
00086 }
00087 public void caseCastExpr(CastExpr v)
00088 {
00089 res.add("((");
00090 res.add(v.getType().toString());
00091 res.add(")");
00092 res.add(" ");
00093 evaluate(v.getOp());
00094 res.add(")");
00095 }
00096 public void caseCaughtExceptionRef(CaughtExceptionRef v)
00097 {
00098 res.add(v.toString());
00099 }
00100
00101
00102
00103 public void caseChooseExpr(ChooseExpr v) {
00104
00105
00106
00107
00108
00109
00110
00111
00112 res.add("Bandera.choose() ? 0 : 1");
00113 }
00114 public void caseCmpExpr(CmpExpr v)
00115 {
00116 res.add("/* CMP was added */");
00117 }
00118 public void caseCmpgExpr(CmpgExpr v)
00119 {
00120 res.add("/* CMPG was added */");
00121 }
00122 public void caseCmplExpr(CmplExpr v)
00123 {
00124 res.add("/* CMPL was added */");
00125 }
00126 public void caseDivExpr(DivExpr v)
00127 {
00128 res.add("(");
00129 evaluate(v.getOp1());
00130 res.add(" ");
00131 res.add("/");
00132 res.add(" ");
00133 evaluate(v.getOp2());
00134 res.add(")");
00135 }
00136 public void caseDoubleConstant(DoubleConstant v)
00137 {
00138 res.add(v.toString());
00139 }
00140 public void caseEqExpr(EqExpr v)
00141 {
00142 String sign = "==";
00143 Value leftOp = v.getOp1();
00144 Value rightOp = v.getOp2();
00145 String rightValue = rightOp.toString().trim();
00146
00147 if (ifstmt) { sign = "!="; ifstmt = false; }
00148 if (rightValue.equals("0"))
00149 {
00150 if (DecompilerInfo.isBool(leftOp))
00151 {
00152 if (sign.equals("=="))
00153 {
00154 res.add("!");
00155 }
00156 evaluate(leftOp);
00157 return;
00158 }
00159 }
00160 evaluate(leftOp);
00161 res.add(" ");
00162 res.add(sign);
00163 res.add(" ");
00164 evaluate(rightOp);
00165 }
00166 public void caseFloatConstant(FloatConstant v)
00167 {
00168 res.add(v.toString());
00169 }
00170 public void caseGeExpr(GeExpr v)
00171 {
00172 String sign = ">=";
00173 if (ifstmt) { ifstmt = false; sign = "<"; }
00174 evaluate(v.getOp1());
00175 res.add(" ");
00176 res.add(sign);
00177 res.add(" ");
00178 evaluate(v.getOp2());
00179 }
00180 public void caseGtExpr(GtExpr v)
00181 {
00182 String sign = ">";
00183 if (ifstmt) { ifstmt = false; sign = "<="; }
00184 evaluate(v.getOp1());
00185 res.add(" ");
00186 res.add(sign);
00187 res.add(" ");
00188 evaluate(v.getOp2());
00189 }
00190 public void caseInstanceFieldRef(InstanceFieldRef v)
00191 {
00192 evaluate(v.getBase());
00193 res.add(".");
00194 res.add(v.getField().getName());
00195 }
00196 public void caseInstanceOfExpr(InstanceOfExpr v)
00197 {
00198 evaluate(v.getOp());
00199 res.add(" ");
00200 res.add("instanceof");
00201 res.add(" ");
00202 res.add(v.getType().toString());
00203 }
00204 public void caseIntConstant(IntConstant v)
00205 {
00206 if (Decompiler.typeTable != null)
00207 {
00208 Abstraction lt = Decompiler.typeTable.get(v);
00209
00210 if (DecompilerUtil.isAbstracted(lt))
00211 {
00212 String tokName = AbstractionClassLoader.getTokenName(lt,v.value);
00213 String fullName = lt.getClass().getName();
00214 int lastDot = fullName.lastIndexOf(".");
00215 String pkgName = fullName.substring(0,lastDot);
00216 Decompiler.addImports(pkgName+".*");
00217 res.add(tokName);
00218 } else res.add(v.toString());
00219 } else res.add(v.toString());
00220 }
00221 public void caseInterfaceInvokeExpr(InterfaceInvokeExpr v)
00222 {
00223 caseNonStaticInvokeExpr(v);
00224 }
00225 private void caseInvokeExpr(InvokeExpr v)
00226 {
00227 int param = v.getArgCount();
00228
00229 SootMethod sm = v.getMethod();
00230 String methodName = sm.getName().trim();
00231
00232 if ((methodName.length()>0) && (!methodName.equals("<init>")))
00233 {
00234 res.add(".");
00235 res.add(methodName);
00236 }
00237 res.add("(");
00238
00239 for (int i=0; i<param; i++)
00240 {
00241 Value theParam = v.getArg(i);
00242 String paramType = sm.getParameterType(i).toString().trim();
00243
00244
00245 if ((theParam instanceof IntConstant) && (paramType.equals("boolean")))
00246 {
00247 String val = theParam.toString().trim();
00248 if (val.equals("0")) res.add("false");
00249 else if (val.equals("1")) res.add("true");
00250 else res.add("true /* Bug in JJJC. boolval = "+val+" */");
00251 } else
00252 {
00253 evaluate(theParam);
00254 }
00255 if (i!=param-1) res.add(",");
00256 }
00257
00258
00259 res.add(")");
00260 }
00261 public void caseLeExpr(LeExpr v)
00262 {
00263 String sign = "<=";
00264 if (ifstmt) { ifstmt = false; sign = ">"; }
00265 evaluate(v.getOp1());
00266 res.add(" ");
00267 res.add(sign);
00268 res.add(" ");
00269 evaluate(v.getOp2());
00270 }
00271 public void caseLengthExpr(LengthExpr v)
00272 {
00273 evaluate(v.getOp());
00274 res.add(".");
00275 res.add("length");
00276 }
00277 public void caseLocal(Local v)
00278 {
00279 res.add(v.getName().trim());
00280 }
00281 public void caseLongConstant(LongConstant v)
00282 {
00283 res.add(v.toString());
00284 }
00285 public void caseLtExpr(LtExpr v)
00286 {
00287 String sign = "<";
00288 if (ifstmt) { ifstmt = false; sign = ">="; }
00289 evaluate(v.getOp1());
00290 res.add(" ");
00291 res.add(sign);
00292 res.add(" ");
00293 evaluate(v.getOp2());
00294 }
00295 public void caseMulExpr(MulExpr v)
00296 {
00297 res.add("(");
00298 evaluate(v.getOp1());
00299 res.add(" ");
00300 res.add("*");
00301 res.add(" ");
00302 evaluate(v.getOp2());
00303 res.add(")");
00304 }
00305 public void caseNeExpr(NeExpr v)
00306 {
00307 String sign = "!=";
00308 Value leftOp = v.getOp1();
00309 Value rightOp = v.getOp2();
00310 String rightValue = rightOp.toString().trim();
00311
00312 if (ifstmt) { sign = "=="; ifstmt = false; }
00313 if (rightValue.equals("0"))
00314 {
00315 if (DecompilerInfo.isBool(leftOp))
00316 {
00317 if (sign.equals("=="))
00318 {
00319 res.add("!");
00320 }
00321 evaluate(leftOp);
00322 return;
00323 }
00324 }
00325 evaluate(leftOp);
00326 res.add(" ");
00327 res.add(sign);
00328 res.add(" ");
00329 evaluate(rightOp);
00330 }
00331 public void caseNegExpr(NegExpr v)
00332 {
00333 res.add("-");
00334 res.add(" ");
00335 evaluate(v.getOp());
00336 }
00337 public void caseNewArrayExpr(NewArrayExpr v)
00338 {
00339 res.add("new");
00340 res.add(" ");
00341 String baseType = v.getType().toString();
00342 while (baseType.endsWith("[]"))
00343 baseType = baseType.substring(0,baseType.length()-2);
00344 res.add(baseType);
00345 res.add("[");
00346 evaluate(v.getSize());
00347 res.add("]");
00348 }
00349 public void caseNewExpr(NewExpr v)
00350 {
00351 res.add("new");
00352 res.add(" ");
00353 res.add(v.getType().toString());
00354 }
00355 public void caseNewInvokeExpr(NewInvokeExpr v)
00356 {
00357 res.add("new");
00358 res.add(" ");
00359 res.add(v.getBaseType().toString());
00360 caseInvokeExpr(v);
00361 }
00362 public void caseNewMultiArrayExpr(NewMultiArrayExpr v)
00363 {
00364 int max = v.getSizeCount();
00365
00366 res.add("new");
00367 res.add(" ");
00368 res.add(v.getBaseType().toString());
00369
00370
00371 for (int i=0; i<max; i++)
00372 {
00373 res.add("[");
00374 evaluate(v.getSize(i));
00375 res.add("]");
00376 }
00377 }
00378 private void caseNonStaticInvokeExpr(NonStaticInvokeExpr v)
00379 {
00380 evaluate(v.getBase());
00381 caseInvokeExpr(v);
00382 }
00383 public void caseNullConstant(NullConstant v)
00384 {
00385
00386 res.add("null");
00387 }
00388 public void caseOrExpr(OrExpr v)
00389 {
00390 res.add("(");
00391 evaluate(v.getOp1());
00392 res.add(" ");
00393 res.add("|");
00394 res.add(" ");
00395 evaluate(v.getOp2());
00396 res.add(")");
00397 }
00398 public void caseParameterRef(ParameterRef v)
00399 {
00400 res.add(v.toString());
00401 }
00402 public void caseRemExpr(RemExpr v)
00403 {
00404 res.add("(");
00405 evaluate(v.getOp1());
00406 res.add(" ");
00407 res.add("%");
00408 res.add(" ");
00409 evaluate(v.getOp2());
00410 res.add(")");
00411 }
00412 public void caseShlExpr(ShlExpr v)
00413 {
00414 res.add("(");
00415 evaluate(v.getOp1());
00416 res.add(" ");
00417 res.add("<<");
00418 res.add(" ");
00419 evaluate(v.getOp2());
00420 res.add(")");
00421 }
00422 public void caseShrExpr(ShrExpr v)
00423 {
00424 res.add("(");
00425 evaluate(v.getOp1());
00426 res.add(" ");
00427 res.add(">>");
00428 res.add(" ");
00429 evaluate(v.getOp2());
00430 res.add(")");
00431 }
00432 public void caseSpecialInvokeExpr(SpecialInvokeExpr v)
00433 {
00434 caseNonStaticInvokeExpr(v);
00435 }
00436 public void caseStaticFieldRef(StaticFieldRef v)
00437 {
00438 SootField sf = v.getField();
00439 String clsName = sf.getDeclaringClass().getName().trim();
00440 String fieldname = v.getField().getName().trim();
00441 if (!clsName.equals(DecompilerInfo.getClassName()))
00442 {
00443 res.add(clsName);
00444 res.add(".");
00445 }
00446 res.add(fieldname);
00447 }
00448 public void caseStaticInvokeExpr(StaticInvokeExpr v)
00449 {
00450 res.add(v.getMethod().getDeclaringClass().getName());
00451 caseInvokeExpr(v);
00452 }
00453 public void caseStringConstant(StringConstant v)
00454 {
00455 res.add(v.toString());
00456 }
00457 public void caseSubExpr(SubExpr v)
00458 {
00459 res.add("(");
00460 evaluate(v.getOp1());
00461 res.add(" ");
00462 res.add("-");
00463 res.add(" ");
00464 evaluate(v.getOp2());
00465 res.add(")");
00466 }
00467 public void caseThisRef(ThisRef v)
00468 {
00469 res.add("this");
00470 }
00471 public void caseUshrExpr(UshrExpr v)
00472 {
00473 res.add("(");
00474 evaluate(v.getOp1());
00475 res.add(" ");
00476 res.add(">>>");
00477 res.add(" ");
00478 evaluate(v.getOp2());
00479 res.add(")");
00480 }
00481 public void caseVirtualInvokeExpr(VirtualInvokeExpr v)
00482 {
00483 caseNonStaticInvokeExpr(v);
00484 }
00485 public void caseXorExpr(XorExpr v)
00486 {
00487 res.add("(");
00488 evaluate(v.getOp1());
00489 res.add(" ");
00490 res.add("^");
00491 res.add(" ");
00492 evaluate(v.getOp2());
00493 res.add(")");
00494 }
00495 public void defaultCase(Object v)
00496 {
00497
00498 res.add("/* Default case: Probably some error! */");
00499 }
00500 public static Vector evaluate(Value v)
00501 {
00502 if (v==null) return new Vector();
00503 v.apply(walker);
00504 return walker.getRes();
00505 }
00506 private Vector getRes()
00507 {
00508 return res;
00509 }
00510 public static void isAnIfStmt(boolean b) { ifstmt = b; }
00511 public static void reset()
00512 {
00513 walker.res = new Vector();
00514 }
00515 }