0001: package net.sf.jdec.core;
0002:
0003: import net.sf.jdec.blockhelpers.IFHelper;
0004: import net.sf.jdec.blockhelpers.LoopHelper;
0005: import net.sf.jdec.blockhelpers.TryHelper;
0006: import net.sf.jdec.blocks.IFBlock;
0007: import net.sf.jdec.config.Configuration;
0008: import net.sf.jdec.constantpool.ClassDescription;
0009: import net.sf.jdec.constantpool.InterfaceMethodRef;
0010: import net.sf.jdec.constantpool.MethodRef;
0011: import net.sf.jdec.constantpool.CPString;
0012: import net.sf.jdec.io.Writer;
0013: import net.sf.jdec.lookup.FinderFactory;
0014: import net.sf.jdec.lookup.IFinder;
0015: import net.sf.jdec.main.ConsoleLauncher;
0016: import net.sf.jdec.reflection.Behaviour;
0017: import net.sf.jdec.util.ExecutionState;
0018: import net.sf.jdec.util.Util;
0019:
0020: import java.io.File;
0021: import java.util.*;
0022:
0023: /*
0024: * DecompilerHelper.java Copyright (c) 2006,07 Swaroop Belur
0025: *
0026: * This program is free software; you can redistribute it and/or
0027: * modify it under the terms of the GNU General Public License
0028: * as published by the Free Software Foundation; either version 2
0029: * of the License, or (at your option) any later version.
0030:
0031: * This program is distributed in the hope that it will be useful,
0032: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0033: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0034: * GNU General Public License for more details.
0035:
0036: * You should have received a copy of the GNU General Public License
0037: * along with this program; if not, write to the Free Software
0038: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0039: *
0040: */
0041: public class DecompilerHelper {
0042:
0043: private static final IFinder genericFinder = FinderFactory
0044: .getFinder(IFinder.BASE);
0045:
0046: /**
0047: * @param index
0048: * localvarindex
0049: * @param insttype
0050: * pass it as store or load
0051: * @return
0052: */
0053:
0054: // [NOTE:] THIS METHOD CAN RETURN NULL: SO HANDLE WITH CARE IN CALLING
0055: // METHOD....[belurs]
0056: public static LocalVariable getLocalVariable(int index,
0057: java.lang.String insttype, java.lang.String dataType,
0058: boolean simpleLoadStore, int instpos) {
0059: Behaviour behaviour = ExecutionState.getMethodContext();
0060: ClassDescription cd = behaviour.getClassRef().getCd();
0061: if (index < 0) {
0062: index += 256;
0063: }
0064: LocalVariable l = null;
0065: LocalVariableStructure structure = behaviour
0066: .getLocalVariables();
0067: if (cd.isClassCompiledWithMinusG()) {
0068: if (structure != null)// Just a double check.. Need not check
0069: // actually
0070: {
0071: int rangeIndex = -1;
0072: if (insttype.equals("store")) {
0073:
0074: if (simpleLoadStore == true)
0075: rangeIndex = instpos + 1;
0076: else
0077: rangeIndex = instpos + 2;
0078: LocalVariable var = structure.getVariabelAtIndex(
0079: index, rangeIndex);
0080: if (var == null) {
0081: Object o = cd
0082: .getMethod_name_storeNLoad_Map()
0083: .get(
0084: behaviour
0085: .getBehaviourName()
0086: .concat(
0087: behaviour
0088: .getStringifiedParameters()));
0089: if (o instanceof Hashtable) {
0090: Hashtable h = (Hashtable) o;
0091: if (h != null && h.size() > 0) {
0092: Integer il = (Integer) h
0093: .get(new Integer(instpos));
0094: if (il != null) {
0095: int loadpos = il.intValue();
0096: var = structure.getVariabelAtIndex(
0097: index, loadpos);
0098: }
0099: }
0100: }
0101: }
0102: if (var == null) {
0103: // Create a veriable here
0104: // This probably indicates the variables is unused in
0105: // code
0106: // TODO Fix Required over here
0107:
0108: var = new LocalVariable(
0109: behaviour
0110: .getBehaviourName()
0111: .concat(
0112: behaviour
0113: .getStringifiedParameters()),
0114: "Var_" + index, index);
0115: boolean duplicateVarName = isLocalVariableWithNameAlreadyPresent(
0116: "jdec_var_" + index, behaviour
0117: .getLocalVariables()
0118: .getMethodLocalVaribales());
0119: if (!duplicateVarName)
0120: var.setDeclarationGenerated(false);
0121: else
0122: var.setDeclarationGenerated(true);
0123: var.setDataType(dataType);
0124: var.setWasCreated(true);
0125: structure.addLocalVariable(var);
0126:
0127: }
0128: return var;
0129:
0130: } else // This is for load
0131: {
0132: LocalVariable var = structure.getVariabelAtIndex(
0133: index, instpos);
0134: if (var == null) {
0135: // NOT Sure what to do here// SHOULD NEVER COME
0136: // HERE.....
0137: // Possible due to a finally block
0138: try {
0139: Writer wr = Writer.getWriter("log");
0140: wr
0141: .writeLog("Could not obtain local variable While decompiling "
0142: + behaviour
0143: .getBehaviourName()
0144: .concat(
0145: behaviour
0146: .getStringifiedParameters()));
0147: wr.writeLog("\nDetails.......");
0148: wr.writeLog("\n[Index Pos " + index
0149: + ",Instruction Pos " + instpos
0150: + " INSTRUCTION CODE: "
0151: + behaviour.getCode()[instpos]
0152: + "]\n");
0153: wr.flush();
0154: } catch (Exception ex) {
0155: }
0156:
0157: }
0158: return var;
0159:
0160: }
0161:
0162: } else
0163: return null;
0164: } else {
0165: ConsoleLauncher.setCurrentClassCompiledWithDebugInfo(false);
0166: LocalVariable toreturn = null;
0167: if (behaviour.getLocalVariables() == null) // Again shud not
0168: // happen...
0169: {
0170: java.lang.String methodName = behaviour
0171: .getBehaviourName();
0172: structure = new LocalVariableStructure();
0173: behaviour.setMethodLocalVariables(structure);
0174: structure.setMethodDescription(methodName
0175: .concat(behaviour.getStringifiedParameters()));
0176: LocalVariableTable localVarTable = LocalVariableTable
0177: .getInstance();
0178: localVarTable.addEntry(methodName.concat(behaviour
0179: .getStringifiedParameters().concat(
0180: "" + behaviour.isMethodConstructor())),
0181: structure);
0182: }
0183: l = structure.getVariabelAtIndex(index, dataType, behaviour
0184: .getDatatypesForParams());
0185:
0186: LocalVariable tmp = null;
0187: if (l == null) // Create and Add
0188: {
0189: java.lang.String variableName = "Var" + "_" + instpos
0190: + "_" + index;
0191: if ((behaviour.getUserFriendlyMethodAccessors()
0192: .indexOf("static") == -1 && !behaviour
0193: .getBehaviourName().trim().equals("static"))
0194: && (index == 0))
0195: variableName = "this";
0196: l = new LocalVariable(behaviour.getBehaviourName()
0197: .concat(behaviour.getStringifiedParameters()),
0198: variableName, index);
0199: l.setDeclarationGenerated(false);
0200: l.setDataType(dataType);
0201: l.setWasCreated(true);
0202: structure.addLocalVariable(l);
0203: toreturn = l;
0204: l.setPassedDataTypeWhileCreatingWithOutMinusG(dataType);
0205:
0206: } else {
0207:
0208: if (structure.getNumberOfSimilarIndexVars(index) > 1) {
0209: Object o = cd
0210: .getMethod_name_storeNLoad_Map()
0211: .get(
0212: behaviour
0213: .getBehaviourName()
0214: .concat(
0215: behaviour
0216: .getStringifiedParameters()));
0217: if (o instanceof Hashtable) {
0218: Hashtable h = (Hashtable) o;
0219: if (h != null && h.size() > 0) {
0220: Integer il = (Integer) h.get(new Integer(
0221: instpos));
0222: if (il != null) {
0223: int loadpos = il.intValue();
0224: tmp = structure
0225: .getVariableForLoadOrStorePos(
0226: index, loadpos);
0227: }
0228: }
0229: }
0230:
0231: }
0232:
0233: if (tmp == null)
0234: toreturn = l;
0235: else
0236: toreturn = tmp;
0237:
0238: }
0239:
0240: java.lang.String dt = getStoredDataType(toreturn
0241: .getIndexPos(), behaviour.getDatatypesForParams());
0242: if (dt != null && dt.trim().length() != 0)
0243: toreturn.setDataType(dt.trim());
0244: if (behaviour.getUserFriendlyMethodAccessors().indexOf(
0245: "static") == -1
0246: && !behaviour.getBehaviourName().trim().equals(
0247: "static") && (toreturn.getIndexPos() == 0)) {
0248: if (toreturn.getVarName().equals("this") == false) {
0249: toreturn.setVarName("this");
0250: }
0251: }
0252: return toreturn;
0253:
0254: }
0255:
0256: }
0257:
0258: private static boolean isLocalVariableWithNameAlreadyPresent(
0259: java.lang.String name, ArrayList list) {
0260: boolean b = false;
0261: for (Iterator iter = list.iterator(); iter.hasNext();) {
0262: LocalVariable element = (LocalVariable) iter.next();
0263: if (element.getVarName().equals(name)) {
0264: b = true;
0265: break;
0266: }
0267: }
0268: return b;
0269: }
0270:
0271: private static java.lang.String getStoredDataType(int index,
0272: Map datatypesForParams) {
0273: java.lang.String dt = "";
0274: if (datatypesForParams != null && datatypesForParams.size() > 0) {
0275: return (java.lang.String) datatypesForParams
0276: .get(new Integer(index));
0277: }
0278: return dt;
0279:
0280: }
0281:
0282: private static boolean AmIPrimitive(java.lang.String className) {
0283: if (className.equals("I") || className.equals("B")
0284: || className.equals("C") || className.equals("S")
0285: || className.equals("F") || className.equals("D")
0286: || className.equals("J") || className.equals("Z")) {
0287: return true;
0288: } else
0289: return false;
0290:
0291: }
0292:
0293: // Copied from LocalVariable Class
0294: public static java.lang.String parse(java.lang.String input) {
0295: java.lang.String type = "";
0296: if (input.equals("I")) {
0297: type = "int";
0298: } else if (input.equals("B")) {
0299: type = "byte";
0300: } else if (input.equals("C")) {
0301: type = "char";
0302: } else if (input.equals("S")) {
0303: type = "short";
0304: } else if (input.equals("Z")) {
0305: type = "boolean";
0306: } else if (input.equals("F")) {
0307: type = "float";
0308: } else if (input.equals("D")) {
0309: type = "double";
0310: } else if (input.equals("J")) {
0311: type = "long";
0312: } else if (input.startsWith("L")) {
0313: type = input.substring(1);
0314: if (type.indexOf(";") != -1)
0315: type = type.substring(0, type.indexOf(";"));
0316: } else if (input.startsWith("[")) {
0317: int lastBracket = input.lastIndexOf("[");
0318: int objectType = input.indexOf("L");
0319: java.lang.String className = "";
0320: if (objectType != -1)
0321: className = input.substring(objectType + 1);
0322: else
0323: className = input.substring(lastBracket + 1);
0324: if (className.indexOf(";") != -1)
0325: className = className.substring(0, className
0326: .indexOf(";"));
0327: boolean b = AmIPrimitive(className);
0328: if (b == true)
0329: type = parse(className);
0330: else {
0331: java.lang.String temp = "";
0332: for (int c = 0; c < lastBracket + 1; c++)
0333: temp += "[]";
0334: type = className + " " + temp;
0335: }
0336:
0337: } else {
0338: type = input;
0339: }
0340:
0341: return type;
0342:
0343: }
0344:
0345: public static boolean isInstDup(byte[] info, int cur) {
0346: return genericFinder.isInstDup(cur);
0347: }
0348:
0349: public static boolean isThisInstrStart(int pos) {
0350: return genericFinder.isThisInstrStart(pos);
0351:
0352: }
0353:
0354: public static boolean isAnewArrayEmbedded(int currentForIndex,
0355: byte[] info) {
0356:
0357: int prev = currentForIndex - 1;
0358: boolean b = false;
0359: int prevPos = getPrevStartCodePos(currentForIndex);
0360: if (prevPos < 0)
0361: return b;
0362: boolean cont = false;
0363: switch (info[prevPos]) {
0364: case JvmOpCodes.ICONST_0:
0365: case JvmOpCodes.ICONST_1:
0366: case JvmOpCodes.ICONST_2:
0367: case JvmOpCodes.ICONST_3:
0368: case JvmOpCodes.ICONST_4:
0369: case JvmOpCodes.ICONST_5:
0370: case JvmOpCodes.BIPUSH:
0371: case JvmOpCodes.SIPUSH:
0372: cont = true;
0373: break;
0374: }
0375: if (!cont)
0376: return b;
0377: cont = false;
0378: prevPos = getPrevStartCodePos(prevPos);
0379: if (prevPos < 0)
0380: return b;
0381: switch (info[prevPos]) {
0382: case JvmOpCodes.ICONST_0:
0383: case JvmOpCodes.ICONST_1:
0384: case JvmOpCodes.ICONST_2:
0385: case JvmOpCodes.ICONST_3:
0386: case JvmOpCodes.ICONST_4:
0387: case JvmOpCodes.ICONST_5:
0388: case JvmOpCodes.BIPUSH:
0389: case JvmOpCodes.SIPUSH:
0390: cont = true;
0391: break;
0392: }
0393: if (!cont)
0394: return b;
0395: prevPos = getPrevStartCodePos(prevPos);
0396: if (prevPos < 0)
0397: return b;
0398: for (int z = prevPos; z >= 0; z--) {
0399:
0400: if (!isThisInstrStart(z))
0401: continue;
0402: switch (info[z]) {
0403:
0404: case JvmOpCodes.ASTORE:
0405: case JvmOpCodes.ASTORE_0:
0406: case JvmOpCodes.ASTORE_1:
0407: case JvmOpCodes.ASTORE_2:
0408: case JvmOpCodes.ASTORE_3:
0409: return b;
0410: case JvmOpCodes.ANEWARRAY:
0411: return !b;
0412:
0413: }
0414:
0415: }
0416: return b;
0417:
0418: }
0419:
0420: // Duplicate Method
0421: private static int getPrevStartCodePos(int i) {
0422: int current = i;
0423: int z;
0424: for (z = current - 1; z >= 0; z--) {
0425:
0426: boolean ok = isThisInstrStart(z);
0427: if (ok) {
0428: return z;
0429: }
0430: }
0431: return z;
0432:
0433: }
0434:
0435: // example String s[]={"1","2"}
0436: public static boolean getArrayDimensionForAnewArrayCase(int current) {
0437:
0438: Behaviour behaviour = ExecutionState.getMethodContext();
0439: byte[] code = behaviour.getCode();
0440: ArrayList starts = behaviour.getInstructionStartPositions();
0441: int prev = getPrevStartCodePos(current);
0442: int size = -1;
0443: if (prev >= 0) {
0444:
0445: switch (code[prev]) {
0446: case JvmOpCodes.ICONST_0:
0447: size = 0;
0448: break;
0449: case JvmOpCodes.ICONST_1:
0450: size = 1;
0451: break;
0452: case JvmOpCodes.ICONST_2:
0453: size = 2;
0454: break;
0455: case JvmOpCodes.ICONST_3:
0456: size = 3;
0457: break;
0458: case JvmOpCodes.ICONST_4:
0459: size = 4;
0460: break;
0461: case JvmOpCodes.ICONST_5:
0462: size = 5;
0463: break;
0464:
0465: case JvmOpCodes.BIPUSH:
0466: size = code[(prev + 1)];
0467: break;
0468: case JvmOpCodes.SIPUSH:
0469: size = getGenericFinder().getOffset(prev);
0470: break;
0471:
0472: }
0473:
0474: if (size != -1) {
0475:
0476: if (isThisInstrStart((current + 3))) {
0477:
0478: int x = current + 3;
0479: if (code[x] == JvmOpCodes.DUP_X2
0480: || code[x] == JvmOpCodes.DUP
0481: || code[x] == JvmOpCodes.DUP2
0482: || code[x] == JvmOpCodes.DUP_X1
0483: || code[x] == JvmOpCodes.DUP2_X1
0484: || code[x] == JvmOpCodes.DUP2_X2) {
0485:
0486: return true;
0487:
0488: }
0489: }
0490:
0491: }
0492:
0493: }
0494:
0495: return false;
0496:
0497: }
0498:
0499: private static IFinder getGenericFinder() {
0500: return genericFinder;
0501: }
0502:
0503: private static IFinder getStoreFinder() {
0504: return FinderFactory.getFinder(IFinder.STORE);
0505: }
0506:
0507: public static boolean checkForPostIncrForLoadCase(byte[] info,
0508: int current, java.lang.String type, boolean insttype,
0509: int index, StringBuffer addsub) {
0510: boolean b = false;
0511: int next = -1;
0512: int[] skipsWRTPostIncr = GlobalVariableStore
0513: .getSkipsWRTPostIncr();
0514: int instPos = -1;
0515: int startFrom = -1;
0516: if (type.equals("category1")) {
0517: if (insttype) {
0518: next = current + 1 + 1;
0519: startFrom = next;
0520: } else {
0521: next = current + 1;
0522: startFrom = next;
0523: }
0524: if (info[next] == JvmOpCodes.DUP) {
0525: next = next + 1;
0526: if ((info[next] == JvmOpCodes.ICONST_1)
0527: || (info[next] == JvmOpCodes.FCONST_1)) {
0528: next = next + 1;
0529: if ((info[next] == JvmOpCodes.ISUB)
0530: || (info[next] == JvmOpCodes.FSUB)
0531: || (info[next] == JvmOpCodes.IADD)
0532: || (info[next] == JvmOpCodes.FADD)) {
0533: StringBuffer varindex = new StringBuffer("");
0534: boolean ok = getStoreFinder()
0535: .isNextInstructionPrimitiveStoreInst(
0536: next + 1, varindex);
0537: if (ok) {
0538: try {
0539: int x = Integer.parseInt(varindex
0540: .toString());
0541: if (x == index) {
0542: b = true;
0543: instPos = next + 1;
0544: if ((info[next] == JvmOpCodes.ISUB)
0545: || (info[next] == JvmOpCodes.FSUB)) {
0546: addsub.append("--");
0547: }
0548: if ((info[next] == JvmOpCodes.IADD)
0549: || (info[next] == JvmOpCodes.FADD)) {
0550: addsub.append("++");
0551: }
0552: }
0553: } catch (Exception exp) {
0554: b = false;
0555: }
0556: }
0557: }
0558:
0559: }
0560:
0561: }
0562:
0563: } else if (type.equals("category2")) {
0564: if (insttype) {
0565: next = current + 1 + 1;
0566: startFrom = next;
0567: } else {
0568: next = current + 1;
0569: startFrom = next;
0570: }
0571: if (info[next] == JvmOpCodes.DUP2) {
0572: next = next + 1;
0573: if ((info[next] == JvmOpCodes.LCONST_1)
0574: || (info[next] == JvmOpCodes.DCONST_1)) {
0575: next = next + 1;
0576: if ((info[next] == JvmOpCodes.LSUB)
0577: || (info[next] == JvmOpCodes.DSUB)
0578: || (info[next] == JvmOpCodes.LADD)
0579: || (info[next] == JvmOpCodes.DADD)) {
0580: StringBuffer varindex = new StringBuffer("");
0581: boolean ok = getStoreFinder()
0582: .isNextInstructionPrimitiveStoreInst(
0583: next + 1, varindex);
0584: if (ok) {
0585: try {
0586: int x = Integer.parseInt(varindex
0587: .toString());
0588: if (x == index) {
0589: b = true;
0590: instPos = next + 1;
0591: if ((info[next] == JvmOpCodes.LSUB)
0592: || (info[next] == JvmOpCodes.DSUB)) {
0593: addsub.append("--");
0594: }
0595: if ((info[next] == JvmOpCodes.LADD)
0596: || (info[next] == JvmOpCodes.DADD)) {
0597: addsub.append("++");
0598: }
0599: }
0600: } catch (Exception exp) {
0601: b = false;
0602: }
0603: }
0604: }
0605:
0606: }
0607:
0608: }
0609: }
0610:
0611: if (instPos != -1 && startFrom != -1) {
0612: int diff = (instPos - startFrom);
0613: skipsWRTPostIncr = new int[diff];
0614: int s = startFrom + 1;
0615: for (int i = 0; i < skipsWRTPostIncr.length; i++) {
0616: skipsWRTPostIncr[i] = s;
0617: s++;
0618: }
0619:
0620: }
0621: GlobalVariableStore.setSkipsWRTPostIncr(skipsWRTPostIncr);
0622: return b;
0623: }
0624:
0625: public static void checkForImport(java.lang.String input,
0626: StringBuffer sb) {
0627:
0628: if (input.indexOf("(") != -1) {
0629: sb.append(input);
0630: return;
0631: }
0632:
0633: if (input.indexOf(")") != -1) {
0634: sb.append(input);
0635: return;
0636: }
0637:
0638: if (input.indexOf("JdecGenerated") != -1) {
0639: sb.append(input);
0640: return;
0641: }
0642:
0643: // if(input.indexOf("$")!=-1){sb.append(input);return;};
0644: if (input.indexOf(".") == -1 && input.indexOf("/") == -1) {
0645: input = input.replaceAll("\\$", ".");
0646: sb.append(input);
0647: return;
0648: }
0649: if (Configuration.getShowImport().equalsIgnoreCase("false")) {
0650:
0651: sb.append(input);
0652: return;
0653: }
0654: if (Configuration.getShowImport().equalsIgnoreCase("true")) {
0655: java.lang.String simplename = "";
0656: java.lang.String fullName = input;
0657: int lastSlash = fullName.lastIndexOf("/");
0658: int dollar = input.lastIndexOf("$");
0659: java.lang.String sname = null;
0660: if (lastSlash != -1) {
0661: if (input.indexOf("$") != -1) {
0662: sname = input.substring(dollar + 1);
0663: input = input.replaceAll("\\$", "/");
0664: }
0665: } else {
0666: lastSlash = fullName.lastIndexOf(".");
0667: if (lastSlash != -1) {
0668: if (input.indexOf("$") != -1) {
0669: sname = input.substring(dollar + 1);
0670: input = input.replaceAll("\\$", ".");
0671: }
0672: }
0673: }
0674: if (lastSlash != -1) {
0675: if (sname == null)
0676: simplename = fullName.substring(lastSlash + 1);
0677: else
0678: simplename = sname;
0679: } else
0680: simplename = fullName;
0681: fullName = fullName.replace('/', '.');
0682: fullName = fullName.replaceAll("\\$", ".");
0683:
0684: StringBuffer fulltype = new StringBuffer();
0685: boolean present = LocalVariableHelper
0686: .simpleTypeAlreadyAddedToImports(simplename,
0687: fulltype);
0688: boolean addim = true;
0689: if (present) {
0690: if (fullName.trim().equals(fulltype.toString().trim())) {
0691: addim = true;
0692: } else {
0693: addim = false;
0694: }
0695: }
0696: if (addim) {
0697: ConsoleLauncher.addImportClass(fullName);
0698: sb.append(simplename);
0699: } else {
0700: sb.append(fullName);
0701: }
0702: return;
0703:
0704: }
0705: // Default
0706: sb.append(input);
0707: return;
0708:
0709: }
0710:
0711: public static boolean checkForStartOfCatch(int instructionPos,
0712: ArrayList methodTries) {
0713: return TryHelper.checkForStartOfCatch(instructionPos,
0714: methodTries);
0715: }
0716:
0717: public static class VariableAtFront {
0718: java.lang.String name;
0719:
0720: java.lang.String type;
0721:
0722: java.lang.String initial;
0723:
0724: public VariableAtFront(java.lang.String s1,
0725: java.lang.String s2, java.lang.String s3) {
0726: name = s1;
0727: type = s2;
0728: initial = s3;
0729: }
0730:
0731: public java.lang.String getInitial() {
0732: if (initial != null) {
0733: return initial;
0734: }
0735:
0736: if (type != null && type.equals("int")) {
0737: return "0";
0738: }
0739: if (type != null && type.equals("boolean")) {
0740: return "false";
0741: }
0742: if (type != null && type.equals("float")) {
0743: return "0f";
0744: }
0745: if (type != null && type.equals("double")) {
0746: return "0d";
0747: }
0748: if (type != null && type.equals("long")) {
0749: return "0L";
0750: }
0751: if (type != null && type.equals("byte")) {
0752: return "0";
0753: }
0754: if (type != null && type.equals("short")) {
0755: return "0";
0756: }
0757: if (type != null && type.equals("char")) {
0758: return "(char)0";
0759: }
0760: return initial;
0761: }
0762:
0763: public java.lang.String getName() {
0764: return name;
0765: }
0766:
0767: public java.lang.String getType() {
0768: return type;
0769: }
0770:
0771: }
0772:
0773: public static VariableAtFront newVariableAtFront(
0774: java.lang.String name, java.lang.String type,
0775: java.lang.String initial) {
0776:
0777: return new VariableAtFront(name, type, initial);
0778:
0779: }
0780:
0781: public static boolean anydupstoreinternarybesidesthis (int current,
0782: byte[] info) {
0783: boolean yes = false;
0784: IFBlock iF = null;// getParentIFInTernaryList();
0785: if (iF == null)
0786: return false;
0787: int x = iF.getIfStart() + 3;
0788: while (x < current - 1) {
0789: if (getGenericFinder().isThisInstrStart(x)) {
0790: boolean dup = false;
0791: if (info[x] == JvmOpCodes.DUP
0792: || info[x] == JvmOpCodes.DUP2) {
0793: int next = x + 1;
0794: if (getStoreFinder().isStoreInst(next,
0795: new StringBuffer(""), new StringBuffer(""))) {
0796: return true;
0797: }
0798: }
0799: }
0800: x++;
0801:
0802: }
0803:
0804: return yes;
0805:
0806: }
0807:
0808: private static Behaviour getContext() {
0809: return ExecutionState.getMethodContext();
0810: }
0811:
0812: public static boolean isTernaryCondition(int i, byte[] info) {
0813: return false;
0814: }
0815:
0816: public static boolean addATHROWOutput(int i) {
0817: if (GlobalVariableStore.getAthrowmap().size() == 0)
0818: return true;
0819: Set entries = GlobalVariableStore.getAthrowmap().entrySet();
0820: Iterator it = entries.iterator();
0821: while (it.hasNext()) {
0822: Map.Entry entry = (Map.Entry) it.next();
0823: Integer pos = (Integer) entry.getKey();
0824: if (pos.intValue() == i) {
0825: java.lang.String str = (java.lang.String) entry
0826: .getValue();
0827: if (str.equals("true")) {
0828: return false;
0829: }
0830: }
0831: }
0832:
0833: return true;
0834:
0835: }
0836:
0837: public static boolean checkForArrayPostIncrement(int current,
0838: OperandStack stack, byte[] code, java.lang.String type,
0839: StringBuffer addtype) {
0840: boolean b = false;
0841:
0842: if (type.equals("category1")) {
0843:
0844: boolean proceed = checkAheadForArrayStore(current, code);
0845: if (proceed) {
0846: proceed = checkBeforeForAddSubInstruction(current,
0847: code, "category1", addtype);
0848: if (proceed) {
0849: return !b;
0850: } else {
0851: return b;
0852: }
0853: } else {
0854: return b;
0855: }
0856:
0857: } else if (type.equals("category2")) {
0858: boolean proceed = checkAheadForArrayStore(current, code);
0859: if (proceed) {
0860: proceed = checkBeforeForAddSubInstruction(current,
0861: code, "category2", addtype);
0862: if (proceed) {
0863: return !b;
0864: } else {
0865: return b;
0866: }
0867: } else {
0868: return b;
0869: }
0870: } else
0871: b = false;
0872: return b;
0873:
0874: }
0875:
0876: private static boolean checkAheadForArrayStore(int current,
0877: byte[] code) {
0878:
0879: boolean b = false;
0880: int pos = current + 1;
0881: boolean exit = false;
0882: boolean found = false;
0883: for (; pos < code.length; pos++) {
0884:
0885: boolean start = isThisInstrStart(pos);
0886: if (!start)
0887: continue;
0888: switch (code[pos]) {
0889: case JvmOpCodes.I2B:
0890: case JvmOpCodes.I2C:
0891: case JvmOpCodes.I2D:
0892: case JvmOpCodes.I2F:
0893: case JvmOpCodes.I2L:
0894: case JvmOpCodes.I2S:
0895: case JvmOpCodes.L2D:
0896: case JvmOpCodes.L2F:
0897: case JvmOpCodes.L2I:
0898: case JvmOpCodes.F2D:
0899: case JvmOpCodes.F2I:
0900: case JvmOpCodes.F2L:
0901: case JvmOpCodes.D2F:
0902: case JvmOpCodes.D2I:
0903: case JvmOpCodes.D2L: {
0904: exit = false;
0905: break;
0906: }
0907:
0908: case JvmOpCodes.DUP_X2:
0909: case JvmOpCodes.DUP2_X2: {
0910: exit = false;
0911: break;
0912: }
0913:
0914: case JvmOpCodes.IASTORE:
0915: case JvmOpCodes.BASTORE:
0916: case JvmOpCodes.CASTORE:
0917: case JvmOpCodes.SASTORE:
0918: case JvmOpCodes.FASTORE:
0919: case JvmOpCodes.LASTORE:
0920: case JvmOpCodes.DASTORE: {
0921: exit = true;
0922: found = true;
0923: break;
0924: }
0925:
0926: default: {
0927: exit = true;
0928: break;
0929: }
0930:
0931: }
0932: if (exit && !found) {
0933: b = false;
0934: break;
0935: }
0936: if (exit && found) {
0937: b = true;
0938: break;
0939: }
0940:
0941: }
0942: return b;
0943: }
0944:
0945: private static boolean checkBeforeForAddSubInstruction(int current,
0946: byte[] code, java.lang.String type, StringBuffer addtype) {
0947: boolean b = false;
0948: int pos = current - 1;
0949: boolean exit = false;
0950: boolean found = false;
0951: ArrayList inststarts = getContext()
0952: .getInstructionStartPositions();
0953: if (type.equals("category2")) {
0954: for (; pos >= 0; pos--) {
0955: boolean start = isThisInstrStart(pos);
0956: if (!start)
0957: continue;
0958: switch (code[pos]) {
0959: case JvmOpCodes.I2B:
0960: case JvmOpCodes.I2C:
0961: case JvmOpCodes.I2D:
0962: case JvmOpCodes.I2F:
0963: case JvmOpCodes.I2L:
0964: case JvmOpCodes.I2S:
0965: case JvmOpCodes.L2D:
0966: case JvmOpCodes.L2F:
0967: case JvmOpCodes.L2I:
0968: case JvmOpCodes.F2D:
0969: case JvmOpCodes.F2I:
0970: case JvmOpCodes.F2L:
0971: case JvmOpCodes.D2F:
0972: case JvmOpCodes.D2I:
0973: case JvmOpCodes.D2L: {
0974: exit = false;
0975: break;
0976: }
0977:
0978: case JvmOpCodes.DUP_X2:
0979: case JvmOpCodes.DUP2_X2: {
0980: exit = true;
0981: break;
0982: }
0983:
0984: case JvmOpCodes.DADD:
0985: case JvmOpCodes.LADD: {
0986: exit = true;
0987: found = true;
0988: addtype.append("add");
0989: break;
0990: }
0991: case JvmOpCodes.DSUB:
0992: case JvmOpCodes.LSUB: {
0993: exit = true;
0994: found = true;
0995: addtype.append("sub");
0996: break;
0997: }
0998:
0999: default: {
1000: exit = true;
1001: break;
1002: }
1003:
1004: }
1005: if (exit && !found) {
1006: b = false;
1007: break;
1008: }
1009: if (exit && found) {
1010: b = true;
1011: break;
1012: }
1013:
1014: }
1015: } else if (type.equals("category1")) {
1016: for (; pos >= 0; pos--) {
1017: boolean start = isThisInstrStart(pos);
1018: if (!start)
1019: continue;
1020: switch (code[pos]) {
1021: case JvmOpCodes.I2B:
1022: case JvmOpCodes.I2C:
1023: case JvmOpCodes.I2D:
1024: case JvmOpCodes.I2F:
1025: case JvmOpCodes.I2L:
1026: case JvmOpCodes.I2S:
1027: case JvmOpCodes.L2D:
1028: case JvmOpCodes.L2F:
1029: case JvmOpCodes.L2I:
1030: case JvmOpCodes.F2D:
1031: case JvmOpCodes.F2I:
1032: case JvmOpCodes.F2L:
1033: case JvmOpCodes.D2F:
1034: case JvmOpCodes.D2I:
1035: case JvmOpCodes.D2L: {
1036: exit = false;
1037: break;
1038: }
1039:
1040: case JvmOpCodes.DUP_X2:
1041: case JvmOpCodes.DUP2_X2: {
1042: exit = true;
1043: break;
1044: }
1045:
1046: case JvmOpCodes.IADD:
1047: case JvmOpCodes.FADD: {
1048: exit = true;
1049: found = true;
1050: addtype.append("add");
1051: break;
1052: }
1053: case JvmOpCodes.ISUB:
1054: case JvmOpCodes.FSUB: {
1055: exit = true;
1056: found = true;
1057: addtype.append("sub");
1058: break;
1059: }
1060:
1061: default: {
1062: exit = true;
1063: break;
1064: }
1065:
1066: }
1067: if (exit && !found) {
1068: b = false;
1069: break;
1070: }
1071: if (exit && found) {
1072: b = true;
1073: break;
1074: }
1075:
1076: }
1077:
1078: }
1079:
1080: else
1081:
1082: b = false;
1083:
1084: return b;
1085: }
1086:
1087: public static boolean checkForArrayMultiAssignablePostIncrement(
1088: int current, OperandStack stack, byte[] code,
1089: java.lang.String type) {
1090: boolean b = false;
1091: if (type.equals("category1")) {
1092:
1093: boolean proceed = checkAheadForArrayStore(current, code);
1094: if (proceed) {
1095: proceed = checkBeforeForAddSubInstruction_Multi(
1096: current, code, "category1");
1097: if (proceed) {
1098: return !b;
1099: } else {
1100: return b;
1101: }
1102: } else {
1103: return b;
1104: }
1105:
1106: } else if (type.equals("category2")) {
1107: boolean proceed = checkAheadForArrayStore(current, code);
1108: if (proceed) {
1109: proceed = checkBeforeForAddSubInstruction_Multi(
1110: current, code, "category2");
1111: if (proceed) {
1112: return !b;
1113: } else {
1114: return b;
1115: }
1116: } else {
1117: return b;
1118: }
1119: } else
1120: b = false;
1121: return b;
1122:
1123: }
1124:
1125: // TODO: Refactor Method
1126: // Also Add more logic
1127: public static boolean checkBeforeForAddSubInstruction_Multi(
1128: int current, byte[] code, java.lang.String type) {
1129: boolean b = false;
1130: int pos = current - 1;
1131: boolean exit = false;
1132: boolean found = false;
1133: ArrayList inststarts = getContext()
1134: .getInstructionStartPositions();
1135: if (type.equals("category2")) {
1136: for (; pos >= 0; pos--) {
1137: boolean start = isThisInstrStart(pos);
1138: if (!start)
1139: continue;
1140: switch (code[pos]) {
1141: case JvmOpCodes.I2B:
1142: case JvmOpCodes.I2C:
1143: case JvmOpCodes.I2D:
1144: case JvmOpCodes.I2F:
1145: case JvmOpCodes.I2L:
1146: case JvmOpCodes.I2S:
1147: case JvmOpCodes.L2D:
1148: case JvmOpCodes.L2F:
1149: case JvmOpCodes.L2I:
1150: case JvmOpCodes.F2D:
1151: case JvmOpCodes.F2I:
1152: case JvmOpCodes.F2L:
1153: case JvmOpCodes.D2F:
1154: case JvmOpCodes.D2I:
1155: case JvmOpCodes.D2L: {
1156: exit = false;
1157: break;
1158: }
1159:
1160: case JvmOpCodes.DUP_X2:
1161: case JvmOpCodes.DUP2_X2: {
1162: boolean ok = false;
1163: floop: for (int cur = pos - 1; cur >= 0; cur--) {
1164: start = isThisInstrStart(cur);
1165: if (start == false)
1166: continue;
1167: int inst = code[cur];
1168: switch (inst) {
1169: case JvmOpCodes.IASTORE:
1170: case JvmOpCodes.BASTORE:
1171: case JvmOpCodes.CASTORE:
1172: case JvmOpCodes.SASTORE:
1173: case JvmOpCodes.FASTORE:
1174: case JvmOpCodes.LASTORE:
1175: case JvmOpCodes.DASTORE: {
1176: ok = true;
1177: break floop;
1178: }
1179: }
1180: boolean b3 = getGenericFinder()
1181: .isCategory2AddSub(pos);
1182: if (b3) {
1183: ok = false;
1184: break;
1185: }
1186:
1187: }
1188: exit = true;
1189: if (ok) {
1190: found = true;
1191: } else {
1192: found = false;
1193: }
1194: break;
1195: }
1196:
1197: default: {
1198: exit = true;
1199: break;
1200: }
1201:
1202: }
1203: if (exit && !found) {
1204: b = false;
1205: break;
1206: }
1207: if (exit && found) {
1208: b = true;
1209: break;
1210: }
1211:
1212: }
1213: } else if (type.equals("category1")) {
1214: for (; pos >= 0; pos--) {
1215: boolean start = isThisInstrStart(pos);
1216: if (!start)
1217: continue;
1218: switch (code[pos]) {
1219: case JvmOpCodes.I2B:
1220: case JvmOpCodes.I2C:
1221: case JvmOpCodes.I2D:
1222: case JvmOpCodes.I2F:
1223: case JvmOpCodes.I2L:
1224: case JvmOpCodes.I2S:
1225: case JvmOpCodes.L2D:
1226: case JvmOpCodes.L2F:
1227: case JvmOpCodes.L2I:
1228: case JvmOpCodes.F2D:
1229: case JvmOpCodes.F2I:
1230: case JvmOpCodes.F2L:
1231: case JvmOpCodes.D2F:
1232: case JvmOpCodes.D2I:
1233: case JvmOpCodes.D2L: {
1234: exit = false;
1235: break;
1236: }
1237:
1238: case JvmOpCodes.DUP_X2:
1239: case JvmOpCodes.DUP2_X2: {
1240: boolean ok = false;
1241: floop: for (int cur = pos - 1; cur >= 0; cur--) {
1242: start = isThisInstrStart(cur);
1243: if (start == false)
1244: continue;
1245: int inst = code[cur];
1246: switch (inst) {
1247: case JvmOpCodes.IASTORE:
1248: case JvmOpCodes.BASTORE:
1249: case JvmOpCodes.CASTORE:
1250: case JvmOpCodes.SASTORE:
1251: case JvmOpCodes.FASTORE:
1252: case JvmOpCodes.LASTORE:
1253: case JvmOpCodes.DASTORE: {
1254: ok = true;
1255: break floop;
1256: }
1257: }
1258: boolean b3 = getGenericFinder()
1259: .isCategory1AddSub(pos);
1260: if (b3) {
1261: ok = false;
1262: break;
1263: }
1264:
1265: }
1266:
1267: exit = true;
1268: if (ok) {
1269: found = true;
1270: } else {
1271: found = false;
1272: }
1273: break;
1274: }
1275:
1276: default: {
1277: exit = true;
1278: break;
1279: }
1280:
1281: }
1282: if (exit && !found) {
1283: b = false;
1284: break;
1285: }
1286: if (exit && found) {
1287: b = true;
1288: break;
1289: }
1290:
1291: }
1292:
1293: }
1294:
1295: else
1296:
1297: b = false;
1298:
1299: return b;
1300: }
1301:
1302: // TODO: find where all this is called
1303: // send back a string abt cast like (byte) etc
1304: // and prepend to that String
1305: public static boolean isArrayElement(int i) {
1306:
1307: byte info[] = getContext().getCode();
1308: int current = i - 1;
1309: boolean dontadd = false;
1310: boolean b = isThisInstrStart(i);
1311: if (!b)
1312: return false;
1313: for (int z = i; z < info.length; z++) {
1314: b = isThisInstrStart(z);
1315: if (!b)
1316: return false;
1317: /*
1318: * switch(info[z]){ case JvmOpCodes.DUP: case JvmOpCodes.DUP2: case
1319: * JvmOpCodes.DUP_X1: case JvmOpCodes.DUP_X2: case
1320: * JvmOpCodes.DUP2_X1: case JvmOpCodes.DUP2_X2: return false; }
1321: */
1322: switch (info[z]) {
1323:
1324: case JvmOpCodes.IASTORE:
1325: case JvmOpCodes.BASTORE:
1326: case JvmOpCodes.SASTORE:
1327: case JvmOpCodes.CASTORE:
1328: case JvmOpCodes.FASTORE:
1329: case JvmOpCodes.LASTORE:
1330: case JvmOpCodes.DASTORE: {
1331: int prevpos1 = z - 1;
1332: int prevpos2 = z - 2;
1333: if (isThisInstrStart(prevpos1)
1334: && getStoreFinder().isInstPrimitiveArrayStore(
1335: info[prevpos1])
1336: && isThisInstrStart(prevpos2)
1337: && getGenericFinder().isInstructionAnyDUP(
1338: prevpos2)) {
1339: // return false;
1340: }
1341: if (!dontadd) {
1342: GlobalVariableStore.getSkipPrimitiveArrayStores()
1343: .add(new Integer(z));
1344: }
1345: return true;
1346:
1347: }
1348:
1349: }
1350:
1351: int j = getGenericFinder().isNextInstructionConversionInst(
1352: z, new StringBuffer());
1353: if (j != -1) {
1354: continue;
1355: } else {
1356: if (isThisInstrStart(z)
1357: && getGenericFinder().isInstructionAnyDUP(z)) {
1358: dontadd = true;
1359: continue;
1360: }
1361: break;
1362: }
1363:
1364: }
1365: return false;
1366:
1367: }
1368:
1369: // Primarily use it for goto and some special cases where appplicable
1370: public static int getJumpAddress(byte[] info, int counter) {
1371: return genericFinder.getJumpAddress(counter);
1372: }
1373:
1374: /*
1375: * public static int getIfCloseNumberForThisIF(byte[] info, int k) { return
1376: * IFHelper.getIfCloseNumberForThisIF(info, k); }
1377: */
1378:
1379: public static int findCodeIndexFromInfiniteLoop(IFBlock ifst,
1380: ArrayList loopTable, int codeIndex) {
1381: return LoopHelper.findCodeIndexFromInfiniteLoop(ifst,
1382: loopTable, codeIndex);
1383: }
1384:
1385: public static int getloopEndForStart(ArrayList list, int start) {
1386:
1387: return LoopHelper.getloopEndForStart(list, start);
1388:
1389: }
1390:
1391: public static boolean isByteCodeALoopStart(ArrayList loops,
1392: int bytecodeend) {
1393:
1394: return LoopHelper.isPositionALoopStart(loops, bytecodeend);
1395: }
1396:
1397: public static int checkLoopsAndSwitchForIfEnd(int end, IFBlock ifs,
1398: Behaviour behaviour) {
1399: byte[] info = behaviour.getCode();
1400: int reqdEnd = -1;
1401: ArrayList loops = behaviour.getBehaviourLoops();
1402: if (loops != null && loops.size() > 0) {
1403:
1404: Object[] sortedLoops = LoopHelper.sortLoops(loops);
1405: int parentLoopStart = LoopHelper.getParentLoopStartForIf(
1406: sortedLoops, ifs.getIfStart());
1407: int loopend = getloopEndForStart(loops, parentLoopStart);
1408: if (ifs.getIfStart() < loopend
1409: && (end > loopend || end < ifs.getIfStart()))
1410: ifs.setIfCloseLineNumber(loopend);
1411: reqdEnd = ifs.getIfCloseLineNumber();
1412:
1413: }
1414:
1415: ArrayList allswicthes = behaviour.getAllSwitchBlks();
1416: if (allswicthes != null && allswicthes.size() > 0) {
1417:
1418: int newifend = -1;
1419: newifend = IFHelper.resetEndofIFElseWRTSwitch(allswicthes,
1420: ifs, reqdEnd, ExecutionState
1421: .getCurrentInstructionPosition(), "if");
1422: boolean valid = IFHelper.isNewEndValid(newifend, ifs, "if",
1423: end);
1424: if (valid) {
1425: ifs.setIfCloseLineNumber(newifend);
1426: reqdEnd = ifs.getIfCloseLineNumber();
1427: // Need to check here for a goto before the case end
1428: int start = ifs.getIfStart();
1429: int bye = ifs.getIfCloseFromByteCode();
1430: ArrayList starts = behaviour
1431: .getInstructionStartPositions();
1432: for (int z = reqdEnd; z > start; z--) {
1433:
1434: int inst = info[z];
1435: boolean isSt = isThisInstrStart(z);
1436: if (isSt && (inst == JvmOpCodes.GOTO)
1437: && (getJumpAddress(info, z) == bye)) {
1438: reqdEnd = z;
1439: break;
1440: }
1441:
1442: }
1443:
1444: } else {
1445: if (ifs.getElseCloseLineNumber() == -1) {
1446: ifs.setIfCloseLineNumber(ifs
1447: .getIfCloseFromByteCode());
1448: reqdEnd = ifs.getIfCloseLineNumber();// here
1449: } else {
1450: reqdEnd = ifs.getIfCloseLineNumber();
1451: }
1452: }
1453:
1454: }
1455: return reqdEnd;
1456:
1457: }
1458:
1459: public static boolean checkForSizeOfArrayTimesStack() {
1460:
1461: if (GlobalVariableStore.getArraytimesstack().size() > 0) {
1462: return true;
1463: } else
1464: return false;
1465: }
1466:
1467: public static boolean prevNewPresent() {
1468: if (GlobalVariableStore.getNewfoundstack().size() < 2)
1469: return false;
1470: return true;
1471: }
1472:
1473: public static boolean skipGetStaticCall(byte[] info,
1474: int currentForIndex) {
1475: int n = currentForIndex + 3;
1476: if (n >= info.length)
1477: return false;
1478: int l = info.length;
1479: OperandStack opStack = getContext().getOpStack();
1480: ClassDescription cd = getContext().getClassRef().getCd();
1481: if (info[n] == JvmOpCodes.DUP || info[n] == JvmOpCodes.DUP2) {
1482: n = n + 1;
1483: boolean b = getGenericFinder().isThisInstrStart(n);
1484: if (b) {
1485:
1486: boolean isif = info[n] == JvmOpCodes.IFNONNULL;
1487: if (isif) {
1488: int j = getJumpAddress(info, n);
1489: if (j < n)
1490: return false;
1491: boolean ok = getGenericFinder().isThisInstrStart(j);
1492: if (ok) {
1493: ok = info[j] == JvmOpCodes.AASTORE;
1494: if (ok) {
1495: for (int x = n + 3; x < l; x++) {
1496: boolean b2 = getGenericFinder()
1497: .isThisInstrStart(x);
1498: if (b2) {
1499: if (info[x] == JvmOpCodes.LDC) {
1500:
1501: int offset = info[x + 1];
1502: if (offset < 0)
1503: offset += 256;
1504: CPString constString = cd
1505: .getStringsAtCPoolPosition(offset);
1506: if (constString == null) {
1507: return false;
1508: }
1509: java.lang.String stringLiteral = cd
1510: .getUTF8String(constString
1511: .getUtf8pointer());
1512: if (stringLiteral == null) {
1513: return false;
1514: }
1515: StringBuffer sb = new StringBuffer(
1516: "");
1517: Util.checkForImport(
1518: stringLiteral, sb);
1519: java.lang.String classToLoad = sb
1520: .toString()
1521: + ".class";
1522: Operand op = new Operand();
1523: op.setOperandValue(classToLoad);
1524: opStack.push(op);
1525: op.setClassType("Class");
1526: GlobalVariableStore
1527: .getSkipWRTClassLoadIf()
1528: .put(
1529: new Integer(
1530: currentForIndex + 3),
1531: new Integer(j));
1532: GlobalVariableStore
1533: .getSkipWRTClassLoadIfUpperLimits()
1534: .add(new Integer(j));
1535: return true;
1536:
1537: }
1538: if (info[x] == JvmOpCodes.LDC_W) {
1539: int offset = getGenericFinder()
1540: .getOffset(x);
1541: CPString constString = cd
1542: .getStringsAtCPoolPosition(offset);
1543: if (constString == null) {
1544: return false;
1545: }
1546: java.lang.String stringLiteral = cd
1547: .getUTF8String(constString
1548: .getUtf8pointer());
1549: if (stringLiteral == null) {
1550: return false;
1551: }
1552:
1553: Operand op = new Operand();
1554: StringBuffer sb = new StringBuffer(
1555: "");
1556: Util.checkForImport(
1557: stringLiteral, sb);
1558: java.lang.String classToLoad = sb
1559: .toString()
1560: + ".class";
1561: op.setOperandValue(classToLoad);
1562: opStack.push(op);
1563: op.setClassType("Class");
1564: GlobalVariableStore
1565: .getSkipWRTClassLoadIf()
1566: .put(
1567: new Integer(
1568: currentForIndex + 3),
1569: new Integer(j));
1570: GlobalVariableStore
1571: .getSkipWRTClassLoadIfUpperLimits()
1572: .add(new Integer(j));
1573: return true;
1574: }
1575:
1576: }
1577:
1578: }
1579:
1580: }
1581: }
1582: }
1583:
1584: }
1585: }
1586: return false;
1587:
1588: }
1589:
1590: public static boolean isGotoPrecededByDUPSTORE(int current,
1591: byte[] info) // FIXME
1592: {
1593: boolean yes = false;
1594: int prev = current - 1;
1595:
1596: boolean store = false;
1597: boolean dup = false;
1598: int x = -1;
1599: while (prev > 0) {
1600: if (getGenericFinder().isThisInstrStart(prev)) {
1601: store = getStoreFinder().isNextInstructionStore(prev);
1602: x = prev;
1603: if (store) {
1604: dup = getGenericFinder().isPrevInstDup(x);
1605: if (dup)
1606: return true;
1607: }
1608:
1609: if (info[prev] == JvmOpCodes.GOTO) {
1610: return false;
1611: }
1612: }
1613: prev--;
1614: }
1615:
1616: return yes;
1617: }
1618:
1619: public static class BranchLabel {
1620: IFBlock IF;
1621:
1622: java.lang.String l; // continue or break or empty
1623:
1624: public java.lang.String getBrlbl() {
1625: return brlbl;
1626: }
1627:
1628: java.lang.String brlbl; // jmpindexlabel
1629:
1630: public BranchLabel(IFBlock ifst, java.lang.String label,
1631: java.lang.String brlbl) {
1632: IF = ifst;
1633: l = label;
1634: this .brlbl = brlbl;
1635: }
1636:
1637: public IFBlock getIF() {
1638: return IF;
1639: }
1640:
1641: public java.lang.String getLBL() {
1642: return l;
1643: }
1644: }
1645:
1646: public static BranchLabel newBranchLabel(IFBlock ifst,
1647: java.lang.String label, java.lang.String brlbl) {
1648: return new BranchLabel(ifst, label, brlbl);
1649: }
1650:
1651: public static int getStoreInstPosInCode(byte[] info, int lend,
1652: int loadIndex)
1653:
1654: {
1655: for (int s = lend; s >= 0; s--) {
1656: if (getGenericFinder().isThisInstrStart(s)) {
1657: int curinst = info[s];
1658: boolean b = getStoreFinder()
1659: .isCurrentInstStore(curinst);
1660: if (b) {
1661: int temp = s + 1;
1662: int storeindex = info[temp];
1663: if (storeindex == loadIndex)
1664: return s;
1665: }
1666: }
1667:
1668: }
1669: return -1;
1670: }
1671:
1672: /***************************************************************************
1673: * NOTE: This is not general purpose method tofind load index inst...Skips
1674: * certain loads see usages
1675: *
1676: * @param inst
1677: * @param info
1678: * @param s
1679: * @return
1680: */
1681: public static int getLoadInstIndex(int inst, byte info[], int s) {
1682: // chkIndex is the index of the goto instruction.
1683:
1684: switch (inst) {
1685:
1686: case JvmOpCodes.ALOAD:
1687: return info[++s];
1688:
1689: case JvmOpCodes.ALOAD_0:
1690: return 0;
1691:
1692: case JvmOpCodes.ALOAD_1:
1693: return 1;
1694:
1695: case JvmOpCodes.ALOAD_2:
1696: return 2;
1697:
1698: case JvmOpCodes.ALOAD_3:
1699: return 3;
1700:
1701: case JvmOpCodes.DLOAD:
1702: return info[++s];
1703:
1704: case JvmOpCodes.DLOAD_0:
1705: return 0;
1706:
1707: case JvmOpCodes.DLOAD_1:
1708: return 1;
1709:
1710: case JvmOpCodes.DLOAD_2:
1711: return 2;
1712:
1713: case JvmOpCodes.DLOAD_3:
1714: return 3;
1715:
1716: case JvmOpCodes.FLOAD:
1717: return info[++s];
1718:
1719: case JvmOpCodes.FLOAD_0:
1720: return 0;
1721:
1722: case JvmOpCodes.FLOAD_1:
1723: return 1;
1724:
1725: case JvmOpCodes.FLOAD_2:
1726: return 2;
1727:
1728: case JvmOpCodes.FLOAD_3:
1729: return 3;
1730:
1731: case JvmOpCodes.ILOAD:
1732: return info[++s];
1733:
1734: case JvmOpCodes.ILOAD_0:
1735: return 0;
1736:
1737: case JvmOpCodes.ILOAD_1:
1738: return 1;
1739:
1740: case JvmOpCodes.ILOAD_2:
1741: return 2;
1742:
1743: case JvmOpCodes.ILOAD_3:
1744: return 3;
1745:
1746: case JvmOpCodes.LLOAD:
1747: return info[++s];
1748:
1749: case JvmOpCodes.LLOAD_0:
1750: return 0;
1751: case JvmOpCodes.LLOAD_1:
1752: return 1;
1753: case JvmOpCodes.LLOAD_2:
1754: return 2;
1755: case JvmOpCodes.LLOAD_3:
1756: return 3;
1757:
1758: }
1759:
1760: return -1;
1761: }
1762:
1763: public static java.lang.String getArrayType(java.lang.String temp) {
1764:
1765: if (temp.indexOf("L") != -1) {
1766: java.lang.String tmp = temp.substring(
1767: temp.indexOf("L") + 1, temp.indexOf(";"));
1768: tmp = tmp.replace('/', '.');
1769: return tmp;
1770:
1771: }
1772:
1773: if (temp.equals("Z")) {
1774: return "boolean";
1775: }
1776: if (temp.equals("D")) {
1777: return "double";
1778: }
1779: if (temp.equals("J")) {
1780: return "long";
1781: }
1782: if (temp.equals("F")) {
1783: return "float";
1784: }
1785: if (temp.equals("B")) {
1786: return "byte";
1787: }
1788: if (temp.equals("I")) {
1789: return "int";
1790: }
1791:
1792: if (temp.equals("C")) {
1793: return "char";
1794: }
1795: if (temp.equals("S")) {
1796: return "short";
1797: }
1798: return null;
1799: }
1800:
1801: public static boolean isNewFollowedByNew(byte[] info, int i) {
1802: int pos = i + 2 + 1;
1803: do {
1804: if (isThisInstrStart(pos)) {
1805: if (info[pos] == JvmOpCodes.NEW)
1806: return true;
1807: StringBuffer temp = new StringBuffer("");
1808: boolean b = getGenericFinder()
1809: .isNextInstructionAnyInvoke(pos, temp);
1810: if (b)
1811: break;
1812: pos++;
1813: } else {
1814: pos++;
1815: }
1816: } while (true && pos < info.length);
1817: return false;
1818: }
1819:
1820: public static void registerInnerClassIfAny(java.lang.String Type) {
1821: java.lang.String type = Type.trim();
1822: if (type.indexOf("$") > 0) {
1823:
1824: java.lang.String path = Configuration
1825: .getPathForCurrentClassFile();
1826: java.lang.String name = ConsoleLauncher.getClassName(path);
1827: int numberof$inmain = 0;
1828: for (int j = 0; j < name.length(); j++) {
1829: char c = name.charAt(j);
1830: if (c == '$')
1831: numberof$inmain++;
1832: }
1833: int numberof$intype = 0;
1834: for (int j = 0; j < Type.length(); j++) {
1835: char c = Type.charAt(j);
1836: if (c == '$')
1837: numberof$intype++;
1838: }
1839: // / if(numberof$inmain+1==numberof$intype) // Need to register
1840: // inner class
1841: // {
1842: InnerClassTracker tracker = ConsoleLauncher.getTracker();
1843: if (tracker != null) {
1844: InnerClassTracker.Node currentRoot = ConsoleLauncher
1845: .getCurrentRootAdded(); // Parent
1846: java.lang.String dir = ConsoleLauncher.getClassDir();
1847: if (type.endsWith(".class") == false)
1848: type += ".class";
1849: type = ConsoleLauncher.getClassName(type);
1850: InnerClassTracker.Node child = tracker.createNode(dir
1851: + File.separator + type, type);
1852: tracker.registerChildNode(currentRoot, child);
1853: }
1854: // }
1855:
1856: } else
1857: return;
1858:
1859: }
1860:
1861: public static boolean isNewArrayEmbedded(byte[] info) {
1862: int currentForIndex = ExecutionState
1863: .getCurrentInstructionPosition();
1864: int prev = currentForIndex - 1;
1865: boolean b = false;
1866: int prevPos = getGenericFinder().getPrevStartOfInst(
1867: currentForIndex);
1868: if (prevPos < 0)
1869: return b;
1870: boolean cont = false;
1871: switch (info[prevPos]) {
1872: case JvmOpCodes.ICONST_0:
1873: case JvmOpCodes.ICONST_1:
1874: case JvmOpCodes.ICONST_2:
1875: case JvmOpCodes.ICONST_3:
1876: case JvmOpCodes.ICONST_4:
1877: case JvmOpCodes.ICONST_5:
1878: case JvmOpCodes.BIPUSH:
1879: case JvmOpCodes.SIPUSH:
1880: cont = true;
1881: break;
1882: }
1883: if (!cont)
1884: return b;
1885: cont = false;
1886: prevPos = getGenericFinder().getPrevStartOfInst(prevPos);
1887: if (prevPos < 0)
1888: return b;
1889: switch (info[prevPos]) {
1890: case JvmOpCodes.ICONST_0:
1891: case JvmOpCodes.ICONST_1:
1892: case JvmOpCodes.ICONST_2:
1893: case JvmOpCodes.ICONST_3:
1894: case JvmOpCodes.ICONST_4:
1895: case JvmOpCodes.ICONST_5:
1896: case JvmOpCodes.BIPUSH:
1897: case JvmOpCodes.SIPUSH:
1898: cont = true;
1899: break;
1900: }
1901: if (!cont)
1902: return b;
1903: prevPos = getGenericFinder().getPrevStartOfInst(prevPos);
1904: if (prevPos < 0)
1905: return b;
1906: for (int z = prevPos; z >= 0; z--) {
1907:
1908: if (!getGenericFinder().isThisInstrStart(z))
1909: continue;
1910: switch (info[z]) {
1911:
1912: case JvmOpCodes.ASTORE:
1913: case JvmOpCodes.ASTORE_0:
1914: case JvmOpCodes.ASTORE_1:
1915: case JvmOpCodes.ASTORE_2:
1916: case JvmOpCodes.ASTORE_3:
1917: return b;
1918: case JvmOpCodes.ANEWARRAY:
1919: case JvmOpCodes.AASTORE:
1920: return !b;
1921:
1922: }
1923:
1924: }
1925: return b;
1926:
1927: }
1928:
1929: public static Operand createOperand(Object val) {
1930: Operand opr = new Operand();
1931: opr.setOperandValue(val);
1932: return opr;
1933:
1934: }
1935:
1936: public static java.lang.String getReturnTypeIfPreviousInvoke(int j,
1937: byte[] info) {
1938:
1939: // Terminator t;
1940: java.lang.String s = "0";
1941: ClassDescription cd = getContext().getClassRef().getCd();
1942: Hashtable invokeStartEnd = GlobalVariableStore
1943: .getInvokeStartEnd();
1944: if (invokeStartEnd != null && invokeStartEnd.size() > 0) {
1945: Integer in = (Integer) invokeStartEnd
1946: .get(new Integer(j - 1));
1947: if (in != null) {
1948: int iin = in.intValue();
1949: switch (info[iin]) {
1950:
1951: case JvmOpCodes.INVOKEINTERFACE:
1952: int classIndex = getGenericFinder().getOffset(iin);
1953: InterfaceMethodRef iref = cd
1954: .getInterfaceMethodAtCPoolPosition(classIndex);
1955: java.lang.String classname = iref.getClassname();
1956: java.lang.String typeofmet = iref.getTypeofmethod();
1957: int br = typeofmet.indexOf(")");
1958: if (br != -1) {
1959: java.lang.String ret = typeofmet
1960: .substring(br + 1);
1961: if (ret.trim().equals("Z")) {
1962: return "false";
1963: }
1964:
1965: }
1966:
1967: break;
1968:
1969: case JvmOpCodes.INVOKESPECIAL:
1970:
1971: classIndex = getGenericFinder().getOffset(iin);
1972: MethodRef mref = cd
1973: .getMethodRefAtCPoolPosition(classIndex);
1974: java.lang.String classtype = mref.getClassname();
1975: typeofmet = mref.getTypeofmethod();
1976: br = typeofmet.indexOf(")");
1977: if (br != -1) {
1978: java.lang.String ret = typeofmet
1979: .substring(br + 1);
1980: if (ret.trim().equals("Z")) {
1981: return "false";
1982: }
1983:
1984: }
1985:
1986: break;
1987:
1988: case JvmOpCodes.INVOKESTATIC:
1989: classIndex = getGenericFinder().getOffset(iin);
1990: mref = cd.getMethodRefAtCPoolPosition(classIndex);
1991: classname = mref.getClassname();
1992: typeofmet = mref.getTypeofmethod();
1993: br = typeofmet.indexOf(")");
1994: if (br != -1) {
1995: java.lang.String ret = typeofmet
1996: .substring(br + 1);
1997: if (ret.trim().equals("Z")) {
1998: return "false";
1999: }
2000:
2001: }
2002:
2003: break;
2004:
2005: case JvmOpCodes.INVOKEVIRTUAL:
2006: classIndex = getGenericFinder().getOffset(iin);
2007: mref = cd.getMethodRefAtCPoolPosition(classIndex);
2008: classname = mref.getClassname();
2009: typeofmet = mref.getTypeofmethod();
2010: br = typeofmet.indexOf(")");
2011: if (br != -1) {
2012: java.lang.String ret = typeofmet
2013: .substring(br + 1);
2014: if (ret.trim().equals("Z")) {
2015: return "false";
2016: }
2017:
2018: }
2019:
2020: break;
2021:
2022: default:
2023: return s;
2024:
2025: }
2026: }
2027:
2028: return s;
2029:
2030: } else {
2031: int iin = j - 3;
2032: int classIndex = -1;
2033: boolean isS = getGenericFinder().isThisInstrStart(iin);
2034: if (isS) {
2035: switch (info[iin]) {
2036:
2037: /*
2038: * case JvmOpCodes.INVOKEINTERFACE: int
2039: * classIndex=getGenericFinder().getOffset(iin);
2040: * InterfaceMethodRef
2041: * iref=cd.getInterfaceMethodAtCPoolPosition(classIndex);
2042: * java.lang.String classname=iref.getClassname();
2043: * java.lang.String typeofmet=iref.getTypeofmethod(); int
2044: * br=typeofmet.indexOf(")"); if(br!=-1) { java.lang.String
2045: * ret=typeofmet.substring(br+1); if(ret.trim().equals("Z")) {
2046: * return "false"; } }
2047: *
2048: * break;
2049: */
2050:
2051: case JvmOpCodes.INVOKESPECIAL:
2052:
2053: classIndex = getGenericFinder().getOffset(iin);
2054: MethodRef mref = cd
2055: .getMethodRefAtCPoolPosition(classIndex);
2056: java.lang.String classtype = mref.getClassname();
2057: java.lang.String typeofmet = mref.getTypeofmethod();
2058: int br = typeofmet.indexOf(")");
2059: if (br != -1) {
2060: java.lang.String ret = typeofmet
2061: .substring(br + 1);
2062: if (ret.trim().equals("Z")) {
2063: return "false";
2064: }
2065:
2066: }
2067:
2068: break;
2069:
2070: case JvmOpCodes.INVOKESTATIC:
2071: classIndex = getGenericFinder().getOffset(iin);
2072: mref = cd.getMethodRefAtCPoolPosition(classIndex);
2073: java.lang.String classname = mref.getClassname();
2074: typeofmet = mref.getTypeofmethod();
2075: br = typeofmet.indexOf(")");
2076: if (br != -1) {
2077: java.lang.String ret = typeofmet
2078: .substring(br + 1);
2079: if (ret.trim().equals("Z")) {
2080: return "false";
2081: }
2082:
2083: }
2084:
2085: break;
2086:
2087: case JvmOpCodes.INVOKEVIRTUAL:
2088: classIndex = getGenericFinder().getOffset(iin);
2089: mref = cd.getMethodRefAtCPoolPosition(classIndex);
2090: classname = mref.getClassname();
2091: typeofmet = mref.getTypeofmethod();
2092: br = typeofmet.indexOf(")");
2093: if (br != -1) {
2094: java.lang.String ret = typeofmet
2095: .substring(br + 1);
2096: if (ret.trim().equals("Z")) {
2097: return "false";
2098: }
2099:
2100: }
2101:
2102: }
2103: }
2104: if (getGenericFinder().isThisInstrStart(j - 5)
2105: && info[j - 5] == JvmOpCodes.INVOKEINTERFACE) {
2106: iin = j - 5;
2107: classIndex = getGenericFinder().getOffset(iin);
2108: InterfaceMethodRef iref = cd
2109: .getInterfaceMethodAtCPoolPosition(classIndex);
2110: java.lang.String classname = iref.getClassname();
2111: java.lang.String typeofmet = iref.getTypeofmethod();
2112: int br = typeofmet.indexOf(")");
2113: if (br != -1) {
2114: java.lang.String ret = typeofmet.substring(br + 1);
2115: if (ret.trim().equals("Z")) {
2116: return "false";
2117: }
2118:
2119: }
2120: }
2121: }
2122: return s;
2123: }
2124:
2125: public static boolean checkForLoadAfterIINC(byte[] info,
2126: OperandStack opStack, int current, LocalVariable local,
2127: int index, java.lang.String c) {
2128:
2129: boolean b = false;
2130: int j = current + 1 + 1 + 1;
2131: int loadindex = -1;
2132: boolean ok = false;
2133: boolean iloadfnd = false;
2134: if (isThisInstrStart(j)) {
2135:
2136: switch (info[j]) {
2137: case JvmOpCodes.ILOAD:
2138: loadindex = info[(j + 1)];
2139: iloadfnd = true;
2140: break;
2141:
2142: case JvmOpCodes.ILOAD_0:
2143: loadindex = 0;
2144: iloadfnd = true;
2145: break;
2146:
2147: case JvmOpCodes.ILOAD_1:
2148: loadindex = 1;
2149: iloadfnd = true;
2150: break;
2151:
2152: case JvmOpCodes.ILOAD_2:
2153: loadindex = 2;
2154: iloadfnd = true;
2155: break;
2156:
2157: case JvmOpCodes.ILOAD_3:
2158: loadindex = 3;
2159: iloadfnd = true;
2160: break;
2161:
2162: case JvmOpCodes.IALOAD:
2163: loadindex = -1;
2164: ok = true;
2165: break;
2166: }
2167:
2168: if (loadindex != -1) {
2169: if (loadindex == index) {
2170:
2171: if (c.trim().indexOf("-1") != -1) {
2172: b = true;
2173: local.setTempVarName("--" + local.getVarName());
2174: } else if (c.trim().indexOf("1") != -1) {
2175: b = true;
2176: local.setTempVarName("++" + local.getVarName());
2177: } else {
2178: b = false;
2179: }
2180: }
2181: } else {
2182: b = false;
2183: }
2184:
2185: if (ok) {
2186: if (c.trim().indexOf("-1") != -1) {
2187: b = true;
2188: Operand currentTop = opStack.peekTopOfStack();
2189: if (currentTop != null) {
2190: java.lang.String topval = currentTop
2191: .getOperandValue();
2192: topval = topval + "--";
2193: currentTop.setOperandValue(topval);
2194: b = true;
2195: } else {
2196: b = false;
2197: }
2198: } else if (c.trim().indexOf("1") != -1) {
2199: b = true;
2200: Operand currentTop = opStack.peekTopOfStack();
2201: if (currentTop != null) {
2202: java.lang.String topval = currentTop
2203: .getOperandValue();
2204: topval = topval + "++";
2205: currentTop.setOperandValue(topval);
2206: b = true;
2207: } else {
2208: b = false;
2209: }
2210: } else {
2211: b = false;
2212: }
2213: }
2214: /*
2215: * if(!b && !iloadfnd) { j=current+1+1+1; StringBuffer buf=new
2216: * StringBuffer(""); boolean
2217: * istore=isThisInstructionIStoreInst(info,j,buf); if(istore==false) {
2218: * if(c.trim().indexOf("-1")!=-1) { b=true; Operand
2219: * currentTop=opStack.peekTopOfStack(); if(currentTop!=null) {
2220: * java.lang.String topval=currentTop.getOperandValue();
2221: * topval=topval+"--"; currentTop.setOperandValue(topval); b=true; }
2222: * else { b=false; } } else if(c.trim().indexOf("1")!=-1) { b=true;
2223: * Operand currentTop=opStack.peekTopOfStack(); if(currentTop!=null) {
2224: * java.lang.String topval=currentTop.getOperandValue();
2225: * topval=topval+"++"; currentTop.setOperandValue(topval); b=true; }
2226: * else { b=false; } } else { b=false; } } }
2227: */
2228:
2229: }
2230:
2231: return b;
2232: }
2233:
2234: public static boolean checkForLoadBeforeIINC(byte[] info,
2235: OperandStack opStack, int current, LocalVariable local,
2236: int index, java.lang.String c) {
2237:
2238: boolean b = false;
2239: int loadindex = -1;
2240: boolean ok = false;
2241: boolean iloadfnd = false;
2242: int j = getGenericFinder().getPrevStartOfInst(current);
2243: if (isThisInstrStart(j)) {
2244:
2245: switch (info[j]) {
2246:
2247: case JvmOpCodes.ILOAD:
2248: loadindex = info[(j + 1)];
2249: iloadfnd = true;
2250: break;
2251:
2252: case JvmOpCodes.ILOAD_0:
2253: loadindex = 0;
2254: iloadfnd = true;
2255: break;
2256:
2257: case JvmOpCodes.ILOAD_1:
2258: loadindex = 1;
2259: iloadfnd = true;
2260: break;
2261:
2262: case JvmOpCodes.ILOAD_2:
2263: loadindex = 2;
2264: iloadfnd = true;
2265: break;
2266:
2267: case JvmOpCodes.ILOAD_3:
2268: loadindex = 3;
2269: iloadfnd = true;
2270: break;
2271:
2272: case JvmOpCodes.IALOAD:
2273: loadindex = -1;
2274: ok = true;
2275: break;
2276:
2277: }
2278:
2279: if (loadindex != -1) {
2280: if (loadindex == index) {
2281:
2282: if (c.trim().indexOf("-1") != -1) {
2283: b = true;
2284: local.setTempVarName(local.getVarName() + "--");
2285: opStack.peekTopOfStack().setOperandValue(
2286: local.getTempVarName());
2287: } else if (c.trim().indexOf("1") != -1) {
2288: b = true;
2289: local.setTempVarName(local.getVarName() + "++");
2290: opStack.peekTopOfStack().setOperandValue(
2291: local.getTempVarName());
2292:
2293: } else {
2294: b = false;
2295: }
2296: }
2297: } else {
2298: b = false;
2299: }
2300:
2301: if (ok) {
2302: if (c.trim().indexOf("-1") != -1) {
2303: b = true;
2304: Operand currentTop = opStack.peekTopOfStack();
2305: if (currentTop != null) {
2306: java.lang.String topval = currentTop
2307: .getOperandValue();
2308: topval = topval + "--";
2309: currentTop.setOperandValue(topval);
2310: b = true;
2311: } else {
2312: b = false;
2313: }
2314: } else if (c.trim().indexOf("1") != -1) {
2315: b = true;
2316: Operand currentTop = opStack.peekTopOfStack();
2317: if (currentTop != null) {
2318: java.lang.String topval = currentTop
2319: .getOperandValue();
2320: topval = topval + "++";
2321: currentTop.setOperandValue(topval);
2322: b = true;
2323: } else {
2324: b = false;
2325: }
2326: } else {
2327: b = false;
2328: }
2329: }
2330: /*
2331: * if(!b && !iloadfnd) { j=current+3; StringBuffer buf=new
2332: * StringBuffer(""); boolean
2333: * istore=isThisInstructionIStoreInst(info,j,buf); if(istore==false) {
2334: * if(c.trim().indexOf("-1")!=-1) { b=true; Operand
2335: * currentTop=opStack.peekTopOfStack(); if(currentTop!=null) {
2336: * java.lang.String topval=currentTop.getOperandValue();
2337: * topval=topval+"--"; currentTop.setOperandValue(topval); b=true; }
2338: * else { b=false; } } else if(c.trim().indexOf("1")!=-1) { b=true;
2339: * Operand currentTop=opStack.peekTopOfStack(); if(currentTop!=null) {
2340: * java.lang.String topval=currentTop.getOperandValue();
2341: * topval=topval+"++"; currentTop.setOperandValue(topval); b=true; }
2342: * else { b=false; } } else { b=false; } } }
2343: */
2344:
2345: }
2346:
2347: return b;
2348: }
2349:
2350: public static boolean checkForValueReturn(byte[] code, int i) {
2351: boolean present = false;
2352: int jvmInst = code[i];
2353: switch (jvmInst) {
2354: case JvmOpCodes.ARETURN:
2355: case JvmOpCodes.IRETURN:
2356: case JvmOpCodes.FRETURN:
2357: case JvmOpCodes.DRETURN:
2358: case JvmOpCodes.LRETURN:
2359: present = true;
2360: break;
2361: default:
2362: present = false;
2363: break;
2364: }
2365: return present;
2366: }
2367:
2368: public static void resetOperandValueIfNecessary(
2369: ArrayList paramlist, int indx, Operand op2) {
2370:
2371: boolean boolparam = isParameterTypeBoolean(paramlist, indx);
2372: if (boolparam) {
2373: if (op2 != null
2374: && op2.getOperandValue() != null
2375: && op2.getOperandValue().toString().trim().equals(
2376: "1"))
2377: op2.setOperandValue("true");
2378: if (op2 != null
2379: && op2.getOperandValue() != null
2380: && op2.getOperandValue().toString().trim().equals(
2381: "0"))
2382: op2.setOperandValue("false");
2383:
2384: }
2385: }
2386:
2387: private static boolean isParameterTypeBoolean(List paramlist,
2388: int indx) {
2389: java.lang.String type = (java.lang.String) paramlist.get(indx);
2390: if (type.equalsIgnoreCase("boolean")) {
2391: return true;
2392: } else {
2393: return false;
2394: }
2395: }
2396:
2397: public static void resetMethodParameters(OperandStack stack,
2398: ArrayList methodParams, int j) {
2399: Behaviour behavior = getContext();
2400: ArrayList problematicInvokes = GlobalVariableStore
2401: .getProblematicInvokes();
2402: // Check if reset needs to be done in the first place
2403: if (problematicInvokes == null
2404: || problematicInvokes.size() == 0)
2405: return;
2406: boolean ok = false;
2407: for (int n = 0; n < problematicInvokes.size(); n++) {
2408:
2409: Integer in = (Integer) problematicInvokes.get(n);
2410: if (in.intValue() == j) {
2411: ok = true; // Yes jdec
2412: break;
2413: } else
2414: ok = false;
2415:
2416: }
2417: if (!ok)
2418: return;
2419:
2420: // some validations
2421: if (methodParams == null || stack == null)
2422: return;
2423: int count = methodParams.size();
2424: if (count == 0)
2425: return;
2426: if (stack.size() < count)
2427: return; // Should Not happen: A Bug in jdec
2428: Operand reqdops[] = new Operand[count];
2429: boolean needtoresetstack = false;
2430: for (int h = 0; h < count; h++) {
2431: reqdops[h] = stack.getTopOfStack();
2432: needtoresetstack = true;
2433: }
2434:
2435: // IMPORTANT : IF needtoresetstack IS TRUE method shud return only after
2436: // resetting stack .NOT before that
2437:
2438: // start Resetting
2439: int opstart = 0;
2440: for (int z = count - 1; z >= 0; z--) {
2441:
2442: Operand current = reqdops[opstart];
2443: opstart++;
2444: if (current != null) {
2445: java.lang.String type = current.getLocalVarType();
2446: boolean needtoreset = false;
2447: java.lang.String param = (java.lang.String) methodParams
2448: .get(z);
2449: if (type != null && type.trim().equals("int")) {
2450:
2451: if (param.trim().equals("byte")) {
2452: needtoreset = true;
2453: } else if (param.trim().equals("boolean")) {
2454: needtoreset = true;
2455: } else if (param.trim().equals("short")) {
2456: needtoreset = true;
2457: } else if (param.trim().equals("char")) {
2458: needtoreset = true;
2459: } else {
2460: needtoreset = false;
2461: }
2462: if (needtoreset) {
2463: int localIndex = current.getLocalVarIndex();
2464: java.lang.String searchFor = "#REPLACE_INT_"
2465: + localIndex + "#";
2466: int len = searchFor.length();
2467: java.lang.String codeAsString = getContext()
2468: .getCodeAsBuffer().toString();
2469: int start = codeAsString.indexOf(searchFor);
2470: java.lang.String name = "";
2471: if (start != -1) {
2472: java.lang.String tp = codeAsString
2473: .substring(start + len, start + len
2474: + 3);
2475: int equalTo = -1;
2476: StringBuffer newpos = new StringBuffer("");
2477: if (tp.equals("int")) {
2478: // java.lang.String=codeStatements.replaceFirst(searchFor+"int",param.trim());
2479: name = (java.lang.String) current
2480: .getOperandValue();
2481:
2482: java.lang.String afterreplace = getStringAfterReplacement(
2483: start, searchFor + "int", param
2484: .trim(), newpos, name,
2485: false, param.trim());
2486: getContext()
2487: .replaceBuffer(afterreplace);
2488:
2489: }
2490: try {
2491: equalTo = Integer.parseInt(newpos
2492: .toString());
2493: } catch (NumberFormatException ne) {
2494: equalTo = -1;
2495: }
2496:
2497: if (equalTo != -1) {
2498: java.lang.String codeasstring = behavior
2499: .getCodeAsBuffer().toString();
2500: int valueIn = codeasstring.indexOf(
2501: "#VALUE" + localIndex + "#",
2502: equalTo);
2503: if (valueIn != -1) {
2504: java.lang.String valuehash = "#VALUE"
2505: + localIndex + "#";
2506: java.lang.String val = codeasstring
2507: .substring(
2508: valueIn
2509: + valuehash
2510: .length(),
2511: valueIn
2512: + valuehash
2513: .length()
2514: + 1);
2515:
2516: java.lang.String afterreplace = getStringAfterReplacement(
2517: valueIn, "#VALUE"
2518: + localIndex + "#",
2519: val, newpos, name, true,
2520: param.trim());
2521: getContext().replaceBuffer(
2522: afterreplace);
2523: }
2524: }
2525: }
2526:
2527: }
2528:
2529: } else if (type != null && type.trim().equals("")) {
2530:
2531: if (param.trim().equals("byte")
2532: || param.trim().equals("short")
2533: || param.trim().equals("char")) {
2534:
2535: current.setOperandValue("(" + param + ")"
2536: + current.getOperandValue());
2537:
2538: }
2539: }
2540: // Check for multidimensional.....
2541:
2542: if (param.trim().indexOf("[") != -1) {
2543: int first = param.trim().indexOf("[");
2544: int last = param.trim().lastIndexOf("[");
2545: int howmany = last - first + 1;
2546: boolean isMulti = current.isMultiDimension();
2547: if (isMulti) {
2548: java.lang.String value = (java.lang.String) current
2549: .getOperandValue();
2550: /*
2551: * if(value.indexOf("[")!=-1) { /*int cnt=1; int
2552: * start=value.indexOf("["); int next=start+1;
2553: * while(next < value.length()) {
2554: *
2555: * if(value.charAt(next)=='[') { cnt++; } next++; }
2556: *
2557: * int total=cnt+howmany;
2558: */
2559: java.lang.String bracks = "";
2560: for (int s = 0; s < howmany; s++) {
2561:
2562: bracks += "[]";
2563: }
2564: value += bracks;
2565: current.setOperandValue(value);
2566:
2567: }
2568:
2569: }
2570:
2571: } else // Again should not happen at all. Returning if this happens
2572: // , so that jdec will not reset a wrong operand's
2573: // value
2574: {
2575: // Restore Stack
2576: for (int l = reqdops.length - 1; l >= 0; l--) {
2577: Operand op = reqdops[l];
2578: stack.push(op);
2579: }
2580:
2581: return;
2582: }
2583:
2584: }
2585:
2586: // This should be final step before returning
2587: if (needtoresetstack) {
2588: // Restore Stack
2589: for (int l = reqdops.length - 1; l >= 0; l--) {
2590: Operand op = reqdops[l];
2591: stack.push(op);
2592: }
2593: }
2594:
2595: }
2596:
2597: private static java.lang.String getStringAfterReplacement(
2598: int fromwhere, java.lang.String lookfor,
2599: java.lang.String replaceString, StringBuffer sb,
2600: java.lang.String name, boolean skipone,
2601: java.lang.String methodparam) {
2602: int equal = -1;
2603: java.lang.String codeAsString = getContext().getCodeAsBuffer()
2604: .toString();
2605: java.lang.String orig = codeAsString;
2606: java.lang.String temp1 = codeAsString.substring(0, fromwhere);
2607: java.lang.String temp2 = replaceString;
2608: java.lang.String temp3 = "";
2609: if (skipone) {
2610: if (methodparam.equalsIgnoreCase("boolean")) {
2611:
2612: if (replaceString.trim().equalsIgnoreCase("0")) {
2613: temp2 = "false";
2614: } else if (replaceString.trim().equalsIgnoreCase("1")) {
2615: temp2 = "true";
2616: } else {
2617:
2618: }
2619:
2620: }
2621: temp3 = codeAsString.substring(fromwhere + lookfor.length()
2622: + 1);
2623: } else {
2624: temp3 = codeAsString
2625: .substring(fromwhere + lookfor.length());
2626: }
2627:
2628: orig = temp1 + temp2 + temp3;
2629: equal = orig.indexOf("=", orig.indexOf(replaceString + "\t"
2630: + name));
2631: sb.append(equal);
2632: return orig;
2633: }
2634:
2635: public static void adjustBracketCount(Operand op) {
2636: java.lang.String value = op.getOperandValue();
2637: int openB = 0;
2638: int closeB = 0;
2639: if (value != null && value.indexOf("(") != -1
2640: && value.indexOf(")") != -1) {
2641: for (int c = 0; c < value.length(); c++) {
2642: char ch = value.charAt(c);
2643: if (ch == ')')
2644: closeB++;
2645: else if (ch == '(')
2646: openB++;
2647: }
2648: if (closeB > openB) {
2649:
2650: java.lang.String temp = value.trim();
2651: int number = closeB - openB;
2652: if (temp.charAt(temp.length() - 1) == ')') {
2653: if (temp.length() - number < 0)
2654: number = 1; // A Crude way of avoiding Exception If any
2655: java.lang.String str = value.substring(0, temp
2656: .length()
2657: - number);
2658: op.setOperandValue(str);
2659: }
2660:
2661: }
2662: if (closeB < openB) {
2663:
2664: java.lang.String temp = value.trim();
2665: int number = openB - closeB;
2666: java.lang.String str = "";
2667: for (int z = 1; z <= number; z++)
2668: str += ")";
2669: op.setOperandValue(temp + str);
2670: }
2671:
2672: }
2673:
2674: }
2675:
2676: public static boolean isMethodRetBoolean(Behaviour b) {
2677:
2678: java.lang.String type = b.getReturnType();
2679: if (type.equals("boolean"))
2680: return true;
2681: return false;
2682:
2683: }
2684:
2685: public static int getNextInstrPos(int index) {
2686: byte[] code = getContext().getCode();
2687: for (int i = index + 1; i < code.length; i++) {
2688: boolean start = getGenericFinder().isThisInstrStart(i);
2689: if (start) {
2690: return i;
2691: }
2692: }
2693: return -1;
2694: }
2695:
2696: }
|