0001: /*
0002: * ClassDescription.java Copyright (c) 2006,07 Swaroop Belur
0003: *
0004: * This program is free software; you can redistribute it and/or
0005: * modify it under the terms of the GNU General Public License
0006: * as published by the Free Software Foundation; either version 2
0007: * of the License, or (at your option) any later version.
0008:
0009: * This program is distributed in the hope that it will be useful,
0010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0012: * GNU General Public License for more details.
0013:
0014: * You should have received a copy of the GNU General Public License
0015: * along with this program; if not, write to the Free Software
0016: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
0017: *
0018: */
0019:
0020: package net.sf.jdec.constantpool;
0021:
0022: import java.io.DataInputStream;
0023: import java.io.IOException;
0024: import java.util.ArrayList;
0025: import java.util.Arrays;
0026: import java.util.HashMap;
0027: import java.util.Hashtable;
0028: import java.util.Iterator;
0029: import java.util.List;
0030: import java.util.Map;
0031:
0032: import net.sf.jdec.blocks.CatchBlock;
0033: import net.sf.jdec.blocks.FinallyBlock;
0034: import net.sf.jdec.blocks.Loop;
0035: import net.sf.jdec.blocks.Switch;
0036: import net.sf.jdec.blocks.TryBlock;
0037: import net.sf.jdec.blocks.Switch.Case;
0038: import net.sf.jdec.constantpool.MethodInfo.ExceptionTable;
0039: import net.sf.jdec.core.JvmOpCodes;
0040: import net.sf.jdec.core.LocalVariable;
0041: import net.sf.jdec.core.LocalVariableStructure;
0042: import net.sf.jdec.core.LocalVariableTable;
0043: import net.sf.jdec.core.ShortcutAnalyser;
0044: import net.sf.jdec.io.Writer;
0045: import net.sf.jdec.main.ConsoleLauncher;
0046: import net.sf.jdec.reflection.ConstructorMember;
0047: import net.sf.jdec.reflection.FieldMember;
0048: import net.sf.jdec.reflection.JavaClass;
0049: import net.sf.jdec.reflection.MethodMember;
0050: import net.sf.jdec.settings.SettingsStore;
0051: import net.sf.jdec.util.Constants;
0052:
0053: /*******************************************************************************
0054: * @author swaroop belur
0055: */
0056: public class ClassDescription {
0057:
0058: private CPool cpool = null;
0059:
0060: ArrayList accessSpecifiers = new ArrayList();
0061:
0062: ArrayList interfacesImplemented = new ArrayList();
0063:
0064: FieldInfo[] allFields = null;
0065:
0066: MethodInfo[] allMethods = null;
0067:
0068: java.lang.String className = "";
0069:
0070: java.lang.String super ClassName = "";
0071:
0072: Hashtable methodLookUp = new Hashtable();
0073:
0074: public static ClassDescription ref = null;
0075:
0076: public ClassDescription() {
0077: /***********************************************************************
0078: * The safest/easiest place to reset the mappings b/w prefix of a
0079: * variable and its hit count.
0080: */
0081: SettingsStore.getVariablesettings().reset();
0082: ref = this ;
0083: }
0084:
0085: public void readAccessSpecifiers(DataInputStream dis)
0086: throws IOException {
0087: int z = dis.readUnsignedShort();
0088: int accessFlags = Integer.parseInt(Integer.toHexString(z));// ,16);
0089: //
0090: Class cl;
0091: switch (accessFlags) {
0092: case Constants.ACC_PUB:
0093: /*
0094: * accessSpecifiers.add(new Integer(Constants.ACC_PUBLIC));
0095: * accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0096: */
0097: accessSpecifiers.add("public");
0098: accessSpecifiers.add("super");
0099: break;
0100:
0101: case Constants.ACC_NPUB:
0102: accessSpecifiers.add("super");
0103: // accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0104: break;
0105:
0106: case Constants.ACC_PUB_ABSTRACT:
0107: accessSpecifiers.add("public");
0108: accessSpecifiers.add("super");
0109: accessSpecifiers.add("abstract");
0110: /*
0111: * accessSpecifiers.add(new Integer(Constants.ACC_PUBLIC));
0112: * accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0113: * accessSpecifiers.add(new Integer(Constants.ACC_ABSTRACT));
0114: */
0115: break;
0116:
0117: case Constants.ACC_NPUB_ABSTRACT:
0118: accessSpecifiers.add("super");
0119: accessSpecifiers.add("abstract");
0120: /*
0121: * accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0122: * accessSpecifiers.add(new Integer(Constants.ACC_ABSTRACT));
0123: */
0124: break;
0125:
0126: case Constants.ACC_NPUB_FINAL:
0127: accessSpecifiers.add("super");
0128: accessSpecifiers.add("final");
0129: /*
0130: * accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0131: * accessSpecifiers.add(new Integer(Constants.ACC_FINAL));
0132: */
0133: break;
0134:
0135: case Constants.ACC_PUB_FINAL:
0136: accessSpecifiers.add("public");
0137: accessSpecifiers.add("super");
0138: accessSpecifiers.add("final");
0139: /*
0140: * accessSpecifiers.add(new Integer(Constants.ACC_PUBLIC));
0141: * accessSpecifiers.add(new Integer(Constants.ACC_SUPER));
0142: * accessSpecifiers.add(new Integer(Constants.ACC_FINAL));
0143: */
0144: break;
0145:
0146: case Constants.ACC_INT_PUB:
0147: accessSpecifiers.add("public");
0148: accessSpecifiers.add("interface");
0149: accessSpecifiers.add("abstract");
0150: /*
0151: * accessSpecifiers.add(new Integer(Constants.ACC_PUBLIC));
0152: * accessSpecifiers.add(new Integer(Constants.ACC_INTERFACE));
0153: * accessSpecifiers.add(new Integer(Constants.ACC_ABSTRACT));
0154: */
0155: break;
0156:
0157: case Constants.ACC_INT_NPUB:
0158: accessSpecifiers.add("interface");
0159: accessSpecifiers.add("abstract");
0160: /*
0161: * accessSpecifiers.add(new Integer(Constants.ACC_INTERFACE));
0162: * accessSpecifiers.add(new Integer(Constants.ACC_ABSTRACT));
0163: */
0164: break;
0165:
0166: }
0167:
0168: // printAccessSpecifies(accessSpecifiers);
0169: // readClassAndSuperClassInfo(dis);
0170: // readInterfaceInformation(dis);
0171: // readFieldInformation(dis);
0172: // readMethodInformation(dis);
0173: }
0174:
0175: public void readClassAndSuperClassInfo(DataInputStream dis)
0176: throws IOException {
0177: int class_info = dis.readUnsignedShort();
0178: int super _class_info = dis.readUnsignedShort();
0179:
0180: ClassInfo cinfo = getClassInfoAtCPoolPosition(class_info);
0181:
0182: className = getUTF8String(cinfo.getUtf8pointer());
0183: className = className.replace('/', '.');
0184: ClassInfo scinfo = getClassInfoAtCPoolPosition(super _class_info);
0185: if (scinfo != null) {
0186: super ClassName = getUTF8String(scinfo.getUtf8pointer());
0187: super ClassName = super ClassName.replace('/', '.');
0188: } else // Fix For java.lang.Object.class
0189: {
0190: super ClassName = "";
0191: }
0192:
0193: }
0194:
0195: public void readInterfaceInformation(DataInputStream dis)
0196: throws IOException {
0197: int interfaceCount = dis.readUnsignedShort();
0198: for (int index = 0; index < interfaceCount; index++) {
0199: int class_info_index = dis.readUnsignedShort();
0200: ClassInfo cinfo = getClassInfoAtCPoolPosition(class_info_index);
0201: interfacesImplemented.add(getUTF8String(
0202: cinfo.getUtf8pointer()).replace('/', '.'));
0203: }
0204: }
0205:
0206: public void readFieldInformation(DataInputStream dis)
0207: throws IOException {
0208: int fieldCount = dis.readUnsignedShort();
0209: allFields = new FieldInfo[fieldCount];
0210: for (int index = 0; index < fieldCount; index++) {
0211: FieldInfo finfo = new FieldInfo();
0212: int accessSpecifier = dis.readUnsignedShort();
0213: int nameandtypeindex = dis.readUnsignedShort();
0214: int descriptor_index = dis.readUnsignedShort();
0215: finfo.addAccessSpecifiers(accessSpecifier);
0216: finfo.setFieldName(getUTF8String(nameandtypeindex));
0217: java.lang.String desc = getUTF8String(descriptor_index);
0218: java.lang.String objectType = "";
0219: if (desc.lastIndexOf("[") != -1) {
0220: objectType = desc.substring(desc.lastIndexOf("[") + 1);
0221: } else {
0222: objectType = desc;
0223: }
0224: if (desc.equals(Constants.ISINT)) {
0225: finfo.addFieldType(Constants.ISINT);
0226: }
0227: if (desc.equals(Constants.ISFLOAT)) {
0228: finfo.addFieldType(Constants.ISFLOAT);
0229: }
0230: if (desc.equals(Constants.ISDOUBLE)) {
0231: finfo.addFieldType(Constants.ISDOUBLE);
0232: }
0233: if (desc.equals(Constants.ISLONG)) {
0234: finfo.addFieldType(Constants.ISLONG);
0235: }
0236: if (desc.equals(Constants.ISBYTE)) {
0237: finfo.addFieldType(Constants.ISBYTE);
0238: }
0239: if (desc.equals(Constants.ISCHAR)) {
0240: finfo.addFieldType(Constants.ISCHAR);
0241: }
0242: if (desc.equals(Constants.ISSHORT)) {
0243: finfo.addFieldType(Constants.ISSHORT);
0244: }
0245: if (desc.equals(Constants.ISBOOLEAN)) {
0246: finfo.addFieldType(Constants.ISBOOLEAN);
0247: }
0248: if (objectType.startsWith(Constants.ISREFERENCE)
0249: && desc.endsWith(";")) {
0250: java.lang.String class_type = desc.substring(0, desc
0251: .length() - 1);
0252: // finfo.addFieldType("L");
0253: finfo.addFieldType(class_type);
0254:
0255: }
0256: if (desc.indexOf(Constants.ISARRAY) != -1) {
0257: // finfo.addFieldType(Constants.ISARRAY);
0258: finfo.setArray(true);
0259: if (desc.lastIndexOf("[") != -1) {
0260: finfo.setDimension(desc.lastIndexOf("[") + 1);
0261: }
0262:
0263: if (objectType.equals(Constants.ISINT)) {
0264: finfo.addFieldType(Constants.ISINT);
0265: }
0266: if (objectType.equals(Constants.ISFLOAT)) {
0267: finfo.addFieldType(Constants.ISFLOAT);
0268: }
0269: if (objectType.equals(Constants.ISDOUBLE)) {
0270: finfo.addFieldType(Constants.ISDOUBLE);
0271: }
0272: if (objectType.equals(Constants.ISLONG)) {
0273: finfo.addFieldType(Constants.ISLONG);
0274: }
0275: if (objectType.equals(Constants.ISBYTE)) {
0276: finfo.addFieldType(Constants.ISBYTE);
0277: }
0278: if (objectType.equals(Constants.ISCHAR)) {
0279: finfo.addFieldType(Constants.ISCHAR);
0280: }
0281: if (objectType.equals(Constants.ISSHORT)) {
0282: finfo.addFieldType(Constants.ISSHORT);
0283: }
0284: if (objectType.equals(Constants.ISBOOLEAN)) {
0285: finfo.addFieldType(Constants.ISBOOLEAN);
0286: }
0287: if (objectType.startsWith(Constants.ISREFERENCE)
0288: && desc.endsWith(";")) {
0289: java.lang.String class_type = objectType.substring(
0290: 0, objectType.length() - 1);
0291: // finfo.addFieldType("L");
0292: finfo.addFieldType(class_type);
0293:
0294: }
0295:
0296: }
0297:
0298: int attributes_count = dis.readUnsignedShort();
0299: for (int k = 0; k < attributes_count; k++) {
0300: int attribute_name_index = dis.readUnsignedShort();
0301: if (getUTF8String(attribute_name_index)
0302: .equalsIgnoreCase("constantvalue")) {
0303: int attribute_length = dis.readInt();
0304: int val_index = dis.readUnsignedShort();
0305: if (!finfo.isArray()
0306: && (finfo.getFieldType().get(0).equals(
0307: Constants.ISINT) || finfo
0308: .getFieldType().get(0).equals(
0309: Constants.ISSHORT))
0310: || finfo.getFieldType().get(0).equals(
0311: Constants.ISBYTE)
0312: || finfo.getFieldType().get(0).equals(
0313: Constants.ISCHAR)) {
0314: finfo.setObj(new Integer(
0315: getINTPrimitiveAtCPoolPosition(
0316: val_index).getValue()));
0317: }
0318: if (!finfo.isArray()
0319: && finfo.getFieldType().get(0).equals(
0320: Constants.ISFLOAT)) {
0321: float value = getFloatPrimitiveAtCPoolPosition(
0322: val_index).getValue();
0323: finfo.setObj(new Float(value));
0324: }
0325: if (!finfo.isArray()
0326: && finfo.getFieldType().get(0).equals(
0327: Constants.ISDOUBLE)) {
0328: double value = getDoublePrimitiveAtCPoolPosition(
0329: val_index).getValue();
0330: finfo.setObj(new Double(value));
0331: }
0332: if (!finfo.isArray()
0333: && finfo.getFieldType().get(0).equals(
0334: Constants.ISLONG)) {
0335: long value = getLongPrimitiveAtCPoolPosition(
0336: val_index).getValue();
0337: finfo.setObj(new Long(value));
0338: }
0339: if (!finfo.isArray()
0340: && ((java.lang.String) finfo.getFieldType()
0341: .get(0))
0342: .indexOf("Ljava/lang/String") != -1) {
0343: CPString value = getStringsAtCPoolPosition(val_index);
0344: int utf8 = value.getUtf8pointer();
0345: java.lang.String strValue = getUTF8String(utf8);
0346: finfo.setObj("\"" + strValue + "\"");
0347: }
0348:
0349: } else {
0350: int attribute_length = dis.readInt();
0351: byte[] info = new byte[attribute_length];
0352: dis.read(info, 0, attribute_length);
0353: }
0354: }
0355: finfo.setBelongsToClass(className);
0356: allFields[index] = finfo;
0357: }
0358: }
0359:
0360: MethodInfo minfo;
0361:
0362: public void readMethodInformation(DataInputStream dis)
0363: throws IOException {
0364: int methodCount = dis.readUnsignedShort();
0365: allMethods = new MethodInfo[methodCount];
0366: for (int i = 0; i < methodCount; i++) {
0367: minfo = new MethodInfo();
0368: int accessSpecifiers = dis.readUnsignedShort();
0369: int nameandtypeIndex = dis.readUnsignedShort();
0370: int descriptorIndex = dis.readUnsignedShort();
0371: int attributesCount = dis.readUnsignedShort();
0372:
0373: java.lang.String methodName = getUTF8String(nameandtypeIndex);
0374:
0375: java.lang.String methodDesc = getUTF8String(descriptorIndex); // NOTE:
0376: // used
0377: // only
0378: // for
0379: // passing
0380: // to
0381: // readCodeAttributes
0382: minfo.setBelongsToClass(className);
0383: // System.out.println(methodName);
0384: minfo.setMethodName(methodName);
0385:
0386: if (methodName.equals("<init>")) {
0387: minfo.setConstructor(true);
0388: methodName = minfo.getBelongsToClass();
0389: minfo.setMethodName(minfo.getBelongsToClass());
0390:
0391: }
0392:
0393: minfo.setAccessSpecifiers(accessSpecifiers);
0394: java.lang.String descriptor = getUTF8String(descriptorIndex);
0395: minfo.parseDescriptor(descriptor);
0396: java.lang.String zn = minfo.getMethodName();
0397: if (zn.indexOf(".") != -1)
0398: zn = zn.replaceAll("\\.", "/");
0399: minfo.setKey(descriptor + "" + zn);
0400:
0401: for (int j = 0; j < attributesCount; j++) {
0402: int attributeNameIndex = dis.readUnsignedShort();
0403: int attributeLength = dis.readInt();
0404: java.lang.String attrType = getUTF8String(attributeNameIndex);
0405: /*
0406: * byte[] info = new byte[attributeLength];
0407: * dis.read(info,0,attributeLength);
0408: */
0409: // System.out.println(attrType+"attrType");
0410: if (attrType.equals("Code")) {
0411: int max_stack = dis.readUnsignedShort();
0412: int max_locals = dis.readUnsignedShort();
0413: int code_length = dis.readInt();
0414:
0415: byte[] info = new byte[code_length];
0416: dis.readFully(info, 0, code_length);
0417:
0418: registerStartOfInstuctionsForMethod(info, minfo);
0419:
0420: // populate all gotos in code
0421: gotoStructure = new HashMap();
0422: gotoStarts = new ArrayList();
0423: gotojumps = new ArrayList();
0424: populateGotos(info, minfo);
0425:
0426: int exc_table_len = dis.readUnsignedShort();
0427: if (exc_table_len > 0)
0428: minfo.setExceptionTablePresent(true);
0429: ArrayList allexceptiontables = new ArrayList();
0430:
0431: for (int indx = 0; indx < exc_table_len; indx++) {
0432:
0433: int startPc = dis.readUnsignedShort();
0434: int endPc = dis.readUnsignedShort();
0435: int handlerPc = dis.readUnsignedShort();
0436: int catchType = dis.readUnsignedShort();
0437: MethodInfo.ExceptionTable etable = minfo.new ExceptionTable(
0438: startPc, endPc, handlerPc, catchType);
0439: if (catchType != 0) {
0440: ClassInfo cinfo = this
0441: .getClassInfoAtCPoolPosition(catchType);
0442: int utf8p = cinfo.getUtf8pointer();
0443: java.lang.String className = this
0444: .getUTF8String(utf8p);
0445: etable.setExceptionName(className);
0446: } else
0447: etable.setExceptionName("<any>");
0448:
0449: // Set Jump for Try
0450: // CHeck For Return Type
0451:
0452: byte tempCode[] = new byte[info.length];
0453: System.arraycopy(info, 0, tempCode, 0,
0454: tempCode.length);
0455: // etable.setEndForTry(endPc);
0456: allexceptiontables.add(etable);
0457:
0458: }
0459:
0460: ArrayList synchronizedTables = new ArrayList();
0461: allexceptiontables = handleTablesForSynchronizedCode(
0462: allexceptiontables, synchronizedTables,
0463: info, minfo);
0464:
0465: minfo
0466: .storeAllExcepptionTableRefs(allexceptiontables);
0467: minfo
0468: .setTablesForSynchronizedBlks(synchronizedTables);
0469: // Hanlde Type of Guard Region for each table
0470: Iterator alltables = allexceptiontables.iterator();
0471: while (alltables.hasNext()) {
0472:
0473: ExceptionTable table = (ExceptionTable) alltables
0474: .next();
0475: if (table.getExceptionName().equals("<any>") == false) {
0476: table.setTypeOfGuardRegion("try");
0477: } else {
0478: // Check for catch or Try
0479: java.lang.String guardType = checkForCatchOrTryGuard(
0480: table, allexceptiontables);
0481: if (guardType.length() == 0)
0482: guardType = "try";
0483: table.setTypeOfGuardRegion(guardType);
0484: }
0485:
0486: }
0487:
0488: int attr_cnt = dis.readUnsignedShort();
0489:
0490: readCodeAttributes(attr_cnt, dis, methodName, minfo);
0491:
0492: minfo.setCode(info);
0493:
0494: // Here switch objects are formed
0495: // to be used in parseJvmcodes method of Decompiler.java
0496: byte src[] = info;
0497: ArrayList startsOF = minfo.getInststartpos();
0498: for (int counter = 0; counter < src.length; counter++) {
0499:
0500: // System.out.println(methodName+"counter"+counter);
0501: int inst = -1;
0502: if (counter >= src.length)
0503: break;
0504: inst = info[counter];
0505: if (isThisInstrStart(startsOF, counter)
0506: && inst == JvmOpCodes.LOOKUPSWITCH) {
0507:
0508: int lookupSwitchPos = counter;
0509: int leave_bytes = (4 - (counter % 4)) - 1;
0510: for (int indx = 0; indx < leave_bytes; indx++) {
0511: counter++;
0512: }
0513: // Read Default
0514: int Default = getSwitchOffset(info,
0515: counter, "");// (info[++counter]
0516: // <<
0517: // 24)
0518: // |
0519: // (info[++counter]
0520: // <<
0521: // 16)
0522: // |
0523: // (info[++counter]
0524: // <<
0525: // 8)
0526: // |info[++counter];
0527: counter = counter + 4;
0528: int numberOfLabels = getSwitchOffset(info,
0529: counter, "");// (info[++counter] << 24) |
0530: // (info[++counter] << 16) |
0531: // (info[++counter] << 8)
0532: // |info[++counter];
0533: counter = counter + 4;
0534: int offsetValues[] = new int[numberOfLabels];
0535: int labels[] = new int[numberOfLabels];
0536: for (int start = 0; start < numberOfLabels; start++) {
0537:
0538: /*
0539: * int i1=info[++counter] ;
0540: *
0541: * int i2=info[++counter] ;
0542: *
0543: * int i3=info[++counter] ;
0544: *
0545: * int i4=info[++counter] ; if(i1 < 0)i1+=256;
0546: * if(i2 < 0)i2+=256; if(i3 < 0)i3+=256; if(i4 <
0547: * 0)i4+=256;
0548: */
0549:
0550: int label = getSwitchOffset(info,
0551: counter, "label");
0552: counter = counter + 4;
0553: /*
0554: * i1=info[++counter] ;
0555: *
0556: * i2=info[++counter] ;
0557: *
0558: * i3=info[++counter] ;
0559: *
0560: * i4=info[++counter] ; if(i1 < 0)i1+=256; if(i2 <
0561: * 0)i2+=256; if(i3 < 0)i3+=256; if(i4 <
0562: * 0)i4+=256;
0563: */
0564:
0565: int offsetVal = getSwitchOffset(info,
0566: counter, "");// (i1 << 24) + (i2 << 16) + (i3 <<
0567: // 8) +(i4<<0);
0568: counter = counter + 4;
0569:
0570: labels[start] = label;
0571: offsetValues[start] = offsetVal;
0572: // System.out.println(labels[start]+"\t"+offsetValues[start]);
0573: java.lang.String ss = "ss";
0574:
0575: }
0576: // Add to each offset
0577: for (int start = 0; start < numberOfLabels; start++) {
0578:
0579: offsetValues[start] = offsetValues[start]
0580: + lookupSwitchPos;
0581: }
0582: Default += lookupSwitchPos;
0583:
0584: // for(int
0585: // kk=0;kk<offsetValues.length;kk++)System.out.println(offsetValues[kk]);
0586: mapSwitchStartsWithLabels(offsetValues,
0587: labels);
0588: // for(int
0589: // kk=0;kk<offsetValues.length;kk++)System.out.println(offsetValues[kk]);
0590: Switch switchblk = new Switch(counter,
0591: Default);
0592: for (int starts = 0; starts < numberOfLabels; starts++) {
0593: int curlabel = labels[starts];
0594: int curOffset = offsetValues[starts];
0595: int next = starts + 1;
0596: int nextoffset = -1;
0597: int pos = getPositionForCaseLabel(curlabel);
0598: if (pos != -1) {
0599: int[] values = getCaseEnd(pos,
0600: curOffset, offsetValues,
0601: labels, Default, info,
0602: minfo);
0603: Switch.Case caseObj = switchblk.new Case(
0604: values[0], values[2],
0605: values[1]);
0606: switchblk.addCase(caseObj);
0607: } else {
0608: Writer writer = Writer
0609: .getWriter("log");
0610: writer
0611: .writeLog("Invalid position(-1) found for some case in switch block\n");
0612: writer.writeLog("Case Label: "
0613: + curlabel);
0614: writer.writeLog("Method "
0615: + minfo.getMethodName());
0616: writer.flush();
0617: }
0618: }
0619: minfo.addSwitchBlock(switchblk);
0620:
0621: } else if (isThisInstrStart(startsOF, counter)
0622: && inst == JvmOpCodes.TABLESWITCH) {
0623: int temp1 = -1;
0624: int temp2 = -1;
0625: int temp3 = -1;
0626: int temp4 = -1;
0627: int tableSwitchPos = counter;
0628: int leave_bytes = (4 - (counter % 4)) - 1;
0629: for (int indx = 0; indx < leave_bytes; indx++) {
0630: counter++;
0631: }
0632: // Read Default
0633: /*
0634: * temp1=info[++counter]; temp2=info[++counter];
0635: * temp3=info[++counter]; temp4=info[++counter];
0636: * if(temp1<0)temp1+=256; if(temp2<0)temp2+=256;
0637: * if(temp3<0)temp3+=256; if(temp4<0)temp4+=256;
0638: */
0639:
0640: int Default = getSwitchOffset(info,
0641: counter, "");
0642: counter = counter + 4;
0643: // temp1 << 24) + (temp2 << 16) + (temp3 << 8) +
0644: // (temp4 << 0);
0645:
0646: /*
0647: * temp1=info[++counter]; temp2=info[++counter];
0648: * temp3=info[++counter]; temp4=info[++counter];
0649: * if(temp1<0)temp1+=256; if(temp2<0)temp2+=256;
0650: * if(temp3<0)temp3+=256; if(temp4<0)temp4+=256;
0651: */
0652:
0653: int low = getSwitchOffset(info, counter,
0654: "label");// temp1
0655: // <<
0656: // 24)
0657: // +
0658: // (temp2
0659: // <<
0660: // 16)
0661: // +
0662: // (temp3
0663: // <<
0664: // 8) +
0665: // (temp4
0666: // <<
0667: // 0);
0668: counter = counter + 4;
0669:
0670: /*
0671: * temp1=info[++counter]; temp2=info[++counter];
0672: * temp3=info[++counter]; temp4=info[++counter];
0673: * if(temp1<0)temp1+=256; if(temp2<0)temp2+=256;
0674: * if(temp3<0)temp3+=256; if(temp4<0)temp4+=256;
0675: */
0676:
0677: int high = getSwitchOffset(info, counter,
0678: "label");// temp1
0679: // <<
0680: // 24)
0681: // +
0682: // (temp2
0683: // <<
0684: // 16)
0685: // +
0686: // (temp3
0687: // <<
0688: // 8) +
0689: // (temp4
0690: // <<
0691: // 0);
0692: counter = counter + 4;
0693: int numberOfOffsets = (high - low) + 1;
0694: int[] offsetValues = new int[numberOfOffsets];
0695: int labels[] = new int[numberOfOffsets];
0696: int labelName = low;
0697: for (int start = 0; start < numberOfOffsets; start++) {
0698: /*
0699: * temp1=info[++counter]; temp2=info[++counter];
0700: * temp3=info[++counter]; temp4=info[++counter];
0701: * if(temp1<0)temp1+=256; if(temp2<0)temp2+=256;
0702: * if(temp3<0)temp3+=256; if(temp4<0)temp4+=256;
0703: */
0704:
0705: int offsetVal = getSwitchOffset(info,
0706: counter, "");// temp1 << 24) + (temp2 << 16) +
0707: // (temp3 << 8) + (temp4 << 0);
0708: counter = counter + 4;
0709: offsetValues[start] = offsetVal;
0710: labels[start] = labelName;
0711: labelName++;
0712:
0713: }
0714: // Add to each offset
0715: for (int start = 0; start < numberOfOffsets; start++) {
0716:
0717: offsetValues[start] = offsetValues[start]
0718: + tableSwitchPos;
0719: }
0720: Default += tableSwitchPos;
0721:
0722: Switch switchblk = new Switch(
0723: tableSwitchPos, Default);
0724: mapSwitchStartsWithLabels(offsetValues,
0725: labels);
0726: for (int s = 0; s < numberOfOffsets; s++) {
0727: int caseStart = offsetValues[s];
0728: int next = s + 1;
0729: int nextCaseStart = -1;
0730: int curlabel = labels[s];
0731: int curOffset = offsetValues[s];
0732: int pos = getPositionForCaseLabel(curlabel);//
0733: if (pos != -1) {
0734: int[] values = getCaseEnd(pos,
0735: curOffset, offsetValues,
0736: labels, Default, info,
0737: minfo);
0738: Switch.Case caseObj = switchblk.new Case(
0739: values[0], values[2],
0740: values[1]);
0741: // Switch.Case caseObj=switchblk.new
0742: // Case(caseStart,nextCaseStart,labels[s]);
0743: // // TODO
0744: switchblk.addCase(caseObj);
0745: } else {
0746: Writer writer = Writer
0747: .getWriter("log");
0748: writer
0749: .writeLog("Invalid position(-1) found for some case in switch block\n");
0750: writer.writeLog("Case Label: "
0751: + curlabel);
0752: writer.writeLog("Method "
0753: + minfo.getMethodName());
0754: writer.flush();
0755: }
0756:
0757: }
0758: minfo.addSwitchBlock(switchblk);
0759:
0760: }
0761:
0762: int bytesToSkip = 0;
0763: boolean increment = false;
0764: boolean isif = isInstructionIF(inst);
0765:
0766: if (isThisInstrStart(startsOF, counter)
0767: && !isif && inst != JvmOpCodes.GOTO
0768: && inst != JvmOpCodes.GOTO_W
0769: && inst != JvmOpCodes.WIDE
0770: && inst != JvmOpCodes.LOOKUPSWITCH
0771: && inst != JvmOpCodes.TABLESWITCH) {
0772: bytesToSkip = skipBytes(inst, counter, src);
0773: increment = true;
0774: }
0775: if (isThisInstrStart(startsOF, counter)
0776: && (inst == JvmOpCodes.GOTO || isif)) {
0777: // System.out.println(counter);
0778: int b1 = info[++counter];
0779: int b2 = info[++counter];
0780: int z;
0781: if (b1 < 0)
0782: b1 = (256 + b1);
0783: if (b2 < 0)
0784: b2 = (256 + b2);
0785: DataInputStream ds;
0786: int indexInst = ((((b1 << 8) | b2)) + (counter - 2));
0787: if (indexInst > 65535)
0788: indexInst = indexInst - 65536;
0789: if (indexInst < 0)
0790: indexInst = 256 + indexInst;
0791: if (counter - 2 >= indexInst) {
0792: // definitely is a loop
0793: // check if the instruction at the goto index is
0794: // a load.
0795: // If it is a load then it is a terminating loop
0796: // else it is an infinite loop.
0797: boolean isStore = false;
0798: Loop loop = new Loop();
0799:
0800: boolean isLoad = IsGotoIndexInstructionIsALoad(
0801: indexInst, info); // modified by
0802: // belurs
0803: isStore = doesStoreFollowLoad(
0804: indexInst, info, minfo);
0805: if (!isLoad) {
0806: isLoad = isGotoIndexInstructionAInvoke(
0807: indexInst, info);
0808: }
0809:
0810: // check if there is a load instruction at the
0811: // index of the of the goto
0812: // if the next instruction is a Load Instruction
0813: // else it is an infininte loop
0814: loop.setStartIndex(indexInst);
0815: java.lang.String ifname = "";
0816:
0817: int loopEnd = -1;
0818: if (isif == false)
0819: loopEnd = getMaxGotoStartGivenJump(indexInst);
0820: // int
0821: // ifJumpIndex=findIfInstructionForThisLoop(info,indexInst,ifname);
0822: if (loopEnd != -1) {
0823: loop.setEndIndex(loopEnd);
0824: } else {
0825: loop.setEndIndex(counter - 2);
0826: }
0827: // loop.setEndIndex(counter-2);
0828: // System.out.println("isLoad"+isLoad+"
0829: // Inst"+inst+" start"+indexInst+"
0830: // End"+(loop.getEndIndex()));
0831: /*
0832: * if(isLoad) { //terminating loop
0833: * loop.setInfinite(false); } else { //infinite
0834: * Loop loop.setInfinite(true); } if(isStore) {
0835: * loop.setInfinite(true); } boolean
0836: * rangeCheck=checkLoopRange(loop.getStartIndex(),loop.getEndIndex(),src,minfo);
0837: * if(rangeCheck) { loop.setInfinite(true); }
0838: */
0839:
0840: int end = getLoopConditionalEnd(loop,
0841: minfo);
0842: if (end > loop.getEndIndex()
0843: && end != -1) {
0844: if (info[loop.getEndIndex()] != JvmOpCodes.GOTO)
0845: loop.setLoopEndForBracket(end);
0846: }
0847: boolean isdowhile = markLoopAsDoWhileType(
0848: loop.getStartIndex(), info,
0849: minfo);
0850: if (isdowhile) {
0851: loop.setDoWhile(isdowhile);
0852: }
0853: minfo.getBehaviourLoops().add(loop);
0854: }
0855: }
0856:
0857: if (isThisInstrStart(startsOF, counter)
0858: && inst == JvmOpCodes.WIDE) {
0859: // Inst is Wide...Need Special Handling
0860: int nextPos = counter + 1;
0861: if (isThisInstrStart(minfo
0862: .getInststartpos(), nextPos)
0863: && src[nextPos] == JvmOpCodes.IINC) {
0864:
0865: counter = counter + 4;
0866:
0867: } else {
0868: counter = counter + 2;
0869: }
0870:
0871: }
0872: if (increment && bytesToSkip != 0) {
0873: // Need to skip
0874: for (int s = 0; s < bytesToSkip; s++) {
0875: counter = counter + 1;
0876: }
0877: increment = false;
0878:
0879: }
0880:
0881: }
0882: ArrayList uniqueLoops = Loop.removeDuplicates(minfo
0883: .getBehaviourLoops());
0884: minfo.setLoops(uniqueLoops);
0885: // Need to reset end of loops again
0886: // Done because at this time some loops have if as their
0887: // ends
0888: // IF cannot be end of loop
0889:
0890: resetEndOfLoops(minfo.getBehaviourLoops(), minfo);
0891:
0892: ArrayList allswicthes = minfo
0893: .getAllSwitchBlksForMethod();
0894: if (allswicthes != null) {
0895: Iterator allswIterator = allswicthes.iterator();
0896: while (allswIterator.hasNext()) {
0897: Switch switchBlock = (Switch) allswIterator
0898: .next();
0899: switchBlock.removeUnwantedCaseBlocks();
0900: }
0901: }
0902:
0903: // In This Step Need to check whether Try Block
0904: // gets ended properly or not.
0905: // Refer to trycatchfinally.txt File for any doubts
0906:
0907: alltables = allexceptiontables.iterator();
0908: ArrayList completeList = minfo
0909: .getExceptionTablesSortedByStartHandlerPC();
0910: Iterator it = completeList.iterator();
0911: while (it.hasNext()) {
0912: // Handle Each Sublist
0913: ArrayList subList = (ArrayList) it.next();
0914: ExceptionTable etable = minfo
0915: .getExceptionTableForSmallestStartOfGuard(subList);
0916: java.lang.String typeofhandler = etable
0917: .getTypeOfHandlerForGuardRegion();
0918:
0919: if (typeofhandler.equals("CatchBlock")) {
0920: int endOfTry = findEndOfTry(subList, minfo);
0921: if (endOfTry != -1)
0922: etable.setEndOfGuardRegion(endOfTry);
0923: ExceptionTable tab = minfo
0924: .getExceptionTableForSmallestStartOfGuard(subList);
0925: resetEndOfTries(subList, tab, minfo);
0926: // System.out.println();
0927: // Create new Exception Tables Here.
0928: // For Those not produced by compiler
0929: int TryStart = etable
0930: .getStartOfGuardRegion();
0931: int TryEnd = findEndOfTryForCreatedTable(
0932: subList, minfo);
0933: if (TryEnd != -1) {
0934: int HandlerPC = etable
0935: .getStartOfHandlerForGuardRegion();
0936: java.lang.String exName = etable
0937: .getExceptionName();
0938: MethodInfo.ExceptionTable newTable = minfo.new ExceptionTable(
0939: etable.getStartPC(), etable
0940: .getEndPC(), etable
0941: .getStartOfHandler(),
0942: exName);
0943: newTable.setTypeOfGuardRegion("try");
0944: newTable.setEndOfGuardRegion(TryEnd);
0945: minfo.addNewExceptionTable(newTable);
0946: etable.setEndOfGuardRegion(newTable
0947: .getEndPC());
0948: // System.out.println();
0949: }
0950: ArrayList delete = minfo
0951: .getAllExceptionTables();
0952: // System.out.println();
0953: } else if (typeofhandler.equals("FinallyBlock")) {
0954: int startOfHandler = ((ExceptionTable) subList
0955: .get(0))
0956: .getStartOfHandlerForGuardRegion();
0957: Iterator allextables = allexceptiontables
0958: .iterator();
0959: boolean catchPresent = false;
0960: int catchIndex = -1;
0961: ArrayList catchHandlers = new ArrayList();
0962: while (allextables.hasNext()) {
0963: ExceptionTable etab = (ExceptionTable) allextables
0964: .next();
0965: if (etab.getStartOfGuardRegion() == etable
0966: .getStartOfGuardRegion()
0967: && etab.getEndOfGuardRegion() == etable
0968: .getEndOfGuardRegion()
0969: && etab != etable) {
0970: if (etab.getExceptionName().equals(
0971: "<any>") == false) {
0972: catchPresent = true;
0973: catchIndex = etab
0974: .getStartOfHandlerForGuardRegion();
0975: catchHandlers.add(new Integer(
0976: catchIndex));
0977: }
0978: }
0979: }
0980: // System.out.println();
0981: if (catchPresent == true) {
0982: int temp[] = new int[catchHandlers
0983: .size()];
0984: for (int s = 0; s < catchHandlers
0985: .size(); s++) {
0986: int in = ((Integer) catchHandlers
0987: .get(s)).intValue();
0988: temp[s] = in;
0989: }
0990: Arrays.sort(temp);
0991: catchIndex = temp[0];
0992:
0993: }
0994: if (catchPresent == true
0995: && catchIndex != -1) {
0996: ArrayList sortedList = minfo
0997: .getSortedExceptionTablesForEndOfGuard(subList);
0998: for (int c = (sortedList.size() - 1); c >= 0; c--) {
0999: ExceptionTable et = (ExceptionTable) sortedList
1000: .get(c);
1001: if (et.getEndOfGuardRegion() < catchIndex) {
1002: etable.setEndOfGuardRegion(et
1003: .getEndOfGuardRegion());
1004: // System.out.println();
1005: break;
1006: }
1007: }
1008: } else {
1009: ArrayList sortedList = minfo
1010: .getSortedExceptionTablesForEndOfGuard(subList);
1011: sortedList = checkForInvalidEntry(sortedList);
1012: for (int c = (sortedList.size() - 1); c >= 0; c--) {
1013: ExceptionTable et = (ExceptionTable) sortedList
1014: .get(c);
1015: if (et.getEndOfGuardRegion() <= startOfHandler) // TODO:
1016: // Verify
1017: // if =
1018: // is
1019: // indeed
1020: // correct.
1021: // right
1022: // now
1023: // a
1024: // guess
1025: {
1026: etable.setEndOfGuardRegion(et
1027: .getEndOfGuardRegion());
1028: break;
1029: } else if (et.getEndOfGuardRegion() > startOfHandler) // ?
1030: // Should
1031: // never
1032: // come
1033: // here//
1034: // Check
1035: {
1036: etable
1037: .setEndOfGuardRegion(startOfHandler);
1038: break;
1039: }
1040:
1041: }
1042: // System.out.println();
1043: }
1044:
1045: }
1046:
1047: }
1048:
1049: // need to reset end of tries in allexception table list
1050: // w.r.t to the created exception table list
1051:
1052: ArrayList createdList = minfo.getCreatedTableList();
1053: if (createdList != null) {
1054: for (int s = 0; s < createdList.size(); s++) {
1055: ExceptionTable t1 = (ExceptionTable) createdList
1056: .get(s);
1057: ArrayList Alltables = minfo
1058: .getAllExceptionTables();
1059: for (int s2 = 0; s2 < Alltables.size(); s2++) {
1060: ExceptionTable et = (ExceptionTable) Alltables
1061: .get(s2);
1062: if (et.getStartPC() == t1.getStartPC()
1063: && et.getEndPC() == t1
1064: .getEndPC()
1065: && et.getStartOfHandler() == t1
1066: .getStartOfHandler()
1067: && et
1068: .getExceptionName()
1069: .equals(
1070: t1
1071: .getExceptionName())) {
1072: et.setEndOfGuardRegion(t1
1073: .getEndOfGuardRegion());
1074: break;
1075: }
1076: }
1077:
1078: }
1079: }
1080:
1081: // need to reset the end of Exception Table whose handler is
1082: // Finally
1083: // because of the created Exception Table List.
1084: // This should actually CORRECTLY ASSOCIATE a finally block
1085: // to an outer try rather than inner try
1086:
1087: // TODO: Check again
1088:
1089: ArrayList tablesWithFinally = minfo
1090: .getTablesWithFinally();
1091: if (tablesWithFinally != null) {
1092: ArrayList overList = new ArrayList();
1093: Iterator it1 = (tablesWithFinally.iterator());
1094: while (it1.hasNext()) {
1095: ExceptionTable et1 = (ExceptionTable) it1
1096: .next();
1097: boolean skip = SkipThisFinallyHandler(et1,
1098: overList);
1099: if (skip == false) {
1100: ArrayList tryTablesWithSamePCS = minfo
1101: .getTryTablesWithPCRange(et1
1102: .getStartPC(), et1
1103: .getEndPC());
1104: if (tryTablesWithSamePCS != null) {
1105: ArrayList sorted = minfo
1106: .getSortedExceptionTablesForEndOfGuard(tryTablesWithSamePCS);
1107: ExceptionTable biggest = (ExceptionTable) sorted
1108: .get(sorted.size() - 1);
1109: int biggestEnfOfGuard = biggest
1110: .getEndOfGuardRegion();
1111: if (biggestEnfOfGuard < et1
1112: .getStartOfHandlerForGuardRegion()) {
1113: et1
1114: .setEndOfGuardRegion(biggestEnfOfGuard);
1115: }
1116: }
1117: }
1118:
1119: }
1120: }
1121:
1122: ArrayList delete = minfo.getAllExceptionTables(); // Delete
1123: // Later
1124: // Link all Exception Tables and complete the blocks Package
1125:
1126: linkAllExceptionTables(minfo);
1127:
1128: // Determine if Finally Exist and where they end
1129: // TODO: Not all cases covered.
1130: // Check for
1131: // 1> return from finally
1132: // 2> Loops
1133: // 3> Conditionals
1134: // 4> Throw an exception
1135: // 5> Embed Try Catch/Finally
1136: // 6> Embed switch
1137: // 7> Test with outer Finally/catch
1138:
1139: alltables = allexceptiontables.iterator();
1140: ArrayList tries = minfo.getAllTryBlocksForMethod();
1141:
1142: while (alltables.hasNext()) {
1143: ExceptionTable curtable = (ExceptionTable) alltables
1144: .next();
1145: findEndOfinallyForTable(curtable, info, minfo);
1146: updateEndOfFinallyForFinallyBlocks(curtable,
1147: tries);
1148: }
1149:
1150: // Need to Find the end of Default for Each switch here
1151: // TODO:
1152: /***********************************************************
1153: *
1154: * 1>Find Default only if there is a clear indication that
1155: * there is a default for this switch 2>If all are returning
1156: * from each case then for the moment ignore default. 3>If
1157: * default end will not be found for a switch then make it
1158: * clear in that switch objec (add a boolean variable) 4>Use
1159: * this boolean variable while polling for switch tables in
1160: * parseJvmCodes
1161: *
1162: */
1163:
1164: allswicthes = minfo.getAllSwitchBlksForMethod();
1165:
1166: if (allswicthes != null) {
1167: Iterator allswIterator = allswicthes.iterator();
1168: while (allswIterator.hasNext()) {
1169: Switch switchBlock = (Switch) allswIterator
1170: .next();
1171: boolean skip = skipCurrentSwitch(
1172: switchBlock, minfo);
1173: switchBlock.setDisplayDefault(!skip);
1174: switchBlock.setEndOfDefault(switchBlock
1175: .getDefaultStart()); // Done keeping the
1176: // above mentioned
1177: // points in mind .
1178: // So For This
1179: // switch NO default
1180: // will be displayed
1181: if (skip == false) {
1182: int defaultStart = switchBlock
1183: .getDefaultStart();
1184: findEndOfDefaultForSwitch(switchBlock,
1185: defaultStart, minfo.getCode(),
1186: minfo);
1187: }
1188:
1189: setFallThruForCases(switchBlock, minfo
1190: .getCode());
1191: if (switchBlock.getDefaultEnd() == switchBlock
1192: .getDefaultStart()) {
1193: // switchBlock.setDisplayDefault(false);
1194: // Commented for test case swtest.class
1195: }
1196: }
1197: }
1198:
1199: // linkCreatedExceptionTables(minfo);
1200: // End of Link
1201: // System.out.println();
1202:
1203: // Reset end of tries w.r.t contained blocks
1204: // (Problem found when no finally is present and last catch
1205: // does not end properly)
1206: ArrayList exptables = minfo.getAllExceptionTables();
1207: ArrayList alltries = minfo
1208: .getAllTryBlocksForMethod();
1209:
1210: // First check with all loops
1211: ArrayList loops = minfo.getBehaviourLoops();
1212: for (int jj = 0; jj < alltries.size(); jj++) {
1213: TryBlock TRY = (TryBlock) alltries.get(jj);
1214: if (!TRY.hasFinallyBlk()) {
1215: CatchBlock lastcatch = TRY
1216: .getLastCatchBlock();
1217: if (lastcatch != null) {
1218: int origs = lastcatch.getStart();
1219: int orige = lastcatch.getEnd();
1220:
1221: int newend = checkEndOFLastCatchWRTContainedLoops(
1222: lastcatch, loops);
1223: if (newend != -1) {
1224: if ((newend - 3) > 0)
1225: lastcatch.setEnd(newend - 3);
1226: }
1227: newend = checkEndOfLastCatchWRTCaseBlks(
1228: lastcatch, allswicthes);
1229: if (newend != -1) {
1230: if ((newend - 3) > 0)
1231: lastcatch.setEnd(newend - 3);
1232: }
1233:
1234: // Now set in the exception table block this new
1235: // end
1236: for (int x = 0; x < exptables.size(); x++) {
1237: ExceptionTable extab = (ExceptionTable) exptables
1238: .get(x);
1239: java.lang.String type = extab
1240: .getTypeOfHandlerForGuardRegion();
1241: if (type
1242: .equalsIgnoreCase("CatchBlock")
1243: || type.indexOf("Catch") >= 0
1244: || type.indexOf("catch") >= 0) {
1245: int handlers = extab
1246: .getStartOfHandlerForGuardRegion();
1247: int handlere = extab
1248: .getEndOfHandlerForGuardRegion();
1249: if (origs == handlers
1250: && orige == handlere) {
1251: extab
1252: .setEndOfHandlerForGuardRegion(lastcatch
1253: .getEnd());
1254: }
1255:
1256: }
1257:
1258: }
1259:
1260: }
1261:
1262: }
1263:
1264: }
1265:
1266: // [NOTE:belurs]
1267: // Need to check for illegal tries here again.
1268: // Refer javap output for ActionItemListener.class for this
1269:
1270: ArrayList methodtries = minfo
1271: .getAllTryBlocksForMethod();
1272: ArrayList list1 = getAllExceptionBlocksWithSameTryStart(methodtries);
1273: if (list1 != null) {
1274: for (int z = 0; z < list1.size(); z++) {
1275:
1276: ArrayList list2 = (ArrayList) list1.get(z);
1277: checkForIllegalTriesForList(list2,
1278: methodtries);
1279:
1280: }
1281:
1282: }
1283:
1284: // BUGFIX For switch case end problem
1285: // Need to figure out if there is any enclosing switch for
1286: // current switch
1287: // and constantly check while ending case of this switch if
1288: // any case
1289: // of sorrounding switch is starting. If so end the case and
1290: // switch as well!!!
1291:
1292: checkEndOfSwitchAndCaseBlockWRTOuterSwitches(minfo);
1293:
1294: }
1295:
1296: else if (attrType.equals("Exceptions")) {
1297: // int type = dis.readUnsignedShort();
1298:
1299: // int length = dis.readInt();
1300: int no_of_exceptions = dis.readUnsignedShort();
1301:
1302: for (int k = 0; k < no_of_exceptions; k++) {
1303: int class_index = dis.readUnsignedShort();
1304: ClassInfo cinfo = getClassInfoAtCPoolPosition(class_index);
1305: minfo.addExceptions(getUTF8String(cinfo
1306: .getUtf8pointer()));
1307:
1308: }
1309:
1310: // minfo.addExceptions(attr)
1311: }
1312:
1313: else if (attrType.equals("Deprecated")) {
1314: // Nothing to be done here
1315:
1316: } else if (attrType.equals("Synthetic")) {
1317: // Nothing to be done here
1318: }
1319:
1320: else // ************ NOTE ******************************
1321: // Should NOT come here according to the Class Spec
1322: // If it comes here it either means there is a problem
1323: // in which this jdec is reading the bytes of the
1324: // Class file OR the Class file format for the class
1325: // being decompiled does NOT conform to the class
1326: // Spec(// TODO put the details of class spec here like version
1327: // number etc)
1328: // ************ NOTE ******************************
1329:
1330: {
1331: // LOG this unknown attribute read
1332: Writer writer = Writer.getWriter("log");
1333: writer
1334: .writeLog("Unknown attribute encountered while parsing the attributes of a method ..."
1335: + attrType);
1336: writer
1337: .writeLog("\nProceeding to read the bytes for this attribute....");
1338:
1339: byte unknownAttrbContent[] = new byte[attributeLength];
1340: dis.read(unknownAttrbContent, 0, attributeLength);
1341:
1342: }
1343:
1344: }
1345:
1346: allMethods[i] = minfo;
1347: if (!compiledWithMinusG) {
1348: LocalVariableStructure localStructure = new LocalVariableStructure();
1349: localStructure.setMethodDescription(methodName
1350: .concat(minfo.getStringifiedParameters()));
1351: LocalVariableTable localVarTable = LocalVariableTable
1352: .getInstance();
1353: localVarTable.addEntry(methodName.concat(minfo
1354: .getStringifiedParameters().concat(
1355: "" + minfo.isConstructor())),
1356: localStructure);
1357: minfo.setStructure(localStructure);
1358: }
1359: if (minfo.getCode() != null) {
1360: scanCodeForLocalVariables(minfo);
1361: }
1362:
1363: // minfo.getReturnType();
1364: // System.out.println();
1365: ShortcutAnalyser analyser = new ShortcutAnalyser(minfo,
1366: minfo.getCode());
1367: analyser.analysze();
1368: analyser.checkMissingLinks();
1369: analyser.collectGroups();
1370: analyser.collectLastIfs();
1371: minfo.setShortCutAnalyser(analyser);
1372:
1373: // Test ...TODO: Remove when done
1374: // analyser.testConnectors();
1375:
1376: }
1377:
1378: }
1379:
1380: private void printAccessSpecifies(ArrayList printAccessSpecifies) {
1381: Iterator it = printAccessSpecifies.iterator();
1382:
1383: /*
1384: * while(it.hasNext()) { System.out.print(it.next()); if(it.hasNext()) }
1385: */
1386:
1387: }
1388:
1389: public void setConstantPool(CPool cpool) {
1390: this .cpool = cpool;
1391: }
1392:
1393: public CPool getConstantPool(CPool cpool) {
1394: return cpool;
1395: }
1396:
1397: public java.lang.String getUTF8String(int cppos) {
1398: // printAllUTF8Strings();
1399: java.lang.String utf8String = "";
1400:
1401: Iterator iter = cpool.getAllUtf8().iterator();
1402: java.lang.String dummys = "";
1403: while (iter.hasNext()) {
1404: UTF8 utf8 = (UTF8) iter.next();
1405: if (utf8.getCppos() == cppos) {
1406:
1407: /*
1408: * try { utf8String = new
1409: * java.lang.String(utf8.getBytes(),"UTF-8");
1410: * dummys=utf8.getStringVal(); } catch(
1411: * UnsupportedEncodingException une) { dummys = new
1412: * java.lang.String(utf8.getBytes()); } int dummy=1;
1413: */
1414: dummys = utf8.getStringVal();// new
1415: // java.lang.String(utf8.getBytes());
1416: // dummys=utf8.getStringVal();
1417: break;
1418: }
1419: }
1420:
1421: if (dummys.indexOf(Constants.tab) != -1) {
1422: dummys = dummys.replaceAll(Constants.tab, "\\\\t");
1423: }
1424: if (dummys.indexOf(Constants.newline) != -1) {
1425: dummys = dummys.replaceAll(Constants.newline, "\\\\n");
1426: }
1427: if (dummys.indexOf(Constants.carriageret) != -1) {
1428: dummys = dummys.replaceAll(Constants.carriageret, "\\\\r");
1429: }
1430: if (dummys.indexOf(Constants.backspace) != -1) {
1431: dummys = dummys.replaceAll(Constants.backspace, "\\\\b");
1432: }
1433: if (dummys.indexOf(Constants.formfeed) != -1) {
1434: dummys = dummys.replaceAll(Constants.formfeed, "\\\\f");
1435: }
1436: if (dummys.indexOf(Constants.doubleQuote) != -1) {
1437: dummys = dummys.replaceAll(Constants.doubleQuote,
1438: "\\\\\\\"");
1439: }
1440: if (dummys.indexOf(Constants.singleQuote) != -1) {
1441: dummys = dummys.replaceAll(Constants.singleQuote, "\\\\\'");
1442: }
1443: if (dummys.indexOf(Constants.dot) != -1) {
1444: dummys = dummys.replaceAll(Constants.dot, "\\\\\\.'");
1445: }
1446: /*
1447: * if(dummys.indexOf(Constants.backslash)!=-1){
1448: * dummys=dummys.replaceAll("\\[~tbnf'\"]"+Constants.backslash,"\\\\\\\\"); }
1449: */
1450: /*
1451: * if(dummys.indexOf(Constants.backslash)!=-1){ int
1452: * i=dummys.indexOf(Constants.backslash); int j=i+1; int start=j;
1453: * while(start!=-1 && start < dummys.length()){ if(dummys.charAt(j)!='b' &&
1454: * dummys.charAt(j)!='f' && dummys.charAt(j)!='r' &&
1455: * dummys.charAt(j)!='n' && dummys.charAt(j)!='t' &&
1456: * dummys.charAt(j)!='\"' && dummys.charAt(j)!='\''){ int
1457: * next=dummys.indexOf(Constants.backslash,i); if(next==(i+1) &&
1458: * (next+1) < dummys.length()){ next=dummys.charAt(next+1);
1459: * if(dummys.charAt(j)!='b' && dummys.charAt(j)!='f' &&
1460: * dummys.charAt(j)!='r' && dummys.charAt(j)!='n' &&
1461: * dummys.charAt(j)!='t' && dummys.charAt(j)!='\"' &&
1462: * dummys.charAt(j)!='\''){ } }
1463: *
1464: * start=start+1; } int temp=dummys.indexOf(Constants.backslash,start);
1465: * if(temp <= start)break; start=temp; j=start; } }
1466: */
1467:
1468: return dummys;
1469: }
1470:
1471: public ClassInfo getClassInfoAtCPoolPosition(int cppos) {
1472: ClassInfo cinfo = null;
1473: boolean present = false;
1474: Iterator iter = cpool.getAllClassInfos().iterator();
1475: while (iter.hasNext()) {
1476: cinfo = (ClassInfo) iter.next();
1477: if (cinfo.getCppos() == cppos) {
1478: present = true;
1479: break;
1480: }
1481: }
1482: if (present)
1483: return cinfo;
1484: else
1485: return null;
1486: }
1487:
1488: public InterfaceMethodRef getInterfaceMethodAtCPoolPosition(
1489: int cppos) {
1490: InterfaceMethodRef interfaceRef = null;
1491: boolean present = false;
1492: Iterator iter = cpool.getAllInterfaceMethodRefs().iterator();
1493:
1494: while (iter.hasNext()) {
1495: interfaceRef = (InterfaceMethodRef) iter.next();
1496: if (interfaceRef.getCppos() == cppos) {
1497: present = true;
1498: break;
1499: }
1500: }
1501: if (present)
1502: return interfaceRef;
1503: else
1504: return null;
1505: }
1506:
1507: public CPString getStringsAtCPoolPosition(int cppos) {
1508: CPString cinfo = null;
1509: boolean present = false;
1510: Iterator iter = cpool.getAllStrings().iterator();
1511: while (iter.hasNext()) {
1512: cinfo = (CPString) iter.next();
1513: if (cinfo.getCppos() == cppos) {
1514: present = true;
1515: break;
1516: }
1517: }
1518: if (present)
1519: return cinfo;
1520: else
1521: return null;
1522: }
1523:
1524: public IntPrimitive getINTPrimitiveAtCPoolPosition(int cppos) {
1525: IntPrimitive cinfo = null;
1526: boolean intPresent = false;
1527: Iterator iter = cpool.getAllIntegers().iterator();
1528: while (iter.hasNext()) {
1529: cinfo = (IntPrimitive) iter.next();
1530: if (cinfo.getCppos() == cppos) {
1531: intPresent = true;
1532: break;
1533: } else
1534: intPresent = false;
1535: }
1536: if (intPresent)
1537: return cinfo;
1538: else
1539: return null;
1540: }
1541:
1542: public FloatPrimitive getFloatPrimitiveAtCPoolPosition(int cppos) {
1543: FloatPrimitive cinfo = null;
1544: boolean floatPresent = false;
1545: Iterator iter = cpool.getAllFloats().iterator();
1546: while (iter.hasNext()) {
1547: cinfo = (FloatPrimitive) iter.next();
1548: if (cinfo.getCppos() == cppos) {
1549: floatPresent = true;
1550: break;
1551: } else
1552: floatPresent = false;
1553: }
1554: if (floatPresent)
1555: return cinfo;
1556: else
1557: return null;
1558: }
1559:
1560: public DoublePrimitive getDoublePrimitiveAtCPoolPosition(int cppos) {
1561: DoublePrimitive cinfo = null;
1562: boolean doublePresent = false;
1563: Iterator iter = cpool.getAllDoubles().iterator();
1564: while (iter.hasNext()) {
1565: cinfo = (DoublePrimitive) iter.next();
1566: if (cinfo.getCppos() == cppos) {
1567: doublePresent = true;
1568: break;
1569: } else
1570: doublePresent = false;
1571: }
1572: if (doublePresent)
1573: return cinfo;
1574: else
1575: return null;
1576: }
1577:
1578: public LongPrimitive getLongPrimitiveAtCPoolPosition(int cppos) {
1579: LongPrimitive cinfo = null;
1580: boolean longPresent = false;
1581: Iterator iter = cpool.getAllLongs().iterator();
1582: while (iter.hasNext()) {
1583: cinfo = (LongPrimitive) iter.next();
1584: if (cinfo.getCppos() == cppos) {
1585: longPresent = true;
1586: break;
1587: } else
1588: longPresent = false;
1589: }
1590: if (longPresent)
1591: return cinfo;
1592: else
1593: return null;
1594: }
1595:
1596: public NameAndType getNameAndTypeAtCPoolPosition(int cppos) {
1597: NameAndType cinfo = null;
1598: boolean present = false;
1599: Iterator iter = cpool.getAllNameAndTypes().iterator();
1600: while (iter.hasNext()) {
1601: cinfo = (NameAndType) iter.next();
1602: if (cinfo.getCppos() == cppos) {
1603: present = true;
1604: break;
1605: }
1606: }
1607: if (present)
1608: return cinfo;
1609: else
1610: return null;
1611:
1612: }
1613:
1614: public MethodRef getMethodRefAtCPoolPosition(int cppos) {
1615: MethodRef cinfo = null;
1616: boolean present = false;
1617: Iterator iter = cpool.getAllMethodRefs().iterator();
1618: while (iter.hasNext()) {
1619: cinfo = (MethodRef) iter.next();
1620: if (cinfo.getCppos() == cppos) {
1621: present = true;
1622: break;
1623: }
1624: }
1625: if (present)
1626: return cinfo;
1627: else
1628: return null;
1629: }
1630:
1631: public FieldRef getFieldRefAtCPoolPosition(int cppos) {
1632: FieldRef cinfo = null;
1633: boolean present = false;
1634: Iterator iter = cpool.getAllFieldRefs().iterator();
1635: while (iter.hasNext()) {
1636: cinfo = (FieldRef) iter.next();
1637: if (cinfo.getCppos() == cppos) {
1638: present = true;
1639: break;
1640: }
1641: }
1642: if (present)
1643: return cinfo;
1644: else
1645: return null;
1646:
1647: }
1648:
1649: public void printAllUTF8Strings() {
1650: Iterator iter = cpool.getAllUtf8().iterator();
1651: while (iter.hasNext()) {
1652: UTF8 utf8 = (UTF8) iter.next();
1653:
1654: }
1655:
1656: }
1657:
1658: public void printAllClassInfos() {
1659: Iterator iter = cpool.getAllClassInfos().iterator();
1660: while (iter.hasNext()) {
1661: ClassInfo utf8 = (ClassInfo) iter.next();
1662:
1663: }
1664:
1665: }
1666:
1667: public void printAllUtf8StringInNameAndTypeObjects() {
1668: NameAndType cinfo = null;
1669:
1670: Iterator iter = cpool.getAllNameAndTypes().iterator();
1671: while (iter.hasNext()) {
1672: cinfo = (NameAndType) iter.next();
1673: // System.out.println(""+getUTF8String(cinfo.getUtf8pointer()));
1674: }
1675:
1676: }
1677:
1678: public void setCompiledWithMinusG(boolean compiledWithMinusG) {
1679: this .compiledWithMinusG = compiledWithMinusG;
1680: }
1681:
1682: public boolean isClassCompiledWithMinusG() {
1683: return compiledWithMinusG;
1684: }
1685:
1686: private boolean compiledWithMinusG = false;
1687:
1688: private void readCodeAttributes(int attr_cnt, DataInputStream dis,
1689: java.lang.String methodName, MethodInfo minfo)
1690: throws IOException
1691:
1692: {
1693: for (int i = 0; i < attr_cnt; i++) {
1694: int attr_name_index = dis.readUnsignedShort(); // name of attribute
1695: java.lang.String attrType = getUTF8String(attr_name_index);
1696: if (attrType.equals("LocalVariableTable")) {
1697: int attr_len = dis.readInt(); // Attribute Length
1698: int localVarTableLen = dis.readUnsignedShort(); // Lcal var
1699: // table length
1700: ArrayList variableList = new ArrayList();
1701: for (int count = 0; count < localVarTableLen; count++) {
1702:
1703: int start_pc = dis.readUnsignedShort();
1704: int len = dis.readUnsignedShort();
1705: int name_index = dis.readUnsignedShort();
1706: java.lang.String localvarName = getUTF8String(name_index);
1707: // System.out.println(localvarName);
1708: int desc_index = dis.readUnsignedShort();
1709: java.lang.String localVardescription = getUTF8String(desc_index);
1710: int index = dis.readUnsignedShort();
1711: compiledWithMinusG = true;
1712:
1713: ConsoleLauncher
1714: .setCurrentClassCompiledWithDebugInfo(true);
1715:
1716: if (index < minfo.getParametersArrayLength()) {
1717: LocalVariable localvar = new LocalVariable(
1718: methodName.concat(minfo
1719: .getStringifiedParameters()),
1720: localVardescription, localvarName,
1721: index, true);
1722: localvar.setBlockStart(start_pc);
1723: localvar.setBlockEnd(start_pc + len);
1724: variableList.add(localvar);
1725: } else {
1726: // 1> Form A local variable Object here
1727: LocalVariable localvar = new LocalVariable(
1728: methodName.concat(minfo
1729: .getStringifiedParameters()),
1730: localVardescription, localvarName,
1731: index);
1732: localvar.setBlockStart(start_pc);
1733: localvar.setBlockEnd(start_pc + len);
1734: variableList.add(localvar);
1735: }
1736:
1737: // 2> Add to ArrayList
1738:
1739: }
1740:
1741: // 3> Create LocalVariableStructure Object and populate
1742:
1743: LocalVariableStructure localStructure = new LocalVariableStructure();
1744: localStructure.setMethodDescription(methodName.concat(
1745: minfo.getStringifiedParameters()).concat(
1746: "" + minfo.isConstructor()));
1747: localStructure.setMethodLocalVaribales(variableList);
1748:
1749: // 4> Get LocalVarTable ref and add the entry
1750: LocalVariableTable localVarTable = LocalVariableTable
1751: .getInstance();
1752: localVarTable.addEntry(methodName.concat(
1753: minfo.getStringifiedParameters()).concat(
1754: "" + minfo.isConstructor()), localStructure);
1755:
1756: minfo.setStructure(localStructure);
1757:
1758: }
1759: if (attrType.equals("LineNumberTable")) {
1760: int attr_len = dis.readInt(); // Attribute Length
1761: int lineNumTableLen = dis.readUnsignedShort(); // Line Number
1762: // table length
1763: /*
1764: * byte[] info = new byte[lineNumTableLen];
1765: * dis.read(info,0,lineNumTableLen);
1766: */// line number table
1767: // info
1768: for (int count = 0; count < lineNumTableLen; count++) {
1769: int start_pc = dis.readUnsignedShort();
1770: int line_num = dis.readUnsignedShort();
1771:
1772: // TODO if the above logic is correct then need to store
1773: // each entry
1774: // as a line number table info
1775: }
1776: }
1777: }
1778: }
1779:
1780: public void populateReflection(Hashtable table) {
1781: JavaClass clazz = new JavaClass(className);
1782: clazz.setCd(this );
1783: table.put(className, clazz);
1784: ConsoleLauncher.setClazzObjects(table);
1785: ConsoleLauncher.setClazzRef(clazz);
1786: clazz.setSuperClassName(super ClassName);
1787: clazz.setAccessSpecifiers(accessSpecifiers);
1788: clazz.setInterfacesImplemented(this .interfacesImplemented);
1789: for (int kk = 0; kk < allFields.length; kk++) {
1790: FieldMember field = new FieldMember();
1791: FieldInfo finfo = allFields[kk];
1792: field.setName(finfo.getFieldName());
1793: if (!finfo.isArray()) {
1794: field.setDataType((java.lang.String) finfo
1795: .getFieldType().get(0));
1796: field.setAccessSpecifiers(finfo.getAccessSpecifiers());
1797: } else {
1798: field.setDataType((java.lang.String) finfo
1799: .getFieldType().get(0));
1800: field.setDimension(finfo.getDimension());
1801: }
1802: field.setFieldValue(finfo.getObj());
1803: clazz.setField(field);
1804: }
1805: ;
1806: for (int kk = 0; kk < allMethods.length; kk++) {
1807: MethodInfo minfo = allMethods[kk];
1808: if (minfo != null) {
1809: if (minfo.isConstructor()) {
1810: ConstructorMember cmember = new ConstructorMember(
1811: className);
1812: cmember.setExceptionsTypes(minfo.getExceptions());
1813: cmember
1814: .setDeclaringClass(minfo
1815: .getBelongsToClass());
1816: cmember.setParams(minfo.getParameters());
1817: cmember.setCode(minfo.getCode());
1818: cmember.setAccessSpecifier(minfo
1819: .getAccessSpecifiers());
1820: clazz.setConstructor(cmember);
1821: cmember.setExceptionTableList(minfo
1822: .getAllExceptionTables());
1823: cmember.setAllTriesForMethod(minfo
1824: .getAllTryBlocksForMethod());
1825: cmember.setCreatedTableList(minfo
1826: .getCreatedTableList());
1827: cmember.setAllswitches(minfo
1828: .getAllSwitchBlksForMethod());
1829: cmember.setSynchronizedTableEntries(minfo
1830: .getSynchronizedTables());
1831: cmember
1832: .setBehaviourLoops(minfo
1833: .getBehaviourLoops());
1834: cmember.setMethodLocalVariables(minfo
1835: .getStructure());
1836: cmember.setInstrStartPos(minfo.getInststartpos());
1837: cmember.setShortCutAnalyser(minfo
1838: .getShortCutAanalyser());
1839: methodLookUp.put(minfo.getKey(), cmember);
1840: } else {
1841: MethodMember mmember = new MethodMember();
1842:
1843: mmember.setMethodName(minfo.getMethodName());
1844: mmember.setExceptionTypes(minfo.getExceptions());
1845: mmember
1846: .setDeclaringClass(minfo
1847: .getBelongsToClass());
1848: mmember.setMethodParams(minfo.getParameters());
1849: if (minfo.getCode() != null)
1850: mmember.setCode(minfo.getCode());
1851: else // Called only for abstract Method
1852: {
1853: mmember.setCode(null);
1854: }
1855: mmember.setMethodAccessors(minfo
1856: .getAccessSpecifiers());
1857:
1858: java.lang.String[] methodSpecifiers = minfo
1859: .getAccessSpecifiers();
1860: for (int i = 0; i < methodSpecifiers.length; i++) {
1861: if (methodSpecifiers[i].equals("abstract")) {
1862: mmember.setAbstract(true);
1863: break;
1864: }
1865: }
1866:
1867: /*
1868: * if(minfo == null || minfo.getReturnType().length()==0) {
1869: * minfo.setReturnType("void"); }
1870: */
1871: mmember.setReturnType(minfo.getReturnType());
1872: clazz.setMethod(mmember);
1873: // clazz.setMethod(mmember);
1874: mmember.setExceptionTableList(minfo
1875: .getAllExceptionTables());
1876: mmember.setAllTriesForMethod(minfo
1877: .getAllTryBlocksForMethod());
1878: mmember.setCreatedTableList(minfo
1879: .getCreatedTableList());
1880: mmember.setAllswitches(minfo
1881: .getAllSwitchBlksForMethod());
1882: mmember.setSynchronizedTableEntries(minfo
1883: .getSynchronizedTables());
1884: mmember
1885: .setBehaviourLoops(minfo
1886: .getBehaviourLoops());
1887: mmember.setMethodLocalVariables(minfo
1888: .getStructure());
1889: mmember.setInstrStartPos(minfo.getInststartpos());
1890: mmember.setShortCutAnalyser(minfo
1891: .getShortCutAanalyser());
1892: // System.out.println(minfo.getKey()+"minfo.getKey()");
1893: methodLookUp.put(minfo.getKey(), mmember);
1894: }
1895: }
1896: }
1897: setMethodLookUp(methodLookUp);
1898: }
1899:
1900: public Hashtable getMethodLookUp() {
1901: return methodLookUp;
1902: }
1903:
1904: public void setMethodLookUp(Hashtable methodLookUp) {
1905: this .methodLookUp = methodLookUp;
1906: ConsoleLauncher.setMethodLookUp(methodLookUp);
1907: }
1908:
1909: private java.lang.String checkForCatchOrTryGuard(
1910: ExceptionTable table, ArrayList allexceptiontables) {
1911: int startOfGuardForPassedTable = table.getStartOfGuardRegion();
1912: java.lang.String guardType = "catch";
1913: // boolean catchIndeed=true;
1914: for (int counter = 0; counter < allexceptiontables.size(); counter++) {
1915:
1916: ExceptionTable currentTable = (ExceptionTable) allexceptiontables
1917: .get(counter);
1918: if (currentTable != table) {
1919: if (currentTable.getStartOfGuardRegion() == startOfGuardForPassedTable
1920: && (currentTable.getExceptionName().equals(
1921: "<any>") == false)) {
1922: guardType = "try";
1923: return guardType;
1924: }
1925: }
1926: }
1927: // Now check for catch
1928: if (guardType.equals("catch")) {
1929: for (int counter = 0; counter < allexceptiontables.size(); counter++) {
1930:
1931: ExceptionTable currentTable = (ExceptionTable) allexceptiontables
1932: .get(counter);
1933: if (currentTable != table) {
1934: if (currentTable.getStartOfHandlerForGuardRegion() == startOfGuardForPassedTable
1935: && (currentTable.getExceptionName().equals(
1936: "<any>") == false)) {
1937: guardType = "catch";
1938:
1939: break;
1940: } else {
1941: guardType = "";
1942: }
1943: }
1944: }
1945: }
1946:
1947: return guardType;
1948:
1949: }
1950:
1951: private int getInstruction(byte[] info, int pos) {
1952: if (pos < 0)
1953: return -1;
1954: if (isThisInstrStart(minfo.getInststartpos(), pos)) {
1955: int temp = info[pos];
1956: return temp;
1957: }
1958: return -1;
1959: }
1960:
1961: private boolean checkForJSR(byte[] info, int pos) // TODO check for jsr_w
1962: // later
1963: {
1964:
1965: int instruction = getInstruction(info, pos);
1966: if (instruction == JvmOpCodes.JSR) {
1967: return true;
1968: } else {
1969: return false;
1970: }
1971: }
1972:
1973: private int getJSRJumpOffset(byte[] info, int pos) {
1974: /*
1975: * int temp1=info[pos+1]; int temp2=info[pos+2]; int offset=temp1<<8|temp2;
1976: * return pos+offset;
1977: */
1978: int b1 = info[++pos];
1979: int b2 = info[++pos];
1980: int z;
1981: if (b1 < 0)
1982: b1 = (256 + b1);
1983: if (b2 < 0)
1984: b2 = (256 + b2);
1985:
1986: int indexInst = ((((b1 << 8) | b2)) + (pos - 2));
1987: if (indexInst > 65535)
1988: indexInst = indexInst - 65536;
1989: if (indexInst < 0)
1990: indexInst = 256 + indexInst;
1991: return indexInst;
1992: }
1993:
1994: private Integer getRetPos(Hashtable ht, int localIndex) {
1995:
1996: Integer pos = null;
1997: Iterator it = ht.entrySet().iterator();
1998: while (it.hasNext()) {
1999: Map.Entry entry = (Map.Entry) it.next();
2000: Integer retpos = (Integer) entry.getKey();
2001: Integer retIndex = (Integer) entry.getValue();
2002: if (retIndex.intValue() == localIndex) {
2003: pos = retpos;
2004: break;
2005: } else {
2006: continue;
2007: }
2008:
2009: }
2010:
2011: return pos;
2012:
2013: }
2014:
2015: private Hashtable getAllReturnsFromoffset(int jsrJumpOffet,
2016: byte[] code, MethodInfo minfo) {
2017: Hashtable table = new Hashtable();
2018: ArrayList starts = minfo.getInststartpos();
2019: for (int start = jsrJumpOffet; start < code.length; start++) {
2020: int jvmcode = getInstruction(code, start);
2021:
2022: if (jvmcode == JvmOpCodes.RET
2023: && isThisInstrStart(starts, start)) {
2024:
2025: int retPosInCode = start;
2026: int nextPos = start + 1;
2027: int retIndex = code[nextPos];
2028: table.put(new Integer(retPosInCode), new Integer(
2029: retIndex));
2030: break;
2031: }
2032: }
2033: return table;
2034: }
2035:
2036: private boolean isRetPresent(int jsrJumpOffet, byte code[]) {
2037: boolean present = false;
2038: for (int start = jsrJumpOffet; start < code.length; start++) {
2039: int jvmcode = getInstruction(code, start);
2040: if (jvmcode == JvmOpCodes.RET) {
2041: present = true;
2042: /*
2043: * int s=start+1; index=code[s]; retPosInCode=new
2044: * Integer(start);;
2045: */
2046: break;
2047: } else {
2048: /*
2049: * retPresent=new Boolean(false); retPosInCode=new Integer(-1);
2050: * index=-1;
2051: */
2052: present = false;
2053: }
2054: }
2055:
2056: return present;
2057:
2058: }
2059:
2060: private int findEndOfTry(ArrayList subList, MethodInfo minfo) {
2061: int endoftry = -1;
2062: if (subList.size() > 0) {
2063: int handlerPc = ((ExceptionTable) subList.get(0))
2064: .getStartOfHandlerForGuardRegion();
2065: int prevendOfGuard = ((ExceptionTable) subList.get(0))
2066: .getEndOfGuardRegion();
2067: for (int s = 1; s < subList.size(); s++) {
2068: if (subList.size() > 1) {
2069: int curendOfGuard = ((ExceptionTable) subList
2070: .get(s)).getEndOfGuardRegion();
2071: if (curendOfGuard > prevendOfGuard
2072: && curendOfGuard <= handlerPc) {
2073: prevendOfGuard = curendOfGuard;
2074: endoftry = prevendOfGuard;
2075: }
2076: } else {
2077: endoftry = prevendOfGuard;
2078: break;
2079: }
2080:
2081: }
2082:
2083: }
2084:
2085: // Check if new end of try is valid ...
2086: /** *--------- NOTE---------------------- ** */
2087: // Refresher: Basically the reason behind implementing this was that if
2088: // the first
2089: // block of this sublist results in having a new end of try BUT that
2090: // there is another
2091: // block with same start and end of guard as this one AND start of
2092: // handler for that
2093: // guard region is the same as the BIGGEST start of guard of a table in
2094: // the sublist
2095: // to which this table(first block mentioned earlier) then this new end
2096: // of try is
2097: // not valid
2098: /** *--------- End of Note -------------- ** */
2099:
2100: if (endoftry != -1) {
2101: ExceptionTable Table = minfo
2102: .getExceptionTableWithBiggestStartOfGuard(subList);
2103: int biggestStart = -1;
2104: int startOfGuard = -1;
2105: int endOfGuard = -1;
2106: if (Table != null) {
2107: biggestStart = Table.getStartOfGuardRegion();
2108: // Get ExceptionTable
2109: ExceptionTable firstTab = minfo
2110: .getExceptionTableForSmallestStartOfGuard(subList);
2111: startOfGuard = firstTab.getStartOfGuardRegion();
2112: endOfGuard = firstTab.getEndOfGuardRegion();
2113: ArrayList sameGuards = minfo
2114: .getTableListWithGuardsSpecified(startOfGuard,
2115: endOfGuard);
2116: if (sameGuards != null) {
2117: for (int s = 0; s < sameGuards.size(); s++) {
2118: ExceptionTable tb = (ExceptionTable) sameGuards
2119: .get(s);
2120: if (tb != firstTab) {
2121: if (tb.getStartOfHandlerForGuardRegion() == biggestStart) {
2122: endoftry = -1; // So Try block's endof try will
2123: // not be reset to new value
2124: // The new value was invalid
2125: break;
2126: }
2127: }
2128:
2129: }
2130: }
2131: }
2132:
2133: }
2134:
2135: return endoftry;
2136: }
2137:
2138: private void resetEndOfTries(ArrayList subList, ExceptionTable tab,
2139: MethodInfo minfo) {
2140:
2141: Iterator it = subList.iterator();
2142: ArrayList temp = new ArrayList();
2143: while (it.hasNext()) {
2144: ExceptionTable table = (ExceptionTable) it.next();
2145: if (table != tab) {
2146: table.setTypeOfGuardRegion(""); // Reset because there is no try
2147: // at position i =
2148: // table.getStartofGuardRegion()
2149: temp.add(table);
2150: }
2151: }
2152:
2153: // Now reset all those tables which have same start and end of guards to
2154: // the tables
2155: // which have been reset above
2156:
2157: if (temp.size() > 0) {
2158: ArrayList alltables = minfo.getAllExceptionTables();
2159: Iterator iterator = temp.iterator();
2160: while (iterator.hasNext()) {
2161: ExceptionTable t = (ExceptionTable) iterator.next();
2162: for (int s = 0; s < alltables.size(); s++) {
2163: ExceptionTable extab = (ExceptionTable) alltables
2164: .get(s);
2165: if (extab.getStartOfGuardRegion() == t
2166: .getStartOfGuardRegion()
2167: && extab.getEndOfGuardRegion() == t
2168: .getEndOfGuardRegion()) {
2169: extab.setTypeOfGuardRegion("");
2170: }
2171: }
2172: }
2173: }
2174:
2175: // Now reset the end of try to those exception tables which have the
2176: // same start and end of guard
2177: // as that of tab passed
2178: ArrayList allTables = minfo.getAllExceptionTables();
2179: for (int s = 0; s < allTables.size(); s++) {
2180: ExceptionTable extab = (ExceptionTable) allTables.get(s);
2181: if (extab.getStartPC() == tab.getStartPC()
2182: && extab.getEndPC() == tab.getEndPC()) {
2183: extab.setEndOfGuardRegion(tab.getEndOfGuardRegion());
2184: }
2185: }
2186: // System.out.println();
2187:
2188: }
2189:
2190: private java.lang.String pollForIfOrSwitch(int whereTostart,
2191: byte[] codeSrc, int inst, MethodInfo minfo) {
2192: java.lang.String str = "";
2193: int start = whereTostart;
2194: // Check For If First
2195: boolean endCheck = false;
2196: int currentInstruction = codeSrc[start];
2197: if (isThisInstrStart(minfo.getInststartpos(), start)) {
2198: switch (currentInstruction) {
2199: case JvmOpCodes.ARETURN:
2200: case JvmOpCodes.IRETURN:
2201: case JvmOpCodes.FRETURN:
2202: case JvmOpCodes.DRETURN:
2203: case JvmOpCodes.LRETURN:
2204: case JvmOpCodes.RETURN:
2205: case JvmOpCodes.ATHROW:
2206: endCheck = true;
2207: }
2208: }
2209: while (!endCheck) {
2210: if (isThisInstrStart(minfo.getInststartpos(), start)) {
2211: switch (currentInstruction) {
2212: case JvmOpCodes.IF_ACMPEQ:
2213: case JvmOpCodes.IF_ACMPNE:
2214: case JvmOpCodes.IF_ICMPEQ:
2215: case JvmOpCodes.IF_ICMPGE:
2216: case JvmOpCodes.IF_ICMPGT:
2217: case JvmOpCodes.IF_ICMPLE:
2218: case JvmOpCodes.IF_ICMPLT:
2219: case JvmOpCodes.IF_ICMPNE:
2220: case JvmOpCodes.IFEQ:
2221: case JvmOpCodes.IFGE:
2222: case JvmOpCodes.IFGT:
2223: case JvmOpCodes.IFLE:
2224: case JvmOpCodes.IFLT:
2225: case JvmOpCodes.IFNE:
2226: case JvmOpCodes.IFNONNULL:
2227: str = "if";
2228: break;
2229: default:
2230: str = "";
2231: }
2232: }
2233:
2234: if (str.length() > 0)
2235: break; // Just a check to ensure we break out of while loop
2236:
2237: // Check For switch // TODO Check for tableswitch also here
2238: if (isThisInstrStart(minfo.getInststartpos(), start)
2239: && (currentInstruction == JvmOpCodes.LOOKUPSWITCH || currentInstruction == JvmOpCodes.TABLESWITCH)) {
2240: str = "switch";
2241: break;
2242: }
2243: start = start + 1;
2244: if (start >= codeSrc.length)
2245: break; // Just a check to avoid exception
2246: currentInstruction = codeSrc[start];
2247: if (isThisInstrStart(minfo.getInststartpos(), start)) {
2248: switch (currentInstruction) {
2249: case JvmOpCodes.ARETURN:
2250: case JvmOpCodes.IRETURN:
2251: case JvmOpCodes.FRETURN:
2252: case JvmOpCodes.DRETURN:
2253: case JvmOpCodes.LRETURN:
2254: case JvmOpCodes.RETURN:
2255: case JvmOpCodes.ATHROW:
2256: endCheck = true;
2257: }
2258: }
2259:
2260: }
2261:
2262: return str;
2263: }
2264:
2265: private int getIFPOS(int whereTostart, byte[] codeSrc,
2266: MethodInfo minfo) {
2267: int ifpos = -1;
2268: int start = whereTostart;
2269:
2270: int currentInstruction = codeSrc[start];
2271: while (start < codeSrc.length) {
2272: if (isThisInstrStart(minfo.getInststartpos(), start)) {
2273: switch (currentInstruction) {
2274: case JvmOpCodes.IF_ACMPEQ:
2275: case JvmOpCodes.IF_ACMPNE:
2276: case JvmOpCodes.IF_ICMPEQ:
2277: case JvmOpCodes.IF_ICMPGE:
2278: case JvmOpCodes.IF_ICMPGT:
2279: case JvmOpCodes.IF_ICMPLE:
2280: case JvmOpCodes.IF_ICMPLT:
2281: case JvmOpCodes.IF_ICMPNE:
2282: case JvmOpCodes.IFEQ:
2283: case JvmOpCodes.IFGE:
2284: case JvmOpCodes.IFGT:
2285: case JvmOpCodes.IFLE:
2286: case JvmOpCodes.IFLT:
2287: case JvmOpCodes.IFNE:
2288: case JvmOpCodes.IFNONNULL:
2289: ifpos = start;
2290: break;
2291: default:
2292: ifpos = -1;
2293: }
2294: }
2295: if (ifpos != -1)
2296: break; // Just a check to ensure we break out of while loop
2297:
2298: start = start + 1;
2299: if (start >= codeSrc.length)
2300: break; // Just a check to avoid exception
2301: currentInstruction = codeSrc[start];
2302:
2303: }
2304:
2305: return ifpos;
2306: }
2307:
2308: private int getIfOffset(int ifpos, byte[] codeSrc) {
2309: /*
2310: * int ifoffset=-1; int start=ifpos; int byte1=codeSrc[start+1]; int
2311: * byte2=codeSrc[start+2]; int jumpOffset=(byte1 << 8)|byte2;
2312: * ifoffset=ifpos+jumpOffset; return ifoffset; // Changed from ifpos to
2313: * ifoffset: belurs
2314: */
2315:
2316: int b1 = codeSrc[++ifpos];
2317: int b2 = codeSrc[++ifpos];
2318: int z;
2319: if (b1 < 0)
2320: b1 = (256 + b1);
2321: if (b2 < 0)
2322: b2 = (256 + b2);
2323:
2324: int indexInst = ((((b1 << 8) | b2)) + (ifpos - 2));
2325: if (indexInst > 65535)
2326: indexInst = indexInst - 65536;
2327: if (indexInst < 0)
2328: indexInst = 256 + indexInst;
2329: return indexInst;
2330:
2331: }
2332:
2333: private int getSwitchStart(int whereTostart, byte[] codeSrc,
2334: MethodInfo minfo) {
2335: int switchpos = -1;
2336:
2337: int start = whereTostart;
2338: int currentInstruction = codeSrc[start];
2339: while (start < codeSrc.length) {
2340: if (isThisInstrStart(minfo.getInststartpos(), start)) {
2341: if (currentInstruction == JvmOpCodes.LOOKUPSWITCH
2342: || currentInstruction == JvmOpCodes.TABLESWITCH)// Handle
2343: // tableswitch
2344: // also
2345: // here
2346: {
2347: switchpos = start;
2348: break;
2349: }
2350: }
2351:
2352: start = start + 1;
2353: if (start >= codeSrc.length)
2354: break; // Just a check to avoid exception
2355: currentInstruction = codeSrc[start];
2356:
2357: }
2358:
2359: return switchpos;
2360:
2361: }
2362:
2363: private int geSwitchDefault(int switchStart, byte[] info) {
2364: int DeafaultValue = -1;
2365: int start = switchStart;
2366: int leave_bytes = (4 - (start % 4)) - 1;
2367: for (int indx = 0; indx < leave_bytes; indx++) {
2368: start++;
2369: }
2370: // Read Default
2371: int Default = getSwitchOffset(info, start, "");// info[++start] << 24)
2372: // | (info[++start] <<
2373: // 16) | (info[++start]
2374: // << 8) |info[++start];
2375: DeafaultValue = Default + start;
2376: return DeafaultValue;
2377: }
2378:
2379: private ArrayList removeAllDuplicateTries(ArrayList allTries) {
2380: ArrayList methodtries = new ArrayList();
2381: for (int i = 0; i < allTries.size(); i++) {
2382: TryBlock Try = (TryBlock) allTries.get(i);
2383: boolean add = false;
2384: if (i == 0)
2385: methodtries.add(Try);
2386: else {
2387: Iterator t = methodtries.iterator();
2388: while (t.hasNext()) {
2389: TryBlock tryBlk = (TryBlock) t.next();
2390: if (tryBlk.getStart() == Try.getStart()
2391: && tryBlk.getEnd() == Try.getEnd()) {
2392: tryBlk.setBiggestTableUsedToCreateTry(Try
2393: .getTableUsedToCreateTry());
2394: add = false;
2395: break;
2396: } else {
2397: add = true;
2398: }
2399:
2400: }
2401: if (add == true) {
2402: methodtries.add(Try);
2403: }
2404: }
2405: }
2406:
2407: return methodtries;
2408:
2409: }
2410:
2411: private ArrayList checkForInvalidEntry(ArrayList subList) {
2412:
2413: ArrayList temp = new ArrayList();
2414: for (int i = 0; i < subList.size(); i++) {
2415: ExceptionTable et = (ExceptionTable) subList.get(i);
2416: if (et.getStartOfGuardRegion() == et
2417: .getStartOfHandlerForGuardRegion()) {
2418:
2419: } else {
2420: temp.add(et);
2421: }
2422: }
2423: return temp;
2424: }
2425:
2426: private int findEndOfTryForCreatedTable(ArrayList subList,
2427: MethodInfo minfo) {
2428: int endoftry = -1;
2429: if (subList.size() > 0) {
2430: int handlerPc = ((ExceptionTable) subList.get(0))
2431: .getStartOfHandlerForGuardRegion();
2432: int prevendOfGuard = ((ExceptionTable) subList.get(0))
2433: .getEndOfGuardRegion();
2434: for (int s = 1; s < subList.size(); s++) {
2435: if (subList.size() > 1) {
2436: int curendOfGuard = ((ExceptionTable) subList
2437: .get(s)).getEndOfGuardRegion();
2438: if (curendOfGuard > prevendOfGuard
2439: && curendOfGuard <= handlerPc) {
2440: prevendOfGuard = curendOfGuard;
2441: endoftry = prevendOfGuard;
2442: }
2443: } else {
2444: endoftry = prevendOfGuard;
2445: break;
2446: }
2447:
2448: }
2449:
2450: }
2451:
2452: return endoftry;
2453: }
2454:
2455: private void linkAllExceptionTables(MethodInfo minfo) {
2456: ArrayList list = minfo.getAllTablesWhoseGuardsAreTries();
2457: list = removeUnwantedEntries(list);
2458: // Need to reset endPc values Here
2459: /**
2460: * * Example Case of Exception table 83 91 97 java/lang/RuntimeException
2461: * 83 94 112 <any> 97 109 112 <any> 112 117 112 <any> // For
2462: * Code...Refer Defect3Code
2463: *
2464: *
2465: */
2466: if (list != null)
2467: resetEndOfGaurdValues(list, minfo);
2468:
2469: // NOTE: the above 2 lines were commented on 16 oct by belurs
2470: // As it was responsible for messing up a try/catch/finally blocks of
2471: // code
2472: // Reference: File Defect6Code
2473:
2474: // TODO: Continuous thoruough testing of try/catch/finally
2475: // Need to revisit later and check whether to do away or alter logic
2476:
2477: // Conflict:
2478: /***********************************************************************
2479: * Need to reset for this case: From To Handler Class 0 18 24
2480: * java/lang/Exception 0 21 37 <any> 24 34 37 <any> 37 42 37 <any> 217
2481: * 245 251 java/lang/Throwable 217 248 272 <any> 251 269 272 <any> 272
2482: * 277 272 <any> 323 364 367 <any> 367 372 367 <any>
2483: *
2484: */
2485:
2486: // Resolution for conflict:
2487: /***********************************************************************
2488: * ROOT CAUSE: Finally was not correctly associated with its try. so a
2489: * new try was produced. However the original fix caused 2 finallys to
2490: * be produced at same point. So resolved conflict by checking if a
2491: * finally already existed for a table whose end of guard region was
2492: * being used to reset the end of guard for another table
2493: *
2494: *
2495: */
2496:
2497: ArrayList allTries = new ArrayList();
2498: if (list != null) {
2499: Iterator iterator = list.iterator();
2500: while (iterator.hasNext()) {
2501: ExceptionTable t = (ExceptionTable) iterator.next();
2502:
2503: TryBlock newTry = new TryBlock();
2504: allTries.add(newTry);
2505: int start = t.getStartOfGuardRegion();
2506: int end = t.getEndOfGuardRegion();
2507: boolean hasFinally = false;
2508: newTry.setStart(start);
2509: newTry.setEnd(end);
2510: newTry.setTableUsedToCreateTry(t);
2511: newTry.setBiggestTableUsedToCreateTry(t);
2512: ArrayList tableList = minfo.getTablesWithGuardRange(
2513: start, end);
2514: int numberOfCatches;
2515: if (tableList != null)
2516: numberOfCatches = minfo
2517: .getNumberOfCatchesForTry(tableList);
2518: else
2519: numberOfCatches = 0;
2520: newTry.setNumberOfCatchBlks(numberOfCatches);
2521: ArrayList sortedTableList = minfo
2522: .sortTableListByStartOfHanlder(tableList);
2523: hasFinally = minfo.doesTryHaveFinally(sortedTableList);
2524: newTry.setHasFinallyBlk(hasFinally);
2525: // Form The Catch blocks Here
2526: // Case 1: Finally is present
2527: if (hasFinally) {
2528: int s;
2529: for (s = 0; s < (sortedTableList.size() - 1); s++) {
2530: ExceptionTable et = (ExceptionTable) sortedTableList
2531: .get(s);
2532: int startOfHandler = et
2533: .getStartOfHandlerForGuardRegion();
2534: ExceptionTable temp = minfo
2535: .getCatchBlk(startOfHandler);
2536: CatchBlock Catch;
2537: if (temp != null) {
2538:
2539: Catch = new CatchBlock();
2540: Catch.setMyStart(et
2541: .getStartOfHandlerForGuardRegion());// temp.getStartOfGuardRegion());
2542: ExceptionTable next = (ExceptionTable) sortedTableList
2543: .get(s + 1);
2544: int y1 = temp.getEndOfGuardRegion();
2545: int y2 = next
2546: .getStartOfHandlerForGuardRegion();
2547: int e = (y1 < y2) ? y1 : y2;
2548: Catch.setEnd(e);//
2549: // Above : changed from next to temp
2550: Catch.setAssociatedTry(newTry);
2551: newTry.addCatchBlk(Catch);
2552: newTry.setHasCatchBlk(true);
2553: if (temp.getEndOfGuardRegion() > temp
2554: .getStartOfHandlerForGuardRegion()) {
2555: // temp.setEndOfGuardRegion(next.getStartOfHandlerForGuardRegion());
2556: Catch
2557: .setEnd(next
2558: .getStartOfHandlerForGuardRegion());
2559: }
2560: } else {
2561: Catch = new CatchBlock();
2562: Catch.setMyStart(et
2563: .getStartOfHandlerForGuardRegion());
2564: ExceptionTable next = (ExceptionTable) sortedTableList
2565: .get(s + 1);
2566: Catch.setEnd(next
2567: .getStartOfHandlerForGuardRegion());
2568: Catch.setAssociatedTry(newTry);
2569: newTry.addCatchBlk(Catch);
2570: newTry.setHasCatchBlk(true);
2571:
2572: // To Fix The Bug when a catch is not ending
2573: // properly
2574: // when temp is null
2575:
2576: ExceptionTable tb = getTableWhoseHandlerIsFinallyForThisTry(
2577: start,
2578: minfo
2579: .getAllTablesWhoseGuardsAreTries());
2580: if (tb != null) {
2581: int endg = tb.getEndOfGuardRegion();
2582: if (endg != -1
2583: && endg > Catch.getStart()
2584: && endg < Catch.getEnd()) {
2585: Catch.setEnd(endg);
2586: }
2587: }
2588:
2589: }
2590: // temp.setEndOfHandlerForGuardRegion(next.getStartOfHandlerForGuardRegion());
2591: // // uncommented TEst case TryTest_6.java
2592:
2593: if (et.getEndOfHandlerForGuardRegion() == -1)
2594: et.setEndOfHandlerForGuardRegion(Catch
2595: .getEnd());
2596: int z = -1;
2597: // }
2598: }
2599:
2600: // Need to Handle finally block Here
2601: FinallyBlock Finally = new FinallyBlock();
2602: Finally.setAssociatedTry(newTry);
2603: ExceptionTable et = (ExceptionTable) sortedTableList
2604: .get(s);
2605: Finally.setStart(et
2606: .getStartOfHandlerForGuardRegion());
2607: Finally.setEnd(et.getEndOfHandlerForGuardRegion());
2608: newTry.setFinallyBlock(Finally);
2609: } else {
2610: int s;
2611: for (s = 0; s < (sortedTableList.size() - 1); s++) {
2612: ExceptionTable et = (ExceptionTable) sortedTableList
2613: .get(s);
2614: int startOfHandler = et
2615: .getStartOfHandlerForGuardRegion();
2616: ExceptionTable next = (ExceptionTable) sortedTableList
2617: .get(s + 1);
2618: CatchBlock Catch = new CatchBlock();
2619: Catch.setMyStart(startOfHandler);
2620: Catch.setEnd(next
2621: .getStartOfHandlerForGuardRegion());
2622: Catch.setAssociatedTry(newTry);
2623: newTry.addCatchBlk(Catch);
2624: newTry.setHasCatchBlk(true);
2625: et.setEndOfHandlerForGuardRegion(next
2626: .getStartOfHandlerForGuardRegion());
2627:
2628: }
2629: // Need to Handle Last Catch Here
2630: // Refer to tryCatchFinally.txt notes
2631: ExceptionTable et = (ExceptionTable) sortedTableList
2632: .get(s);
2633: int CatchStart = -1;
2634: int startOfCatch = et
2635: .getStartOfHandlerForGuardRegion();
2636: byte codeSrc[] = minfo.getCode();
2637: int jvmInst = codeSrc[startOfCatch - 3];
2638: boolean gotoPresent = false;
2639:
2640: if (jvmInst == JvmOpCodes.GOTO) {
2641: gotoPresent = true;
2642: CatchStart = startOfCatch;
2643: } else {
2644: jvmInst = codeSrc[startOfCatch - 1];
2645: gotoPresent = false;
2646: }
2647: // TODO:
2648: /**
2649: * Here additional Logic to be written to track any goto
2650: * before any of the catches belonging to this try . NOT
2651: * only this catch.
2652: */
2653: if (gotoPresent == false) {
2654:
2655: Iterator sortedTableListIT = sortedTableList
2656: .iterator();
2657: while (sortedTableListIT.hasNext()) {
2658: ExceptionTable table = (ExceptionTable) sortedTableListIT
2659: .next();
2660: if (table != et) {
2661: int catchStart = table
2662: .getStartOfHandlerForGuardRegion();
2663: int inst = codeSrc[catchStart - 3];
2664: if (inst == JvmOpCodes.GOTO) {
2665: gotoPresent = true;
2666: jvmInst = JvmOpCodes.GOTO;
2667: CatchStart = catchStart;
2668: break;
2669: } else {
2670: gotoPresent = false;
2671: }
2672: }
2673:
2674: }
2675:
2676: }
2677: int gotoOffset = -1;
2678: int returnType = -1;
2679:
2680: // Todo handle the case of goto_w
2681: if (gotoPresent == true) {
2682: /*
2683: * gotoOffset=(codeSrc[CatchStart-2]<<8)|codeSrc[CatchStart-1];
2684: * if(gotoOffset < 0)
2685: * gotoOffset=(codeSrc[CatchStart-2]+1)*256-Math.abs(codeSrc[CatchStart-1]);
2686: * gotoOffset+=CatchStart-3;
2687: */
2688: gotoOffset = getJumpAddress(codeSrc,
2689: (CatchStart - 3));
2690: if (gotoOffset >= codeSrc.length)
2691: gotoPresent = false;
2692: else {
2693: CatchBlock Catch = new CatchBlock();
2694: Catch.setAssociatedTry(newTry);
2695: boolean reset = verifyEndOfCatch(newTry,
2696: Catch, gotoOffset, CatchStart - 3,
2697: codeSrc, minfo);
2698: if (!reset)
2699: Catch.setEnd(gotoOffset);
2700: Catch.setMyStart(et
2701: .getStartOfHandlerForGuardRegion());
2702: newTry.addCatchBlk(Catch);
2703: newTry.setHasCatchBlk(true);
2704: et.setEndOfHandlerForGuardRegion(Catch
2705: .getEnd());
2706: // et.setEndOfGuardRegion(Try.getEnd()); //
2707: // Commented ....
2708: Catch
2709: .useMeForDeterminingTheEndOfLastCatch(false);
2710:
2711: // belurs:
2712: // Need to reset catch end if this cond is true
2713: // TODO; THIS piece of code is likely NOT to produce
2714: // the correct end of catch
2715: // Keep testing
2716:
2717: if (Catch.getEnd() < Catch.getStart()) {
2718:
2719: int st = Catch.getStart();
2720: byte c[] = minfo.getCode();
2721: st = st + 1;
2722: int newpos = -1;
2723: while (st < c.length) {
2724:
2725: if (isThisInstrStart(minfo
2726: .getInststartpos(), st)
2727: && c[st] == JvmOpCodes.GOTO
2728: && getJumpAddress(c, st) == Catch
2729: .getEnd()) {
2730: // newpos=st+3;
2731: Catch.setEnd(st);
2732: et
2733: .setEndOfHandlerForGuardRegion(Catch
2734: .getEnd());
2735: break;
2736: }
2737: boolean retpr = false;
2738: switch (c[st]) {
2739: case JvmOpCodes.IRETURN:
2740: case JvmOpCodes.LRETURN:
2741: case JvmOpCodes.FRETURN:
2742: case JvmOpCodes.DRETURN:
2743: case JvmOpCodes.ARETURN:
2744: case JvmOpCodes.RETURN:
2745: retpr = true;
2746: break;
2747: default:
2748: retpr = false;
2749: }
2750: if (retpr) {
2751: newpos = st;
2752: Catch.setEnd(newpos);
2753: et
2754: .setEndOfHandlerForGuardRegion(Catch
2755: .getEnd());
2756: break;
2757: }
2758: if (c[st] == JvmOpCodes.ATHROW) {
2759: newpos = st + 1;
2760: if (newpos >= c.length)
2761: newpos = st;
2762: Catch.setEnd(newpos);
2763: et
2764: .setEndOfHandlerForGuardRegion(Catch
2765: .getEnd());
2766: break;
2767: }
2768:
2769: st++;
2770: }
2771: }
2772:
2773: }
2774: // System.out.println();
2775:
2776: }
2777:
2778: if (gotoPresent == false) {
2779:
2780: boolean handledInIfOrSwitch = false;
2781: int whereTostart = startOfCatch;
2782: int ifpos = -1;
2783: jvmInst = codeSrc[startOfCatch - 1];
2784: int instruction = jvmInst;
2785: // Cases Covered:
2786: // If , switch
2787: // If covers all ifs, for , while, do--while
2788: // switch...As the name suggests only for
2789: // switch(lookupswitch,tableswitch)
2790:
2791: /*
2792: * switch(jvmInst) { case JvmOpCodes.ARETURN: case
2793: * JvmOpCodes.IRETURN: case JvmOpCodes.FRETURN: case
2794: * JvmOpCodes.DRETURN: case JvmOpCodes.LRETURN: case
2795: * JvmOpCodes.RETURN:
2796: */
2797:
2798: int currentInstruction = codeSrc[startOfCatch];
2799: boolean endCheck = false;
2800: switch (currentInstruction) {
2801: case JvmOpCodes.ARETURN:
2802: case JvmOpCodes.IRETURN:
2803: case JvmOpCodes.FRETURN:
2804: case JvmOpCodes.DRETURN:
2805: case JvmOpCodes.LRETURN:
2806: case JvmOpCodes.RETURN:
2807: case JvmOpCodes.ATHROW:
2808: endCheck = true;
2809: }
2810: boolean ok = true;
2811: while (!endCheck) {
2812:
2813: java.lang.String IF_Switch = pollForIfOrSwitch(
2814: whereTostart, codeSrc, jvmInst,
2815: minfo);
2816: int ifoffset = -1;
2817: int switchDefault = -1;
2818: int switchStart = -1;
2819: int newInstruction = -1;
2820: if (IF_Switch.equals("if")) // found an if
2821: {
2822: ifpos = getIFPOS(whereTostart, codeSrc,
2823: minfo);
2824: ifoffset = getIfOffset(ifpos, codeSrc);
2825: if (ifoffset > ifpos) // Not a do...while
2826: {
2827: newInstruction = codeSrc[ifoffset];
2828: currentInstruction = newInstruction;
2829: whereTostart = ifoffset;
2830:
2831: switch (currentInstruction) {
2832: case JvmOpCodes.ARETURN:
2833: case JvmOpCodes.IRETURN:
2834: case JvmOpCodes.FRETURN:
2835: case JvmOpCodes.DRETURN:
2836: case JvmOpCodes.LRETURN:
2837: case JvmOpCodes.RETURN:
2838: case JvmOpCodes.ATHROW:
2839: endCheck = true;
2840: }
2841: continue;
2842: } else // Got a do....while
2843: {
2844: newInstruction = codeSrc[ifoffset + 3];
2845: currentInstruction = newInstruction;
2846: whereTostart = ifoffset + 3;
2847: switch (currentInstruction) {
2848: case JvmOpCodes.ARETURN:
2849: case JvmOpCodes.IRETURN:
2850: case JvmOpCodes.FRETURN:
2851: case JvmOpCodes.DRETURN:
2852: case JvmOpCodes.LRETURN:
2853: case JvmOpCodes.RETURN:
2854: case JvmOpCodes.ATHROW:
2855: endCheck = true;
2856: }
2857: continue;
2858: }
2859: } else if (IF_Switch.equals("switch")) // found a
2860: // switch
2861: {
2862: switchStart = getSwitchStart(
2863: whereTostart, codeSrc, minfo);
2864: if (switchStart != -1) {
2865: switchDefault = geSwitchDefault(
2866: switchStart, codeSrc);
2867: if (switchDefault >= 0
2868: && switchDefault < codeSrc.length) {
2869: newInstruction = codeSrc[switchDefault];
2870: currentInstruction = newInstruction;
2871: whereTostart = switchDefault;
2872: switch (currentInstruction) {
2873: case JvmOpCodes.ARETURN:
2874: case JvmOpCodes.IRETURN:
2875: case JvmOpCodes.FRETURN:
2876: case JvmOpCodes.DRETURN:
2877: case JvmOpCodes.LRETURN:
2878: case JvmOpCodes.RETURN:
2879: case JvmOpCodes.ATHROW:
2880: endCheck = true;
2881: }
2882: }
2883: }
2884: } else {
2885: ok = false;
2886: break;
2887: }
2888:
2889: }
2890: if (ok == true) {
2891: CatchBlock newCatchBlk = new CatchBlock();
2892: newCatchBlk.setAssociatedTry(newTry);
2893: newCatchBlk.setEnd(whereTostart);
2894: newCatchBlk.setMyStart(et
2895: .getStartOfHandlerForGuardRegion());
2896: newTry.addCatchBlk(newCatchBlk);
2897: newTry.setHasCatchBlk(true);
2898: handledInIfOrSwitch = true;
2899: newCatchBlk
2900: .useMeForDeterminingTheEndOfLastCatch(true);
2901: }
2902:
2903: boolean done = false;
2904: if (handledInIfOrSwitch == false) {
2905: jvmInst = codeSrc[startOfCatch - 1];
2906: switch (jvmInst) {
2907: case JvmOpCodes.ARETURN:
2908: case JvmOpCodes.IRETURN:
2909: case JvmOpCodes.FRETURN:
2910: case JvmOpCodes.DRETURN:
2911: case JvmOpCodes.LRETURN:
2912: case JvmOpCodes.RETURN:
2913:
2914: currentInstruction = codeSrc[startOfCatch];
2915: int Start = startOfCatch;
2916: while (currentInstruction != instruction) {
2917: Start = Start + 1;
2918: if (Start < codeSrc.length) {
2919: currentInstruction = codeSrc[Start];
2920: if (currentInstruction == instruction) {
2921: /***********************************
2922: * BUG in end of catch.
2923: */
2924:
2925: CatchBlock newCatchBlk = new CatchBlock();
2926: newCatchBlk
2927: .setAssociatedTry(newTry);
2928: newCatchBlk.setEnd(Start);
2929: newCatchBlk
2930: .setMyStart(et
2931: .getStartOfHandlerForGuardRegion());
2932: newTry
2933: .addCatchBlk(newCatchBlk);
2934: newTry.setHasCatchBlk(true);
2935: newCatchBlk
2936: .useMeForDeterminingTheEndOfLastCatch(true);
2937: int newcatchend = checkToResetCatchEndWRTNextTry(
2938: minfo,
2939: Start,
2940: list,
2941: newTry.getStart(),
2942: et
2943: .getStartOfHandlerForGuardRegion());
2944: newCatchBlk
2945: .setEnd(newcatchend);
2946:
2947: done = true;
2948: break;
2949: }
2950: } else
2951: break;
2952:
2953: }
2954: break;
2955:
2956: default:
2957:
2958: }
2959: }
2960:
2961: // Add logic here
2962: int endpos = -1;
2963: if (!done && !handledInIfOrSwitch) {
2964:
2965: int i = startOfCatch + 1;
2966: boolean endfor = false;
2967: ArrayList starts = minfo.getInststartpos();
2968: for (; i < codeSrc.length; i++) {
2969: if (codeSrc[i] == JvmOpCodes.ATHROW
2970: && isThisInstrStart(starts, i)) {
2971: endpos = i;
2972: }
2973: switch (codeSrc[i]) {
2974: case JvmOpCodes.IRETURN:
2975: case JvmOpCodes.LRETURN:
2976: case JvmOpCodes.FRETURN:
2977: case JvmOpCodes.DRETURN:
2978: case JvmOpCodes.ARETURN:
2979: case JvmOpCodes.RETURN:
2980: if (isThisInstrStart(starts, i)) {
2981: endpos = i;
2982: endfor = true;
2983: break;
2984: }
2985:
2986: }
2987: if (endfor)
2988: break;
2989:
2990: }
2991:
2992: if (endpos != -1) {
2993:
2994: CatchBlock Catch = new CatchBlock();
2995: Catch.setAssociatedTry(newTry);
2996: Catch.setEnd(endpos);
2997: Catch
2998: .setMyStart(et
2999: .getStartOfHandlerForGuardRegion());
3000: newTry.addCatchBlk(Catch);
3001: newTry.setHasCatchBlk(true);
3002: handledInIfOrSwitch = true;
3003: Catch
3004: .useMeForDeterminingTheEndOfLastCatch(true);
3005: }
3006:
3007: }
3008:
3009: }
3010:
3011: }
3012: }
3013:
3014: }
3015:
3016: allTries = removeAllDuplicateTries(allTries);
3017: minfo.setAllTryBlocksForMethod(allTries);
3018: }
3019:
3020: private int checkToResetCatchEndWRTNextTry(MethodInfo minfo,
3021: int catchend, ArrayList list, int trystart, int catchstart) {
3022: List sorted = minfo
3023: .getSortedExceptionTablesForStartOfGuard(list);
3024: ExceptionTable next = null;
3025: for (int z = 0; z < sorted.size(); z++) {
3026: ExceptionTable t = (ExceptionTable) sorted.get(z);
3027: if (t.getStartOfGuardRegion() == trystart) {
3028: if ((z + 1) < sorted.size()) {
3029: next = (ExceptionTable) sorted.get(z + 1);
3030: break;
3031: }
3032: }
3033: }
3034: if (next != null) {
3035: int nexttrystart = next.getStartOfGuardRegion();
3036: if (catchend > nexttrystart) {
3037: catchend = catchstart;
3038: return catchend;
3039: }
3040: }
3041: return catchend;
3042: }
3043:
3044: private void linkCreatedExceptionTables(MethodInfo minfo) {
3045: ArrayList list = minfo.getAllCreatedTablesWhoseGuardsAreTries();
3046: ArrayList allCreatedTries = new ArrayList();
3047: if (list != null) {
3048: Iterator iterator = list.iterator();
3049: while (iterator.hasNext()) {
3050: ExceptionTable t = (ExceptionTable) iterator.next();
3051:
3052: TryBlock Try = new TryBlock();
3053: allCreatedTries.add(Try);
3054: int start = t.getStartOfGuardRegion();
3055: int end = t.getEndOfGuardRegion();
3056: boolean hasFinally = false;
3057: Try.setStart(start);
3058: Try.setEnd(end);
3059: ArrayList tableList = minfo
3060: .getCreatedTablesWithGuardRange(start, end);
3061: int numberOfCatches;
3062: if (tableList != null)
3063: numberOfCatches = minfo
3064: .getNumberOfCatchesForTry(tableList);
3065: else
3066: numberOfCatches = 0;
3067: Try.setNumberOfCatchBlks(numberOfCatches);
3068:
3069: }
3070: }
3071: }
3072:
3073: private boolean SkipThisFinallyHandler(ExceptionTable et1,
3074: ArrayList overList) {
3075: boolean skip = false;
3076: if (overList == null || overList.size() == 0) {
3077: skip = false;
3078: overList.add(et1);
3079: return skip;
3080: } else {
3081: for (int s = 0; s < overList.size(); s++) {
3082: ExceptionTable tab = (ExceptionTable) overList.get(s);
3083: if (tab.getStartOfHandlerForGuardRegion() == et1
3084: .getStartOfHandlerForGuardRegion()) {
3085: skip = true;
3086: break;
3087: } else {
3088: skip = false;
3089: continue;
3090: }
3091: }
3092: if (skip == false)
3093: overList.add(et1);
3094: return skip;
3095: }
3096:
3097: }
3098:
3099: public java.lang.String getSuperClassName() {
3100: return super ClassName;
3101: }
3102:
3103: public java.lang.String getClassName() {
3104: return className;
3105: }
3106:
3107: private void findEndOfDefaultForSwitch(Switch switchBlk,
3108: int defaultStart, byte[] code, MethodInfo minfo) {
3109:
3110: // Changed made [post 1.1]
3111: // Need to check whether default appears before the first case in switch
3112: Case fcase = switchBlk.getFirstCase();
3113:
3114: int fcasestart = -1;
3115: if (fcase != null) {
3116: fcasestart = fcase.getCaseStart();
3117: if (defaultStart < fcasestart) {
3118: switchBlk.setEndOfDefault(fcasestart);
3119: return;
3120: }
3121: }
3122: // End of change
3123:
3124: int s = defaultStart;
3125: int len = code.length;
3126: int endOfDefault = -1;
3127: forloop: for (; s < len; s++) {
3128: // System.out.println("s is "+s);
3129: int currentInstruction = getInstruction(code, s);
3130: /*
3131: * boolean IF=isInstructionIF(currentInstruction); if(IF) { int
3132: * ifPos=s; int jumpoffset=getJumpAddressForIf(ifPos,code); //TODO:
3133: * May lead to bugs if(jumpoffset > s) { s=jumpoffset; } else { //
3134: * s=s+1; } }
3135: */
3136: if (currentInstruction == JvmOpCodes.LOOKUPSWITCH) {
3137: int defaultjump = getDefaultAddressForSwitch(s, code);
3138: if (defaultjump > s) {
3139: s = defaultjump;
3140:
3141: } else {
3142: // s=s+1;
3143: }
3144: } else if (currentInstruction == JvmOpCodes.TABLESWITCH) {
3145: int defaultjump = getDefaultAddressForSwitch(s, code);
3146: if (defaultjump > s) {
3147: s = defaultjump;
3148:
3149: } else {
3150: // s=s+1;
3151: }
3152: }
3153: /*
3154: * else if(currentInstruction==JvmOpCodes.GOTO) {
3155: *
3156: * int gotoAddress=getGotoAddress(s,code,"normal");
3157: * if(gotoAddress!=-1 && gotoAddress > s) { s=gotoAddress; } // else
3158: * //s=s+1; }
3159: */
3160: // Detect here whether it is inside a try or start of Try or Catch
3161: // or Finally
3162: else if (minfo.getAllTryBlocksForMethod() != null
3163: && minfo.getAllTryBlocksForMethod().size() > 0) {
3164: ArrayList allTries = minfo.getAllTryBlocksForMethod();
3165: for (int st = 0; st < allTries.size(); st++) {
3166: TryBlock Try = (TryBlock) allTries.get(st);
3167: if (Try != null) {
3168: int tryStart = Try.getStart();
3169: if (tryStart == s) { // || (s > tryStart && s <=
3170: // Try.getEnd())) { [commented
3171: // for c:\array2.class]}
3172: FinallyBlock finallyBlk = Try
3173: .getFinallyBlock();
3174: if (finallyBlk != null) {
3175: int finallyEnd = finallyBlk.getEnd();
3176: s = finallyEnd; // what if finally end if not
3177: // set
3178: // TODO: check for -1 case
3179: break;
3180: } else {
3181: CatchBlock lastCatch = Try
3182: .getLastCatchBlock();
3183: int catchEnd = lastCatch.getEnd();
3184: s = catchEnd;
3185: break;
3186: }
3187: }
3188: if ((s == Try.getEnd())) {
3189: s = Try.getEnd();
3190: endOfDefault = s;
3191: break forloop;
3192: }
3193:
3194: }
3195:
3196: }
3197: }
3198:
3199: else if (currentInstruction == JvmOpCodes.ATHROW) {
3200: endOfDefault = s;
3201: break;
3202: } else if (checkForReturn(code, s, minfo))// currentInstruction==JvmOpCodes.RETURN)
3203: {
3204: endOfDefault = s;
3205: break;
3206: } else {
3207: // int dummy=s;
3208: // s=++s;
3209: }
3210:
3211: }
3212: // Just set the end to endofdefault here
3213: // if it is -1 then may be there is a gap in the
3214: // logic here and needs to be looked at
3215: // For Now Just setting to end of method
3216:
3217: // System.out.println();
3218: if (endOfDefault == -1) {
3219: switchBlk.setEndOfDefault(code.length - 1); // TODO: Test This
3220: // vigorously
3221: } else {
3222: switchBlk.setEndOfDefault(endOfDefault);
3223: }
3224:
3225: }
3226:
3227: private boolean isInstructionIF(int instruction) {
3228:
3229: switch (instruction) {
3230:
3231: case JvmOpCodes.IF_ACMPEQ:
3232: return true;
3233: case JvmOpCodes.IF_ACMPNE:
3234: return true;
3235: case JvmOpCodes.IF_ICMPEQ:
3236: return true;
3237: case JvmOpCodes.IF_ICMPGE:
3238: return true;
3239: case JvmOpCodes.IF_ICMPGT:
3240: return true;
3241: case JvmOpCodes.IF_ICMPLE:
3242: return true;
3243: case JvmOpCodes.IF_ICMPLT:
3244: return true;
3245: case JvmOpCodes.IF_ICMPNE:
3246: return true;
3247:
3248: case JvmOpCodes.IFEQ:
3249: return true;
3250: case JvmOpCodes.IFGE:
3251: return true;
3252: case JvmOpCodes.IFGT:
3253: return true;
3254: case JvmOpCodes.IFLE:
3255: return true;
3256: case JvmOpCodes.IFNE:
3257: return true;
3258: case JvmOpCodes.IFLT:
3259: return true;
3260: case JvmOpCodes.IFNULL:
3261: return true;
3262: case JvmOpCodes.IFNONNULL:
3263: return true;
3264: default:
3265: return false;
3266:
3267: }
3268:
3269: }
3270:
3271: private int getJumpAddressForIf(int startOfIf, byte[] code) {
3272: /*
3273: * int i1=code[(startOfIf+1)]; int i2=code[(startOfIf+2)]; return ((i1<<8)|i2)+startOfIf;
3274: */
3275: int b1 = code[++startOfIf];
3276: int b2 = code[++startOfIf];
3277: int z;
3278: if (b1 < 0)
3279: b1 = (256 + b1);
3280: if (b2 < 0)
3281: b2 = (256 + b2);
3282:
3283: int indexInst = ((((b1 << 8) | b2)) + (startOfIf - 2));
3284: if (indexInst > 65535)
3285: indexInst = indexInst - 65536;
3286: if (indexInst < 0)
3287: indexInst = 256 + indexInst;
3288: return indexInst;
3289:
3290: }
3291:
3292: private int getDefaultAddressForSwitch(int s, byte[] info) {
3293: int lookupSwitchPos = s;
3294: int leave_bytes = (4 - (s % 4)) - 1;
3295: for (int indx = 0; indx < leave_bytes; indx++) {
3296: s++;
3297: }
3298: // Read Default
3299: int Default = getSwitchOffset(info, s, ""); // (info[++s] << 24) |
3300: // (info[++s] << 16) |
3301: // (info[++s] << 8)
3302: // |info[++s];
3303: return Default + lookupSwitchPos;
3304: }
3305:
3306: private int getGotoAddress(int counter, byte[] info,
3307: java.lang.String type) {
3308:
3309: int b1 = info[++counter];
3310: int b2 = info[++counter];
3311: int z;
3312: if (b1 < 0)
3313: b1 = (256 + b1);
3314: if (b2 < 0)
3315: b2 = (256 + b2);
3316:
3317: int indexInst = ((((b1 << 8) | b2)) + (counter - 2));
3318: if (indexInst > 65535)
3319: indexInst = indexInst - 65536;
3320: if (indexInst < 0)
3321: indexInst = 256 + indexInst;
3322: return indexInst;
3323:
3324: }
3325:
3326: private ArrayList removeUnwantedEntries(ArrayList list) {
3327: ArrayList temp = new ArrayList();
3328: if (list != null) {
3329: for (int s = 0; s < list.size(); s++) {
3330: ExceptionTable table = (ExceptionTable) list.get(s);
3331: if (table.getStartPC() == table.getStartOfHandler()) {
3332: // Unwanted table
3333: } else
3334: temp.add(table);
3335: }
3336: return temp;
3337: }
3338: return null;
3339: }
3340:
3341: private void resetEndOfGaurdValues(ArrayList list, MethodInfo minfo) {
3342:
3343: for (int s = 0; s < list.size(); s++) {
3344: ExceptionTable curTable = (ExceptionTable) list.get(s);
3345: for (int s2 = 0; s2 < list.size(); s2++) {
3346: ExceptionTable table = (ExceptionTable) list.get(s2);
3347: if (table != curTable) {
3348: int startPC = table.getStartPC();
3349: int endPC = table.getEndPC();
3350: int handlerPC = table.getStartOfHandler();
3351:
3352: int curtablestartPC = curTable.getStartPC();
3353: int curtableendPC = curTable.getEndPC();
3354: int curtablehandlerPC = curTable
3355: .getStartOfHandler();
3356:
3357: // Check
3358: if (curtablestartPC == startPC) // Only if this is true
3359: {
3360:
3361: if (curtableendPC > endPC
3362: && curtableendPC <= handlerPC) // Need
3363: // to
3364: // Reset
3365: {
3366: // System.out.println();
3367: boolean skip = skipResetting(table, minfo);
3368: if (!skip)
3369: curTable.setEndOfGuardRegion(table
3370: .getEndOfGuardRegion());
3371: }
3372:
3373: }
3374:
3375: }
3376: }
3377:
3378: }
3379:
3380: }
3381:
3382: private int ReturnInst(MethodInfo minfo) {
3383: int inst = -1;
3384: java.lang.String retType = minfo.getReturnType().trim();
3385: if (retType.equals("void")) {
3386: inst = JvmOpCodes.RETURN;
3387: }
3388: if (retType.equals("int") || retType.equals("short")
3389: || retType.equals("byte") || retType.equals("char")
3390: || retType.equals("boolean")) {
3391: inst = JvmOpCodes.IRETURN;
3392: }
3393:
3394: if (retType.equals("float")) {
3395: inst = JvmOpCodes.FRETURN;
3396: }
3397: if (retType.equals("double")) {
3398: inst = JvmOpCodes.DRETURN;
3399: }
3400: if (minfo.isReturnTypeAsObjectType() == true) {
3401: inst = JvmOpCodes.ARETURN;
3402: }
3403:
3404: return inst;
3405:
3406: }
3407:
3408: private boolean isInstructionASwitch(int targetJvmInst) {
3409:
3410: if (targetJvmInst == JvmOpCodes.LOOKUPSWITCH
3411: || targetJvmInst == JvmOpCodes.TABLESWITCH)
3412: return true;
3413: else
3414: return false;
3415:
3416: }
3417:
3418: private int getDefaultStart(int i, byte[] info) {
3419: int lookupSwitchPos = i;
3420: int leave_bytes = (4 - (i % 4)) - 1;
3421: for (int indx = 0; indx < leave_bytes; indx++) {
3422: i++;
3423: }
3424: // Read Default
3425: int Default = getSwitchOffset(info, i, "");// (info[++i] << 24) |
3426: // (info[++i] << 16) |
3427: // (info[++i] << 8)
3428: // |info[++i];
3429: return Default + lookupSwitchPos;
3430: }
3431:
3432: private void findEndOfinallyForTable(ExceptionTable curtable,
3433: byte[] info, MethodInfo minfo) {
3434: if (curtable.getTypeOfHandlerForGuardRegion().equals(
3435: "FinallyBlock")) {
3436:
3437: if (curtable.getEndOfHandlerForGuardRegion() == -1) // Need to
3438: // Handle
3439: {
3440:
3441: int startOfFinally = curtable
3442: .getStartOfHandlerForGuardRegion();
3443: int jvmInstruction = getInstruction(info,
3444: startOfFinally);
3445: boolean isJsrPresent = false;
3446: int jsrJumpOffet = -1;
3447: // TODO check for astore_w
3448: if (jvmInstruction == JvmOpCodes.ASTORE_0
3449: || jvmInstruction == JvmOpCodes.ASTORE_1
3450: || jvmInstruction == JvmOpCodes.ASTORE_2
3451: || jvmInstruction == JvmOpCodes.ASTORE_3) {
3452: isJsrPresent = checkForJSR(info, startOfFinally + 1);
3453: if (isJsrPresent == true)
3454: jsrJumpOffet = getJSRJumpOffset(info,
3455: startOfFinally + 1);
3456: } else if (jvmInstruction == JvmOpCodes.ASTORE) {
3457: isJsrPresent = checkForJSR(info, startOfFinally + 2);
3458: if (isJsrPresent == true)
3459: jsrJumpOffet = getJSRJumpOffset(info,
3460: startOfFinally + 2);
3461: }
3462: if (isJsrPresent == false) {
3463: // get End of Finally
3464: int counter = startOfFinally;
3465: // Get aload instruction for astore got above
3466: // (jvmInstruction)
3467: int aloadInstrcution = -1;
3468: boolean simpleastore = true;
3469: if (jvmInstruction == JvmOpCodes.ASTORE_0)
3470: aloadInstrcution = JvmOpCodes.ALOAD_0;
3471: if (jvmInstruction == JvmOpCodes.ASTORE_1)
3472: aloadInstrcution = JvmOpCodes.ALOAD_1;
3473: if (jvmInstruction == JvmOpCodes.ASTORE_2)
3474: aloadInstrcution = JvmOpCodes.ALOAD_2;
3475: if (jvmInstruction == JvmOpCodes.ASTORE_3)
3476: aloadInstrcution = JvmOpCodes.ALOAD_3;
3477: if (jvmInstruction == JvmOpCodes.ASTORE) {
3478: aloadInstrcution = JvmOpCodes.ALOAD;
3479: simpleastore = false;
3480: }
3481: int start = startOfFinally;
3482: boolean done = false;
3483: for (;;) {
3484: if (done)
3485: break;
3486: if (start < info.length - 1) {
3487: if (simpleastore == true) {
3488: int tempInt = start + 1;
3489: int temp = -1;
3490: do {
3491: temp = info[tempInt];
3492: if (isThisInstrStart(minfo
3493: .getInststartpos(), tempInt)
3494: && temp == JvmOpCodes.ATHROW) {
3495: curtable
3496: .setEndOfHandlerForGuardRegion(tempInt);
3497: done = true;
3498: break;
3499: }
3500: boolean retpres = checkForReturn(
3501: info, tempInt, minfo);
3502: if (retpres) {
3503: curtable
3504: .setEndOfHandlerForGuardRegion(tempInt);
3505: done = true;
3506: break;
3507: }
3508: tempInt++;
3509:
3510: } while (tempInt < info.length);
3511: } else {
3512: int tempInt = start + 1 + 1;
3513: int temp = -1;
3514: do {
3515: temp = info[tempInt];
3516: if (isThisInstrStart(minfo
3517: .getInststartpos(), tempInt)
3518: && temp == JvmOpCodes.ATHROW) {
3519: curtable
3520: .setEndOfHandlerForGuardRegion(tempInt);
3521: done = true;
3522: break;
3523: }
3524: boolean retpres = checkForReturn(
3525: info, tempInt, minfo);
3526: if (retpres) {
3527: curtable
3528: .setEndOfHandlerForGuardRegion(tempInt);
3529: done = true;
3530: break;
3531: }
3532:
3533: tempInt++;
3534:
3535: } while (tempInt < info.length);
3536: }
3537: } else
3538: break;
3539: }
3540:
3541: int z = curtable.getEndOfHandlerForGuardRegion();
3542: if (z == -1) {
3543:
3544: java.lang.String retType = minfo
3545: .getReturnType();
3546: if (retType.equals("int")
3547: || retType.equals("byte")
3548: || retType.equals("short")
3549: || retType.equals("char")
3550: || retType.equals("boolean")) {
3551: int c = startOfFinally;
3552: while (c < info.length) {
3553: int val = info[c];
3554: if (val == JvmOpCodes.IRETURN) {
3555: curtable
3556: .setEndOfHandlerForGuardRegion(c);
3557: break;
3558: }
3559: c++;
3560: }
3561: }
3562: boolean isObjectType = minfo
3563: .isReturnTypeAsObjectType();
3564: if (isObjectType) {
3565: int c = startOfFinally;
3566: while (c < info.length) {
3567: int val = info[c];
3568: if (val == JvmOpCodes.ARETURN) {
3569: curtable
3570: .setEndOfHandlerForGuardRegion(c);
3571: break;
3572: }
3573: c++;
3574: }
3575: }
3576:
3577: }
3578: } else { // TODO: check for astore_wide
3579: int jvmCode = getInstruction(info, jsrJumpOffet);
3580: int localVarIndex = -1;
3581: if (jvmCode == JvmOpCodes.ASTORE)
3582: localVarIndex = info[jsrJumpOffet + 1];
3583: if (jvmCode == JvmOpCodes.ASTORE_0)
3584: localVarIndex = 0;
3585: if (jvmCode == JvmOpCodes.ASTORE_1)
3586: localVarIndex = 1;
3587: if (jvmCode == JvmOpCodes.ASTORE_2)
3588: localVarIndex = 2;
3589: if (jvmCode == JvmOpCodes.ASTORE_3)
3590: localVarIndex = 3;
3591:
3592: boolean retPresent = true;
3593: int retPosInCode = -1;
3594: Integer retPos = null;
3595:
3596: // retPresent=isRetPresent(jsrJumpOffet,info);
3597: // if(retPresent==true)
3598: // {
3599:
3600: Hashtable rets = getAllReturnsFromoffset(
3601: jsrJumpOffet, info, minfo);
3602: retPos = getRetPos(rets, localVarIndex);
3603:
3604: // }
3605: if (retPresent == true && retPos != null) {
3606: curtable.setEndOfHandlerForGuardRegion(retPos
3607: .intValue());
3608:
3609: } else {
3610: // No ret for this jsr of finally
3611: // TODO: No code added. ?
3612: int targetJvmInst = -1;
3613: int startReadingFrom = jsrJumpOffet;
3614: targetJvmInst = this .getInstruction(info,
3615: startReadingFrom);
3616: boolean endOffinallyFound = false;
3617: int FinallyEnd = -1;
3618: boolean hasBeenIncremented = false;
3619: boolean checkForReturnOrAthrow;
3620: boolean iffound;
3621: boolean switcchfound;
3622: boolean tryblkfound;
3623: boolean gotofound;
3624: for (;;) {
3625: iffound = false;
3626: switcchfound = false;
3627: tryblkfound = false;
3628: gotofound = false;
3629: checkForReturnOrAthrow = true;
3630: boolean IF = isInstructionIF(targetJvmInst);
3631: if (IF) // All blocks for which compiler generates
3632: // an if
3633: {
3634: int ifJump = getJumpAddressForIf(
3635: startReadingFrom, info);
3636: if (ifJump > startReadingFrom) {
3637: startReadingFrom = ifJump;
3638: hasBeenIncremented = true;
3639: checkForReturnOrAthrow = false;
3640: } else {
3641: hasBeenIncremented = false;
3642: checkForReturnOrAthrow = false;
3643: }
3644: iffound = true;
3645:
3646: } else if (!iffound
3647: && isInstructionASwitch(targetJvmInst)) // Look
3648: // for
3649: // a
3650: // switch
3651: // here
3652: {
3653: int defaultStart = getDefaultStart(
3654: startReadingFrom, info);
3655: startReadingFrom = defaultStart;
3656: hasBeenIncremented = true;
3657: checkForReturnOrAthrow = false;
3658: switcchfound = true;
3659:
3660: } else if (!switcchfound && !iffound
3661: && targetJvmInst == JvmOpCodes.GOTO) // Hanlde
3662: // Goto
3663: // //
3664: // Not
3665: // sure
3666: // whether
3667: // it
3668: // is
3669: // explicitly
3670: // required
3671: {
3672: int gotoJump = getGotoAddress(
3673: startReadingFrom, info,
3674: "normal");
3675: if (gotoJump > startReadingFrom) {
3676: startReadingFrom = gotoJump;
3677: hasBeenIncremented = true;
3678: checkForReturnOrAthrow = false;
3679: } else {
3680: hasBeenIncremented = false;
3681: checkForReturnOrAthrow = false;
3682: }
3683:
3684: gotofound = true;
3685:
3686: } // TODO: Handler goto_w later
3687: if (!switcchfound
3688: && !iffound
3689: && !gotofound
3690: && minfo.getAllTryBlocksForMethod() != null
3691: && minfo.getAllTryBlocksForMethod()
3692: .size() > 0) {
3693: // Handle embedded Try/catch/Finally Here
3694: // problem here ???
3695: // what if finally has inner finally and that
3696: // finally also has jsr and no ret ?
3697: ArrayList allTries = minfo
3698: .getAllTryBlocksForMethod();
3699: Iterator triesIT = allTries.iterator();
3700: while (triesIT.hasNext()) {
3701: TryBlock tryblk = (TryBlock) triesIT
3702: .next();
3703: if (tryblk != null) {
3704: int tryStart = tryblk
3705: .getStart();
3706: if (tryStart == startReadingFrom
3707: || (startReadingFrom > tryStart && startReadingFrom <= tryblk
3708: .getEnd())) {
3709: tryblkfound = true;
3710: if (tryblk.hasFinallyBlk() == true) {
3711: FinallyBlock finblk = tryblk
3712: .getFinallyBlock();
3713: if (finblk != null) // Shud not
3714: // be
3715: // necessary
3716: // . Just
3717: // double
3718: // check to
3719: // avoid
3720: // Runtime
3721: // exception
3722: { // Note such problems can be
3723: // logged so that such bugs
3724: // can be fixed when they
3725: // surface
3726: // TODO: look for such cases
3727: // and log it(even if log
3728: // level is 1).
3729:
3730: int finEnd = finblk
3731: .getEnd();
3732: if (finEnd != -1) {
3733: // Hopefully the end of
3734: // finally Ends Ok ....
3735: // There is no other
3736: // easy way to skip past
3737: // this finally
3738: // correctly
3739: // if finEnd is some
3740: // wrong value
3741: int temp = finEnd + 1;
3742: if (temp > info.length - 1) {
3743:
3744: startReadingFrom = finEnd;
3745: } else {
3746: startReadingFrom = temp;
3747: }
3748: hasBeenIncremented = true;
3749: checkForReturnOrAthrow = false;
3750: } else {
3751: // Here a recursive call
3752: // will have to be made
3753: // to get the end of
3754: // embedded finally
3755: // There is no other way
3756: // apart from recursive
3757: // call as the finally
3758: // blocks can
3759: // be embedded to any
3760: // level.
3761: /**
3762: * NOTE:
3763: */
3764: // Here a dummy
3765: // exception table is
3766: // created as the
3767: // signature of this
3768: // method demands such
3769: // so once the method
3770: // returns the end of
3771: // handler for this
3772: // dummy table will be
3773: // the
3774: // reqd value.
3775: /*
3776: * IMPORTANT: THIS DUMMY
3777: * EXCEPTION TABLE
3778: * SHOULD NOT BE ADDED
3779: * TO THE
3780: * allexceptiontable
3781: * list for this method.
3782: * It should be
3783: * nullified immediately
3784: */
3785: MethodInfo.ExceptionTable dummyExceptiontable = minfo.new ExceptionTable(
3786: -1, -1,
3787: -1, -1);
3788: dummyExceptiontable
3789: .setExceptionName("<any>");
3790: dummyExceptiontable
3791: .setEndOfHandlerForGuardRegion(-1);
3792: dummyExceptiontable
3793: .setStartOfHandlerForGuardRegion(finblk
3794: .getStart());
3795: this
3796: .findEndOfinallyForTable(
3797: dummyExceptiontable,
3798: info,
3799: minfo);
3800: int endOfFinally = dummyExceptiontable
3801: .getEndOfHandlerForGuardRegion();
3802: finblk
3803: .setEnd(endOfFinally);
3804: int temp = endOfFinally + 1;
3805: if (temp > info.length - 1)
3806: startReadingFrom = endOfFinally;
3807: else
3808: startReadingFrom = temp;
3809:
3810: // Important
3811: dummyExceptiontable = null;
3812: hasBeenIncremented = true;
3813: checkForReturnOrAthrow = false;
3814:
3815: break;
3816:
3817: }
3818:
3819: }
3820:
3821: } else {
3822: // Handle last catch here
3823: // Need to set
3824: // hasBeenIncremented properly
3825: CatchBlock catcblk = tryblk
3826: .getLastCatchBlock();
3827: if (catcblk != null) {
3828: int end = catcblk
3829: .getEnd();
3830: startReadingFrom = end;
3831: break;
3832: }
3833:
3834: }
3835:
3836: }
3837: }
3838:
3839: }
3840:
3841: }
3842: if (!switcchfound
3843: && !iffound
3844: && !gotofound
3845: && !tryblkfound
3846: && (targetJvmInst == ReturnInst(minfo))) {
3847: endOffinallyFound = true;
3848: FinallyEnd = startReadingFrom;
3849: // hasBeenIncremented=true;
3850: curtable
3851: .setEndOfHandlerForGuardRegion(FinallyEnd);
3852: // System.out.println();
3853: break;
3854:
3855: }
3856: if (targetJvmInst == JvmOpCodes.ATHROW) {
3857: endOffinallyFound = true;
3858: FinallyEnd = startReadingFrom;
3859: // hasBeenIncremented=true;
3860: curtable
3861: .setEndOfHandlerForGuardRegion(FinallyEnd);
3862: // System.out.println();
3863: break;
3864: }
3865: if (hasBeenIncremented == false)
3866: targetJvmInst = this .getInstruction(
3867: info, ++startReadingFrom);
3868: if (hasBeenIncremented) {
3869: targetJvmInst = this .getInstruction(
3870: info, startReadingFrom);
3871: hasBeenIncremented = false;
3872: }
3873:
3874: }
3875:
3876: }
3877:
3878: }
3879:
3880: } else {
3881: // Already Handled or set. Do Nothing
3882: }
3883:
3884: }
3885: }
3886:
3887: private boolean skipCurrentSwitch(Switch switchBlock,
3888: MethodInfo minfo) {
3889: boolean skip = false;
3890: boolean anyGotoPresent = false;
3891: byte[] code = minfo.getCode();
3892: int defStart = switchBlock.getDefaultStart();
3893: ArrayList allCases = switchBlock.getAllCases();
3894: for (int s = 0; s < allCases.size(); s++) {
3895: Switch.Case caseBlk = (Switch.Case) allCases.get(s);
3896: int caseEnd = caseBlk.getCaseEnd();
3897: int temp1 = caseEnd - 3;
3898: int temp2 = caseEnd - 2;
3899: int temp3 = caseEnd - 1;
3900: int inst = -1;
3901: if (temp1 >= 0 && temp1 < code.length
3902: && isThisInstrStart(minfo.getInststartpos(), temp1)) {
3903: inst = code[temp1];
3904: }
3905: if (inst == JvmOpCodes.GOTO) // TODO: Handle goto_w later
3906: {
3907: anyGotoPresent = true;
3908: int offset1 = code[temp2];
3909: int offset2 = code[temp3];
3910: if (offset1 < 0)
3911: offset1 = (256 + offset1);
3912: if (offset2 < 0)
3913: offset2 = (256 + offset2);
3914: int offset = (offset1 << 8) | offset2;
3915: offset += temp1;
3916: if (offset > 65535)
3917: offset = offset - 65536;
3918: if (offset < 0)
3919: offset = 256 + offset;
3920: if (offset == defStart) {
3921: skip = true;
3922: break;
3923: }
3924:
3925: }
3926: }
3927: if (!skip) {
3928: ArrayList loops = minfo.getBehaviourLoops();
3929: for (int i = 0; i < loops.size(); i++) {
3930: Loop l = (Loop) loops.get(i);
3931: if (l.getEndIndex() == defStart) {
3932: if (l.getStartIndex() < switchBlock
3933: .getStartOfSwitch()) {
3934: skip = true;
3935: break;
3936: }
3937: }
3938: }
3939:
3940: }
3941:
3942: // if(anyGotoPresent==false) // For the moment.
3943: // skip=true; // TODO: Figure out if there is more efficient way to
3944: // solve the problem
3945: // Problem wil arise if default is also returning something
3946: // Probable solution: look at commonly used ways of writing
3947: // switch blocks and figure out
3948: return skip;
3949:
3950: }
3951:
3952: private void setFallThruForCases(Switch switchBlock, byte[] code) {
3953: ArrayList allCases = switchBlock.getAllCases();
3954: for (int s = 0; s < allCases.size(); s++) {
3955: Switch.Case caseblk = (Switch.Case) allCases.get(s);
3956: int caseEnd = caseblk.getCaseEnd();
3957:
3958: int inst = code[caseEnd - 1];
3959: // Check for athrow
3960: if (inst == JvmOpCodes.ATHROW) {
3961: caseblk.setFallsThru(false);
3962: caseblk.setGotoAsEndForCase(false);
3963: continue;
3964: }
3965: switch (inst) {
3966: case JvmOpCodes.ARETURN:
3967: case JvmOpCodes.IRETURN:
3968: case JvmOpCodes.FRETURN:
3969: case JvmOpCodes.LRETURN:
3970: case JvmOpCodes.DRETURN:
3971: case JvmOpCodes.RETURN: {
3972: caseblk.setGotoAsEndForCase(false);
3973: caseblk.setFallsThru(false);
3974: continue;
3975: }
3976:
3977: }
3978:
3979: inst = code[caseEnd - 3];
3980: int gotoj = getJumpAddress(code, caseEnd - 3);
3981: if (inst == JvmOpCodes.GOTO && gotoj > caseEnd) // TODO: check for
3982: // goto_w;
3983: {
3984: caseblk.setFallsThru(false);
3985: caseblk.setGotoAsEndForCase(true);
3986: }
3987:
3988: }
3989:
3990: }
3991:
3992: private void updateEndOfFinallyForFinallyBlocks(
3993: ExceptionTable curtable, ArrayList tries) {
3994:
3995: for (int i = 0; i < tries.size(); i++) {
3996: TryBlock tryblk = (TryBlock) tries.get(i);
3997: if (tryblk.hasFinallyBlk()) {
3998: FinallyBlock fin = tryblk.getFinallyBlock();
3999: // TODO:should not have to check this actually...Can remove when
4000: // testing is done
4001: if (fin != null) {
4002: int end = fin.getEnd();
4003: if (end == -1) {
4004: int start = fin.getStart();
4005: int tableStart = curtable
4006: .getStartOfHandlerForGuardRegion();
4007: if (tableStart == start
4008: && curtable
4009: .getTypeOfHandlerForGuardRegion()
4010: .equals("FinallyBlock")) {
4011: fin.setEnd(curtable
4012: .getEndOfHandlerForGuardRegion());
4013: break;
4014: }
4015: }
4016: }
4017:
4018: }
4019:
4020: }
4021:
4022: }
4023:
4024: private boolean skipResetting(ExceptionTable table, MethodInfo minfo) {
4025: int start = table.getStartOfGuardRegion();
4026: int end = table.getEndOfGuardRegion();
4027: boolean skip = false;
4028:
4029: ArrayList neededTables = minfo.getTableListWithGuardsSpecified(
4030: start, end);
4031: for (int s = 0; s < neededTables.size(); s++) {
4032: ExceptionTable curtable = (ExceptionTable) neededTables
4033: .get(s);
4034: if (curtable.getExceptionName().equals("<any>")) {
4035: skip = true;
4036: }
4037:
4038: }
4039: return skip;
4040: }
4041:
4042: private ArrayList handleTablesForSynchronizedCode(
4043: ArrayList allexceptiontables, ArrayList synchronizedTables,
4044: byte[] info, MethodInfo minfo) {
4045: ArrayList updatedCompleteList = new ArrayList();
4046: for (int s = 0; s < allexceptiontables.size(); s++) {
4047: ExceptionTable table = (ExceptionTable) allexceptiontables
4048: .get(s);
4049: int startPC = table.getStartPC();
4050: // int endPC=table.getEndPC();
4051: int temp = startPC - 1;
4052: int jvmInst = -1;
4053: if (temp >= 0)
4054: jvmInst = info[temp];
4055: int endPC = table.getEndPC();
4056:
4057: boolean isSynchronzed = true;
4058: if (info[(endPC - 1)] == JvmOpCodes.MONITOREXIT) {
4059: isSynchronzed = true; // e:/synchTryTest.class
4060: }
4061: /**
4062: * For some fix, isSynchronzed was used also.. but again this is not
4063: * working in other cases reverting back...
4064: */
4065:
4066: /*******************************************************************
4067: * Fix for not setting a finally block as a synchronized block. This
4068: * fix is not complete. In the next release , inner synch blocks
4069: * need to be handled as well.
4070: */
4071: boolean mexitFound = false;
4072: int hpc = table.getStartOfHandler();
4073: for (int start = hpc - 1; start > table.getStartPC(); start--) {
4074: if (isThisInstrStart(minfo.getInststartpos(), start)) {
4075: if (info[start] == JvmOpCodes.MONITOREXIT) {
4076: mexitFound = true;
4077: break;
4078: }
4079: }
4080: }
4081:
4082: if (!mexitFound) {
4083: /**
4084: * Case when the synch block explicitly throws an exception
4085: */
4086: if (info[(hpc - 1)] == JvmOpCodes.ATHROW) {
4087: mexitFound = true;
4088: }
4089:
4090: }
4091: if (mexitFound
4092: && (jvmInst == JvmOpCodes.MONITORENTER)
4093: && (table.getExceptionName() == null || table
4094: .getExceptionName().equals("<any>"))) {
4095: synchronizedTables.add(table);
4096: table.setMonitorEnterPosInCode(temp);
4097: } else {
4098: updatedCompleteList.add(table);
4099: table.setMonitorEnterPosInCode(-1);
4100: }
4101: }
4102:
4103: return updatedCompleteList;
4104:
4105: }
4106:
4107: private int skipBytes(int inst, int counter, byte[] src) {
4108: int i = 0; // Defaults to 0
4109: HashMap map = ConsoleLauncher.getInstructionMap();
4110: Iterator it = map.entrySet().iterator();
4111: while (it.hasNext()) {
4112:
4113: Map.Entry entry = (Map.Entry) it.next();
4114: Integer key = (Integer) entry.getKey();
4115: Integer value = (Integer) entry.getValue();
4116: int jvmInst = key.intValue();
4117: int skipBytes = value.intValue();
4118: if (jvmInst == inst) {
4119: i = skipBytes;
4120: break;
4121: }
4122:
4123: }
4124: return i;
4125: }
4126:
4127: private boolean verifyEndOfCatch(TryBlock Try, CatchBlock Catch,
4128: int gotoOffset, int gotoStart, byte[] codeSrc,
4129: MethodInfo minfo) {
4130:
4131: int temp = gotoOffset;
4132: int jvmInstAtOffset = codeSrc[gotoOffset];
4133:
4134: if (jvmInstAtOffset == JvmOpCodes.JSR) // TOOD: handle jsr_w later
4135: {
4136: /*
4137: * int offset1=codeSrc[++temp]; int offset2=codeSrc[++temp]; int
4138: * jsroffset = ((offset1 << 8) | offset2); if(jsroffset < 0) {
4139: * jsroffset=(offset1+1)*256-Math.abs(offset2); }
4140: * jsroffset+=(temp-2);
4141: */
4142: Try.setHasFinallyBlk(true); // [Note:] belurs
4143: // Try.setEnd(gotoStart); // Commented This line as it was picking
4144: // the last catch as reference.
4145:
4146: // ArrayList list=minfo.getTablesWithGuardStart(Try.getStart());
4147: // TestCase TryCatch_6.java
4148: ArrayList list = minfo.getTablesWithGuardRange(Try
4149: .getStart(), Try.getEnd());
4150: boolean finallyFound = false;
4151: int finallyStart = -1;
4152: for (int s = 0; list != null && s < list.size(); s++) {
4153: ExceptionTable table = (ExceptionTable) list.get(s);
4154: if (table.getExceptionName().equals("<any>")) {
4155: finallyStart = table
4156: .getStartOfHandlerForGuardRegion();
4157: table.setEndOfGuardRegion(Try.getEnd());
4158: finallyFound = true;
4159: break;
4160: }
4161: }
4162: if (finallyFound) {
4163: FinallyBlock Finally = new FinallyBlock();
4164: Finally.setAssociatedTry(Try);
4165: Finally.setStart(finallyStart);
4166: Finally.setEnd(-1);
4167: Try.setFinallyBlock(Finally);
4168: Catch.setEnd(finallyStart);
4169: return true;
4170: } else
4171: return false;
4172:
4173: } else {
4174: ArrayList list = minfo.getTablesWithGuardRange(Try
4175: .getStart(), Try.getEnd());
4176: return false;
4177: }
4178:
4179: }
4180:
4181: public boolean IsGotoIndexInstructionIsALoad(int chkIndex,
4182: byte info[]) {
4183: // chkIndex is the index of the goto instruction.
4184: int val = info[chkIndex];
4185: switch (val) {
4186: case JvmOpCodes.AALOAD:
4187: return true;
4188:
4189: case JvmOpCodes.ALOAD:
4190: return true;
4191:
4192: case JvmOpCodes.ALOAD_0:
4193: return true;
4194:
4195: case JvmOpCodes.ALOAD_1:
4196: return true;
4197:
4198: case JvmOpCodes.ALOAD_2:
4199: return true;
4200:
4201: case JvmOpCodes.ALOAD_3:
4202: return true;
4203:
4204: case JvmOpCodes.BALOAD:
4205: return true;
4206:
4207: case JvmOpCodes.CALOAD:
4208: return true;
4209:
4210: case JvmOpCodes.DALOAD:
4211: return true;
4212:
4213: case JvmOpCodes.DLOAD:
4214: return true;
4215:
4216: case JvmOpCodes.DLOAD_0:
4217: return true;
4218:
4219: case JvmOpCodes.DLOAD_1:
4220: return true;
4221:
4222: case JvmOpCodes.DLOAD_2:
4223: return true;
4224:
4225: case JvmOpCodes.DLOAD_3:
4226: return true;
4227:
4228: case JvmOpCodes.FALOAD:
4229: return true;
4230:
4231: case JvmOpCodes.FLOAD:
4232: return true;
4233:
4234: case JvmOpCodes.FLOAD_0:
4235: return true;
4236:
4237: case JvmOpCodes.FLOAD_1:
4238: return true;
4239:
4240: case JvmOpCodes.FLOAD_2:
4241: return true;
4242:
4243: case JvmOpCodes.FLOAD_3:
4244: return true;
4245:
4246: case JvmOpCodes.IALOAD:
4247: return true;
4248:
4249: case JvmOpCodes.ILOAD:
4250: return true;
4251:
4252: case JvmOpCodes.ILOAD_0:
4253: return true;
4254:
4255: case JvmOpCodes.ILOAD_1:
4256: return true;
4257:
4258: case JvmOpCodes.ILOAD_2:
4259: return true;
4260:
4261: case JvmOpCodes.ILOAD_3:
4262: return true;
4263:
4264: case JvmOpCodes.LALOAD:
4265: case JvmOpCodes.LLOAD:
4266: case JvmOpCodes.LLOAD_0:
4267: case JvmOpCodes.LLOAD_1:
4268: case JvmOpCodes.LLOAD_2:
4269: case JvmOpCodes.LLOAD_3:
4270: return true;
4271:
4272: case JvmOpCodes.SALOAD:
4273: return true;
4274: }
4275:
4276: return false;
4277: }
4278:
4279: private int findIfInstructionForThisLoop(byte[] code, int start,
4280: java.lang.String name) {
4281: int s = -1;
4282: boolean ok = false;
4283:
4284: for (s = start; s < code.length; s++) {
4285:
4286: switch (code[s]) {
4287:
4288: case JvmOpCodes.IF_ACMPEQ:
4289: name = "IF_ACMPEQ";
4290: ok = true;
4291: break;
4292: case JvmOpCodes.IF_ACMPNE:
4293: name = "IF_ACMPNE";
4294: ok = true;
4295: break;
4296: case JvmOpCodes.IF_ICMPEQ:
4297: name = "IF_ICMPEQ";
4298: ok = true;
4299: break;
4300: case JvmOpCodes.IF_ICMPGE:
4301: name = "IFICMPGE";
4302: ok = true;
4303: break;
4304: case JvmOpCodes.IF_ICMPGT:
4305: name = "IF_ICMPGT";
4306: ok = true;
4307: break;
4308: case JvmOpCodes.IF_ICMPLE:
4309: name = "IF_ICMPLE";
4310: ok = true;
4311: break;
4312: case JvmOpCodes.IF_ICMPLT:
4313: name = "IF_ICMPLT";
4314: ok = true;
4315: break;
4316: case JvmOpCodes.IF_ICMPNE:
4317: name = "IF_ICMPNE";
4318: ok = true;
4319: break;
4320:
4321: case JvmOpCodes.IFEQ:
4322: name = "IFEQ";
4323: ok = true;
4324: break;
4325: case JvmOpCodes.IFGE:
4326: name = "IFGE";
4327: ok = true;
4328: break;
4329: case JvmOpCodes.IFGT:
4330: name = "IFGT";
4331: ok = true;
4332: break;
4333: case JvmOpCodes.IFLE:
4334: name = "IFLE";
4335: ok = true;
4336: break;
4337: case JvmOpCodes.IFNE:
4338: name = "IFNE";
4339: ok = true;
4340: break;
4341: case JvmOpCodes.IFLT:
4342: name = "IFLT";
4343: ok = true;
4344: break;
4345: case JvmOpCodes.IFNULL:
4346: name = "IFNULL";
4347: ok = true;
4348: break;
4349: case JvmOpCodes.IFNONNULL:
4350: name = "IFNONNULL";
4351: ok = true;
4352: break;
4353: default:
4354: name = "UNKNOWN";
4355:
4356: ok = false;
4357: break;
4358:
4359: }
4360: if (ok)
4361: break;
4362: }
4363: int reqdOffset = -1;
4364: if (s < code.length) {
4365: reqdOffset = getIfOffset(s, code);
4366: }
4367:
4368: return reqdOffset;
4369: }
4370:
4371: private boolean isGotoIndexInstructionAInvoke(int indexInst,
4372: byte[] info) {
4373: if (indexInst < 0)
4374: return false;
4375: switch (info[indexInst]) {
4376: case JvmOpCodes.INVOKEINTERFACE:
4377: case JvmOpCodes.INVOKESTATIC:
4378: case JvmOpCodes.INVOKEVIRTUAL:
4379: case JvmOpCodes.INVOKESPECIAL:
4380: return true; // TODO: should we include invokespecial ???
4381: default:
4382: return false;
4383: }
4384:
4385: }
4386:
4387: void populateGotos(byte[] info, MethodInfo minfo) {
4388: for (int s = 0; s < info.length; s++) {
4389: if (info[s] == JvmOpCodes.GOTO
4390: && isThisInstrStart(minfo.getInststartpos(), s)) // TODO
4391: // what
4392: // abt
4393: // goto_w
4394: // ????
4395: {
4396: int gotoStart = s;
4397: int gotoAddress = getGotoAddress(gotoStart, info,
4398: "normal");
4399: // TODO: As of Now hardcoding to normal !!!
4400: // Possible source of Bug...May have to revisit
4401: gotoStructure.put(new Integer(gotoStart), new Integer(
4402: gotoAddress));
4403: gotoStarts.add(new Integer(gotoStart));
4404: gotojumps.add(new Integer(gotoAddress));
4405:
4406: }
4407: }
4408: }
4409:
4410: // Utility methods for gotoStructure
4411:
4412: public int getMaxGotoStartGivenJump(int gotoAddress) {
4413: int end = -1;
4414: int pos = -1;
4415: for (int k = gotojumps.size() - 1; k >= 0; k--) {
4416: if (((Integer) gotojumps.get(k)).intValue() == gotoAddress) {
4417: pos = ((Integer) gotoStarts.get(k)).intValue();
4418: break;
4419: }
4420:
4421: }
4422:
4423: return pos;
4424: }
4425:
4426: private HashMap gotoStructure;
4427:
4428: private ArrayList gotoStarts;
4429:
4430: public ArrayList getGotojumps() {
4431: return gotojumps;
4432: }
4433:
4434: private ArrayList gotojumps;
4435:
4436: public ArrayList getGotoStarts() {
4437: return gotoStarts;
4438: }
4439:
4440: private boolean isStoreInst(int index, byte[] info, MethodInfo minfo) {
4441:
4442: if (index < 0)
4443: return false;
4444: boolean b = isThisInstrStart(minfo.getInststartpos(), index);
4445: if (!b)
4446: return false;
4447: switch (info[index]) {
4448: case JvmOpCodes.AASTORE:
4449: case JvmOpCodes.ASTORE:
4450: case JvmOpCodes.ASTORE_0:
4451: case JvmOpCodes.ASTORE_1:
4452: case JvmOpCodes.ASTORE_2:
4453: case JvmOpCodes.ASTORE_3:
4454:
4455: case JvmOpCodes.BASTORE:
4456: case JvmOpCodes.CASTORE:
4457: case JvmOpCodes.DASTORE:
4458: case JvmOpCodes.DSTORE:
4459: case JvmOpCodes.DSTORE_0:
4460: case JvmOpCodes.DSTORE_1:
4461: case JvmOpCodes.DSTORE_2:
4462: case JvmOpCodes.DSTORE_3:
4463: case JvmOpCodes.FASTORE:
4464: case JvmOpCodes.FSTORE:
4465: case JvmOpCodes.FSTORE_0:
4466: case JvmOpCodes.FSTORE_1:
4467: case JvmOpCodes.FSTORE_2:
4468: case JvmOpCodes.FSTORE_3:
4469: case JvmOpCodes.IASTORE:
4470: case JvmOpCodes.ISTORE:
4471: case JvmOpCodes.ISTORE_0:
4472: case JvmOpCodes.ISTORE_1:
4473: case JvmOpCodes.ISTORE_2:
4474: case JvmOpCodes.ISTORE_3:
4475: case JvmOpCodes.LASTORE:
4476: case JvmOpCodes.LSTORE:
4477: case JvmOpCodes.LSTORE_0:
4478: case JvmOpCodes.LSTORE_1:
4479: case JvmOpCodes.LSTORE_2:
4480: case JvmOpCodes.LSTORE_3:
4481: case JvmOpCodes.SASTORE:
4482: return true;
4483: default:
4484: return false;
4485:
4486: }
4487:
4488: }
4489:
4490: private boolean doesStoreFollowLoad(int s, byte[] info,
4491: MethodInfo minfo) {
4492:
4493: int temp = s + 1;
4494: int temp2 = s + 2;
4495: boolean b1 = isStoreInst(temp, info, minfo);
4496: boolean b2 = isStoreInst(temp2, info, minfo);
4497:
4498: switch (info[s]) {
4499: case JvmOpCodes.AALOAD:
4500: return b1;
4501:
4502: case JvmOpCodes.ALOAD:
4503: return b2;
4504:
4505: case JvmOpCodes.ALOAD_0:
4506: case JvmOpCodes.ALOAD_1:
4507: case JvmOpCodes.ALOAD_2:
4508: case JvmOpCodes.ALOAD_3:
4509: return b1;
4510: case JvmOpCodes.BALOAD:
4511: return b1;
4512:
4513: case JvmOpCodes.CALOAD:
4514: return b1;
4515:
4516: case JvmOpCodes.DALOAD:
4517: return b1;
4518:
4519: case JvmOpCodes.DLOAD:
4520: return b2;
4521:
4522: case JvmOpCodes.DLOAD_0:
4523: case JvmOpCodes.DLOAD_1:
4524: case JvmOpCodes.DLOAD_2:
4525: case JvmOpCodes.DLOAD_3:
4526: return b1;
4527: case JvmOpCodes.FALOAD:
4528: return b1;
4529:
4530: case JvmOpCodes.FLOAD:
4531: return b2;
4532:
4533: case JvmOpCodes.FLOAD_0:
4534: case JvmOpCodes.FLOAD_1:
4535: case JvmOpCodes.FLOAD_2:
4536: case JvmOpCodes.FLOAD_3:
4537: return b1;
4538:
4539: case JvmOpCodes.IALOAD:
4540: return b1;
4541:
4542: case JvmOpCodes.ILOAD:
4543: return b2;
4544:
4545: case JvmOpCodes.ILOAD_0:
4546: case JvmOpCodes.ILOAD_1:
4547: case JvmOpCodes.ILOAD_2:
4548: case JvmOpCodes.ILOAD_3:
4549: return b1;
4550:
4551: case JvmOpCodes.LALOAD:
4552: return b1;
4553:
4554: case JvmOpCodes.LLOAD:
4555: return b2;
4556:
4557: case JvmOpCodes.LLOAD_0:
4558: case JvmOpCodes.LLOAD_1:
4559: case JvmOpCodes.LLOAD_2:
4560: case JvmOpCodes.LLOAD_3:
4561: return b1;
4562:
4563: case JvmOpCodes.SALOAD:
4564: return b1;
4565: default:
4566: return false;
4567:
4568: }
4569:
4570: }
4571:
4572: private int getJumpAddress(byte[] info, int counter) {
4573:
4574: int b1 = info[++counter];
4575: int b2 = info[++counter];
4576: int z;
4577: if (b1 < 0)
4578: b1 = (256 + b1);
4579: if (b2 < 0)
4580: b2 = (256 + b2);
4581:
4582: int indexInst = ((((b1 << 8) | b2)) + (counter - 2));
4583: if (indexInst > 65535)
4584: indexInst = indexInst - 65536;
4585: if (indexInst < 0)
4586: indexInst = 256 + indexInst;
4587: return indexInst;
4588: }
4589:
4590: private boolean checkLoopRange(int s, int e, byte[] src,
4591: MethodInfo minfo) {
4592: boolean b = false;
4593: int ifcounter = 0; // sbelur:
4594: boolean ifpresent = false;
4595: for (int t = s; t < e; t++) // Removed equality test for e as it was
4596: // producing an infinite loop Test:
4597: // BigInteger.class Method addOne
4598: {
4599: if (isThisInstrStart(minfo.getInststartpos(), t)) {
4600: int inst = src[t];
4601: boolean isIf = isInstructionIF(inst);
4602:
4603: if (isIf == true) {
4604: ifpresent = true;
4605: ifcounter++;
4606: int ifjump = getJumpAddress(src, t);
4607: int pos = t + 3;
4608: if (pos < src.length
4609: && isThisInstrStart(
4610: minfo.getInststartpos(), pos)) {
4611: if (src[pos] == JvmOpCodes.GOTO) {
4612: int gotoj = getJumpAddress(src, pos);
4613: if (gotoj > e && src[e] == JvmOpCodes.GOTO) {
4614: // return true;
4615: }
4616: }
4617: }
4618:
4619: if (ifjump == s) {
4620: return true;
4621: }
4622:
4623: if ((ifjump - 3) >= 0
4624: && src[ifjump - 3] == JvmOpCodes.GOTO
4625: && isThisInstrStart(
4626: minfo.getInststartpos(),
4627: (ifjump - 3))) {
4628: int gj = getJumpAddress(src, (ifjump - 3));
4629: if (gj == s) {
4630: return true;
4631: }
4632: }
4633: if ((ifjump - 3) >= 0
4634: && src[ifjump - 3] == JvmOpCodes.GOTO
4635: && isThisInstrStart(
4636: minfo.getInststartpos(),
4637: (ifjump - 3))) {
4638: int gj = getJumpAddress(src, (ifjump - 3));
4639: if (checkForReturn(src, gj, minfo)) {
4640: return true;
4641: }
4642: }
4643:
4644: if (ifjump > e
4645: && (src[e] == JvmOpCodes.GOTO || isInstructionIF(src[e]))) {
4646: return true;
4647: } else {
4648: b = false;
4649: }
4650: }
4651:
4652: }
4653:
4654: }
4655:
4656: if (!ifpresent)
4657: return true;
4658: return b;
4659:
4660: }
4661:
4662: private ArrayList caseStartsLabels = null;
4663:
4664: private ArrayList caseLabelSorted = null;
4665:
4666: private void mapSwitchStartsWithLabels(int[] offsetValues,
4667: int[] labels) {
4668: caseStartsLabels = new ArrayList();
4669: caseLabelSorted = new ArrayList();
4670: if (offsetValues == null || offsetValues.length == 0)
4671: return;
4672: for (int s = 0; s < offsetValues.length; s++) {
4673: if (s > labels.length)
4674: break;
4675: int start = offsetValues[s];
4676: int label = labels[s];
4677: SwitchCaseHelper helper = new SwitchCaseHelper(start,
4678: label, false, s);
4679: caseStartsLabels.add(helper);
4680: }
4681: int copy[] = (int[]) offsetValues.clone();
4682: Arrays.sort(copy);
4683: int prev = copy[0];
4684: ArrayList temp = new ArrayList();
4685: ArrayList temp2 = new ArrayList();
4686: // temp.add(new Integer(prev));
4687:
4688: for (int h = 1; h < copy.length; h++) {
4689: if (copy[h] == prev) {
4690: } else {
4691: int[] lbls = getLabelsForOffset(prev);
4692: // temp.add(lbls);
4693: prev = copy[h];
4694: for (int m = 0; m < lbls.length; m++) {
4695: temp.add(new Integer(lbls[m]));
4696: }
4697: }
4698: }
4699: int[] lbls = getLabelsForOffset(prev);
4700: for (int m = 0; m < lbls.length; m++) {
4701: temp.add(new Integer(lbls[m]));
4702: }
4703: caseLabelSorted = temp;
4704:
4705: }
4706:
4707: private int[] getLabelsForOffset(int offset) {
4708: ArrayList temp = new ArrayList();
4709: for (int k = 0; k < caseStartsLabels.size(); k++) {
4710: SwitchCaseHelper helper = (SwitchCaseHelper) caseStartsLabels
4711: .get(k);
4712: if (helper.getCasestart() == offset) {
4713: temp.add(new Integer(helper.getCaselabel()));
4714: }
4715: }
4716: Integer in[] = (Integer[]) temp
4717: .toArray(new Integer[temp.size()]);
4718: int[] reqd = new int[in.length];
4719: for (int m = 0; m < in.length; m++) {
4720: reqd[m] = in[m].intValue();
4721: }
4722: return reqd;
4723: }
4724:
4725: // FIXME:
4726: private int[] getCaseEnd(int desiredPos, int curOffset,
4727: int[] offsetValues, int[] labels, int def, byte[] info,
4728: MethodInfo minfo) {
4729: int arr[] = new int[3];
4730: int offsetValCopy[] = (int[]) offsetValues.clone();
4731: Arrays.sort(offsetValCopy);
4732: for (int k = 0; k < offsetValCopy.length; k++) {
4733: int cur = offsetValCopy[k];
4734: if (cur == curOffset && (k == desiredPos)) {
4735: // int lbl=((Integer)caseStartsLabels.get(new
4736: // Integer(cur))).intValue();
4737: int lbl = getCaseLabel(cur);
4738: if (k < (offsetValCopy.length - 1)) {
4739: int next = k + 1;
4740: arr[0] = cur;
4741: arr[1] = lbl;
4742: int getnext = getNextDifferentCaseStart(
4743: offsetValCopy, cur);
4744: if (offsetValCopy[next] == getnext)
4745: arr[2] = offsetValCopy[next];
4746: else {
4747: if (getnext != -1)
4748: arr[2] = getnext;
4749: else
4750: arr[2] = offsetValCopy[next];
4751: }
4752: } else {
4753: if (def > cur) {
4754: arr[0] = cur;
4755: arr[1] = lbl;
4756: arr[2] = def;
4757: } else {
4758: int e = findEndOfLastCaseForSwitch(cur, info,
4759: minfo);
4760: arr[0] = cur;
4761: arr[1] = lbl;
4762: arr[2] = e;
4763:
4764: }
4765: }
4766: break;
4767: }
4768: }
4769:
4770: return arr;
4771: }
4772:
4773: private int getSwitchOffset(byte[] info, int counter,
4774: java.lang.String lbl) {
4775: int b1 = info[++counter];
4776: int b2 = info[++counter];
4777: int b3 = info[++counter];
4778: int b4 = info[++counter];
4779:
4780: if (b1 < 0)
4781: b1 = (256 + b1);
4782: if (b2 < 0)
4783: b2 = (256 + b2);
4784: if (b3 < 0)
4785: b3 = (256 + b3);
4786: if (b4 < 0)
4787: b4 = (256 + b4);
4788:
4789: int jmp = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
4790: if (jmp > 65535)
4791: jmp = jmp - 65536;
4792: if (lbl.equals("label"))
4793: return jmp;
4794: if (jmp < 0)
4795: jmp = 512 + jmp;
4796: return jmp;
4797: }
4798:
4799: // list---loops
4800: private int checkEndOFLastCatchWRTContainedLoops(CatchBlock Catch,
4801: ArrayList list) {
4802: int newend = -1;
4803: if (list == null || list.size() == 0)
4804: return newend;
4805: ArrayList possibleCaseEnds = new ArrayList();
4806: for (int s = 0; s < list.size(); s++) {
4807:
4808: Loop loop = (Loop) list.get(s);
4809: int lend = loop.getEndIndex();
4810: int lstart = loop.getStartIndex();
4811: int cstart = Catch.getStart();
4812: int cend = Catch.getEnd();
4813: if (lend > cstart && lend < cend) // Need to reset
4814: {
4815: // newend=lend;
4816: possibleCaseEnds.add(new Integer(lend));
4817: }
4818: }
4819:
4820: if (possibleCaseEnds.size() > 0) {
4821: Integer ints[] = (Integer[]) possibleCaseEnds
4822: .toArray(new Integer[possibleCaseEnds.size()]);
4823: Arrays.sort(ints);
4824: newend = ints[0].intValue();
4825:
4826: }
4827:
4828: return newend;
4829: }
4830:
4831: private int checkEndOfLastCatchWRTCaseBlks(CatchBlock last,
4832: ArrayList list) {
4833:
4834: int newend = -1;
4835: if (list == null || list.size() == 0)
4836: return newend;
4837: ArrayList possibleCaseEnds = new ArrayList();
4838: for (int s = 0; s < list.size(); s++) {
4839:
4840: Switch swblk = (Switch) list.get(s);
4841: ArrayList cases = swblk.getAllCases();
4842: for (int s1 = 0; s1 < cases.size(); s1++) {
4843:
4844: Switch.Case c = (Switch.Case) cases.get(s1);
4845: int cstart = c.getCaseStart();
4846: int cend = c.getCaseEnd();
4847: if (cend > last.getStart() && cend < last.getEnd()) {
4848: // last.setEnd(cend);
4849: possibleCaseEnds.add(new Integer(cend));
4850: }
4851: }
4852: }
4853: if (possibleCaseEnds.size() > 0) {
4854: Integer ints[] = (Integer[]) possibleCaseEnds
4855: .toArray(new Integer[possibleCaseEnds.size()]);
4856: Arrays.sort(ints);
4857: newend = ints[0].intValue();
4858:
4859: }
4860:
4861: return newend;
4862: }
4863:
4864: /**
4865: * [note:] belurs This method is used when
4866: *
4867: * 1> When compiled with -g to determine those variables that ae null in
4868: * structure by scanning any returns apart from normal return inst 2> When
4869: * compiled with -g:none to create some local variables(As of now only
4870: * iload_<n> because this is where ambiguity comes in. Anyway there is no
4871: * local variable created at this point with -g:none option. THIS FEATURE
4872: * WILL BE USED TO DISTINGUISH A BOOLEAN VARIABLE FROM INTEGER. BY DEFAULT
4873: * ALL istore_<n> will result in integer variables in decompiled code
4874: *
4875: * @param minfo
4876: */
4877:
4878: private void scanCodeForLocalVariables(MethodInfo minfo) {
4879: Hashtable storeNLoad_Map = new Hashtable();
4880: method_name_storeNLoad_Map.put(minfo.getMethodName().concat(
4881: minfo.getStringifiedParameters()), storeNLoad_Map);
4882:
4883: if (compiledWithMinusG) {
4884: LocalVariableStructure structure = minfo.getStructure();
4885: byte[] code = minfo.getCode();
4886: for (int s = 1; s < code.length; s++) {
4887: int t = code[s];
4888: if (isThisInstReturn(t)) {
4889: java.lang.StringBuffer loadpos = new java.lang.StringBuffer(
4890: "");
4891: int loadInstIndex = isPrevInstLoadInst((s - 1),
4892: code, loadpos, storeNLoad_Map, minfo); // Returns load
4893: // index if load
4894: // is present
4895: // else return
4896: // -1
4897: if (loadInstIndex != -1) {
4898: int pos = (s - 1);
4899: LocalVariable var = structure
4900: .getVariabelAtIndex(loadInstIndex,
4901: (s - 1));
4902:
4903: if (var == null) // Make another attempt
4904: {
4905: var = structure.getVariabelAtIndex(
4906: loadInstIndex, (s - 2));
4907: pos = (s - 2);
4908: }
4909: if (var == null) // Local variable has to be created
4910: {
4911: java.lang.String varName = "Var" + "_"
4912: + loadpos + "_" + loadInstIndex;
4913: java.lang.String rettype = minfo
4914: .getReturnType();
4915: LocalVariable newvar = new LocalVariable(
4916: minfo
4917: .getMethodName()
4918: .concat(
4919: minfo
4920: .getStringifiedParameters()),
4921: varName, loadInstIndex);
4922: newvar.setDataType(rettype);
4923: newvar.setPrimitive(true);
4924: newvar.setDeclarationGenerated(false);
4925: try {
4926: newvar
4927: .setLoadORStorePosUsedToCreateVraiable(Integer
4928: .parseInt(loadpos
4929: .toString()
4930: .trim()));
4931: } catch (NumberFormatException ne) {
4932: newvar
4933: .setLoadORStorePosUsedToCreateVraiable(99999);
4934: }
4935: newvar.setWasCreated(true);
4936: structure.addLocalVariable(newvar);
4937:
4938: }
4939: }
4940:
4941: }
4942: }
4943:
4944: } else {
4945: LocalVariableStructure struc = minfo.getStructure();
4946: byte[] code = minfo.getCode();
4947: for (int s = 0; s < code.length; s++) {
4948:
4949: /*
4950: * int ifpos=isThisNextIfZeroInst(code,s); if(ifpos!=-1) { int
4951: * loadOffset=isPrevInstILoad(ifpos,code); if(loadOffset!=-1) {
4952: * LocalVariable l=struc.getVariabelAtIndex(loadOffset);
4953: * if(l==null) { int pos=getLoadPosInCode(ifpos,code);
4954: * LocalVariable var=new LocalVariable();
4955: * var.setMethodName(minfo.getMethodName().concat(minfo.getStringifiedParameters()));
4956: * var.setIndexPos(loadOffset);
4957: * var.setVarName("Var"+"_"+pos+"_"+loadOffset);
4958: * var.setDataType("int"); // TODO : Fixme later
4959: * var.setPrimitive(true); var.setDeclarationGenerated(false);
4960: * var.setWasCreated(true); struc.addLocalVariable(var); } } }
4961: * else {
4962: */
4963: int t = code[s];
4964: if (isThisInstReturn(t)) {
4965:
4966: java.lang.StringBuffer loadpos = new java.lang.StringBuffer(
4967: "");
4968: int loadInstIndex = isPrevInstLoadInst((s - 1),
4969: code, loadpos, storeNLoad_Map, minfo); // Returns load
4970: // index if load
4971: // is present
4972: // else return
4973: // -1
4974: if (loadInstIndex != -1) {
4975: // int pos=new Integer(loadpos).intValue();
4976: LocalVariable var = struc
4977: .getVariabelAtIndex(loadInstIndex);
4978:
4979: if (var == null) // Local variable has to be created
4980: {
4981: java.lang.String varName = "Var" + "_"
4982: + loadpos.toString() + "_"
4983: + loadInstIndex;
4984: java.lang.String rettype = minfo
4985: .getReturnType();
4986: LocalVariable newvar = new LocalVariable(
4987: minfo
4988: .getMethodName()
4989: .concat(
4990: minfo
4991: .getStringifiedParameters()),
4992: varName, loadInstIndex);
4993: newvar.setDataType(rettype);
4994: newvar.setPrimitive(true);
4995: newvar.setDeclarationGenerated(false);
4996: struc.addLocalVariable(newvar);
4997: try {
4998: newvar
4999: .setLoadORStorePosUsedToCreateVraiable(Integer
5000: .parseInt(loadpos
5001: .toString()
5002: .trim()));
5003: } catch (NumberFormatException ne) {
5004: newvar
5005: .setLoadORStorePosUsedToCreateVraiable(99999);
5006: }
5007: newvar.setWasCreated(true);
5008: struc.addLocalVariable(newvar);
5009: }
5010: }
5011:
5012: }
5013: // }
5014:
5015: // Check all invokes here
5016: int invokeinst = code[s];
5017:
5018: if (isNextInstructionInvokeVirtual(invokeinst)
5019: || isNextInstructionInvokeStatic(invokeinst)
5020: || isNextInstructionInvokeInterface(invokeinst)
5021: || isNextInstructionInvokeSpecial(invokeinst)) {
5022: // processVarDataType(code,s,struc,minfo);
5023: }
5024:
5025: }
5026:
5027: }
5028:
5029: }
5030:
5031: private int getOffset(byte[] info, int counter) {
5032:
5033: int b1 = info[++counter];
5034: int b2 = info[++counter];
5035: int z;
5036: if (b1 < 0)
5037: b1 = (256 + b1);
5038: if (b2 < 0)
5039: b2 = (256 + b2);
5040:
5041: int indexInst = (((b1 << 8) | b2));
5042: if (indexInst > 65535)
5043: indexInst = indexInst - 65536;
5044: if (indexInst < 0)
5045: indexInst = 256 + indexInst;
5046: return indexInst;
5047: }
5048:
5049: /*
5050: * private void processVarDataType(byte[] code,int s,LocalVariableStructure
5051: * struc,MethodInfo minfo) { int classIndex=getOffset(code,s); MethodRef
5052: * mref = this.getMethodRefAtCPoolPosition(classIndex); java.lang.String
5053: * methodSignature = mref.getTypeofmethod();
5054: * parseDescriptor(methodSignature); if(parsedSignature!=null &&
5055: * parsedSignature.size() >0) { int size=parsedSignature.size(); if(size >
5056: * 0) { ArrayList loadList=getRequiredLoadVarIndexes(code,s,size);
5057: *
5058: * for(int s1=0;s1<size;s1++) { java.lang.String
5059: * type=(java.lang.String)parsedSignature.get(s1); int
5060: * index=((localPosIndex)loadList.get(s1)).getIndex() ; int
5061: * loadpos=((localPosIndex)loadList.get(s1)).getPos(); LocalVariable
5062: * local=struc.getVariabelAtIndex(index);
5063: *
5064: * if(local==null) { java.lang.String varname="Var"+"_"+loadpos+"_"+index;
5065: * local=new
5066: * LocalVariable(minfo.getMethodName().concat(minfo.getStringifiedParameters()),varname,index); } } } } }
5067: */
5068:
5069: private ArrayList VarIndexes(byte[] code, int s, int size) {
5070: ArrayList list = new ArrayList();
5071: int count = 0;
5072: int start = (s - 1);
5073: while (count <= size && start >= 0) {
5074: StringBuffer sb = new StringBuffer("");
5075: StringBuffer in = new StringBuffer("");
5076: // if(isThisInstrStart(minfo.getIn))
5077: int loadpos = getLocalVarPosInCodeFromLoadInst(sb,
5078: code[start], in, start);
5079: int index = -1;
5080: if (loadpos != -1) {
5081: java.lang.String type = sb.toString();
5082: if (type.equals("simple")) {
5083: index = code[Integer.parseInt(in.toString())];
5084: } else {
5085: index = code[(start + 1)];
5086: }
5087: localPosIndex obj = new localPosIndex(index, loadpos);
5088: list.add(obj);
5089: count++;
5090: }
5091: --start;
5092:
5093: }
5094:
5095: return list;
5096: }
5097:
5098: class localPosIndex {
5099:
5100: int index; // local index
5101:
5102: int pos; // where in code
5103:
5104: localPosIndex(int i, int p) {
5105: index = i;
5106: pos = p;
5107: }
5108:
5109: public int getIndex() {
5110: return index;
5111: }
5112:
5113: public int getPos() {
5114: return pos;
5115: }
5116: }
5117:
5118: private boolean isThisInstReturn(int inst) {
5119:
5120: switch (inst) {
5121: case JvmOpCodes.ARETURN:
5122: case JvmOpCodes.IRETURN:
5123: case JvmOpCodes.FRETURN:
5124: case JvmOpCodes.DRETURN:
5125: case JvmOpCodes.LRETURN:
5126: return true;
5127: default:
5128: return false;
5129:
5130: }
5131:
5132: }
5133:
5134: private int isPrevInstLoadInst(int s, byte[] code,
5135: java.lang.StringBuffer pos, Hashtable ht, MethodInfo minfo) {
5136:
5137: int inst = code[s];
5138: int storePos = -1;
5139: int next = s + 1;
5140: if (isThisInstrStart(minfo.getInststartpos(), s)) {
5141: switch (inst) {
5142:
5143: /*
5144: * case JvmOpCodes.DLOAD : if(next >= code.length)return -1; return
5145: * code[next];
5146: */
5147:
5148: case JvmOpCodes.ALOAD_0:
5149: addCorresPondingStorePosInCode(JvmOpCodes.ASTORE_0, s,
5150: code, ht, 0, "simple", minfo);
5151: pos.append(s);
5152: return 0;
5153:
5154: case JvmOpCodes.ALOAD_1:
5155: addCorresPondingStorePosInCode(JvmOpCodes.ASTORE_1, s,
5156: code, ht, 1, "simple", minfo);
5157: pos.append(s);
5158: return 1;
5159:
5160: case JvmOpCodes.ALOAD_2:
5161: addCorresPondingStorePosInCode(JvmOpCodes.ASTORE_2, s,
5162: code, ht, 2, "simple", minfo);
5163: pos.append(s);
5164: return 2;
5165:
5166: case JvmOpCodes.ALOAD_3:
5167: addCorresPondingStorePosInCode(JvmOpCodes.ASTORE_3, s,
5168: code, ht, 3, "simple", minfo);
5169: pos.append(s);
5170: return 3;
5171:
5172: case JvmOpCodes.DLOAD_0:
5173: addCorresPondingStorePosInCode(JvmOpCodes.DSTORE_0, s,
5174: code, ht, 0, "simple", minfo);
5175: pos.append(s);
5176: return 0;
5177:
5178: case JvmOpCodes.DLOAD_1:
5179: addCorresPondingStorePosInCode(JvmOpCodes.DSTORE_1, s,
5180: code, ht, 1, "simple", minfo);
5181: pos.append(s);
5182: return 1;
5183:
5184: case JvmOpCodes.DLOAD_2:
5185: addCorresPondingStorePosInCode(JvmOpCodes.DSTORE_2, s,
5186: code, ht, 2, "simple", minfo);
5187: pos.append(s);
5188: return 2;
5189:
5190: case JvmOpCodes.DLOAD_3:
5191: pos.append(s);
5192: addCorresPondingStorePosInCode(JvmOpCodes.DSTORE_3, s,
5193: code, ht, 3, "simple", minfo);
5194: return 3;
5195:
5196: /*
5197: * case JvmOpCodes.FLOAD : if(next >= code.length)return -1;
5198: * return code[next];
5199: */
5200:
5201: case JvmOpCodes.FLOAD_0:
5202: addCorresPondingStorePosInCode(JvmOpCodes.FSTORE_0, s,
5203: code, ht, 0, "simple", minfo);
5204: pos.append(s);
5205: return 0;
5206:
5207: case JvmOpCodes.FLOAD_1:
5208: addCorresPondingStorePosInCode(JvmOpCodes.FSTORE_1, s,
5209: code, ht, 1, "simple", minfo);
5210: pos.append(s);
5211: return 1;
5212:
5213: case JvmOpCodes.FLOAD_2:
5214: addCorresPondingStorePosInCode(JvmOpCodes.FSTORE_2, s,
5215: code, ht, 2, "simple", minfo);
5216: pos.append(s);
5217: return 2;
5218:
5219: case JvmOpCodes.FLOAD_3:
5220: addCorresPondingStorePosInCode(JvmOpCodes.FSTORE_3, s,
5221: code, ht, 3, "simple", minfo);
5222: pos.append(s);
5223: return 3;
5224:
5225: /*
5226: * case JvmOpCodes.ILOAD : if(next >= code.length)return -1;
5227: * return code[next];
5228: */
5229:
5230: case JvmOpCodes.ILOAD_0:
5231: addCorresPondingStorePosInCode(JvmOpCodes.ISTORE_0, s,
5232: code, ht, 0, "simple", minfo);
5233: pos.append(s);
5234: return 0;
5235:
5236: case JvmOpCodes.ILOAD_1:
5237: addCorresPondingStorePosInCode(JvmOpCodes.ISTORE_1, s,
5238: code, ht, 1, "simple", minfo);
5239: pos.append(s);
5240: return 1;
5241:
5242: case JvmOpCodes.ILOAD_2:
5243: addCorresPondingStorePosInCode(JvmOpCodes.ISTORE_2, s,
5244: code, ht, 2, "simple", minfo);
5245: pos.append(s);
5246: return 2;
5247:
5248: case JvmOpCodes.ILOAD_3:
5249: addCorresPondingStorePosInCode(JvmOpCodes.ISTORE_3, s,
5250: code, ht, 3, "simple", minfo);
5251: pos.append(s);
5252: return 3;
5253:
5254: /*
5255: * case JvmOpCodes.LLOAD: if(next >= code.length)return -1;
5256: * return code[next];
5257: */
5258: case JvmOpCodes.LLOAD_0:
5259: addCorresPondingStorePosInCode(JvmOpCodes.LSTORE_0, s,
5260: code, ht, 0, "simple", minfo);
5261: pos.append(s);
5262: return 0;
5263: case JvmOpCodes.LLOAD_1:
5264: addCorresPondingStorePosInCode(JvmOpCodes.LSTORE_1, s,
5265: code, ht, 1, "simple", minfo);
5266: pos.append(s);
5267: return 1;
5268: case JvmOpCodes.LLOAD_2:
5269: addCorresPondingStorePosInCode(JvmOpCodes.LSTORE_2, s,
5270: code, ht, 2, "simple", minfo);
5271: pos.append(s);
5272: return 2;
5273: case JvmOpCodes.LLOAD_3:
5274: addCorresPondingStorePosInCode(JvmOpCodes.LSTORE_3, s,
5275: code, ht, 3, "simple", minfo);
5276: pos.append(s);
5277: return 3;
5278:
5279: }
5280:
5281: } //
5282: int p = s - 1;
5283:
5284: if (p >= 0 && isThisInstrStart(minfo.getInststartpos(), p)) {
5285:
5286: switch (code[p]) {
5287: case JvmOpCodes.DLOAD:
5288: addCorresPondingStorePosInCode(JvmOpCodes.DSTORE, p,
5289: code, ht, code[s], "com", minfo);
5290: pos.append(p);
5291: return code[s];
5292: case JvmOpCodes.LLOAD:
5293: addCorresPondingStorePosInCode(JvmOpCodes.LSTORE, p,
5294: code, ht, code[s], "com", minfo);
5295: pos.append(p);
5296: return code[s];
5297: case JvmOpCodes.ILOAD:
5298: addCorresPondingStorePosInCode(JvmOpCodes.ISTORE, p,
5299: code, ht, code[s], "com", minfo);
5300: pos.append(p);
5301: return code[s];
5302: case JvmOpCodes.FLOAD:
5303: addCorresPondingStorePosInCode(JvmOpCodes.FSTORE, p,
5304: code, ht, code[s], "com", minfo);
5305: pos.append(p);
5306: return code[s];
5307:
5308: case JvmOpCodes.ALOAD:
5309: addCorresPondingStorePosInCode(JvmOpCodes.ASTORE, p,
5310: code, ht, code[s], "com", minfo);
5311: pos.append(p);
5312: return code[s];
5313:
5314: }
5315: }
5316:
5317: return -1;
5318: }
5319:
5320: private int isThisNextIfZeroInst(byte[] code, int s) {
5321: switch (code[s]) {
5322: case JvmOpCodes.IFEQ:
5323: case JvmOpCodes.IFNE:
5324: return s;
5325: }
5326: return -1;
5327: }
5328:
5329: private int isPrevInstILoad(int ifpos, byte[] code) {
5330:
5331: // Attempt1
5332: int prev = ifpos - 1;
5333: int inst = code[prev];
5334: switch (inst) {
5335:
5336: case JvmOpCodes.ILOAD_0:
5337: return 0;
5338: case JvmOpCodes.ILOAD_1:
5339: return 1;
5340: case JvmOpCodes.ILOAD_2:
5341: return 2;
5342: case JvmOpCodes.ILOAD_3:
5343: return 3;
5344: }
5345:
5346: // attempt2
5347: prev = ifpos - 2;
5348: if (code[prev] == JvmOpCodes.ILOAD) {
5349: return code[(prev + 1)];
5350: }
5351:
5352: return -1;
5353: }
5354:
5355: private int getLoadPosInCode(int ifpos, byte[] code) {
5356: // Attempt1
5357: int prev = ifpos - 1;
5358: int inst = code[prev];
5359: switch (inst) {
5360:
5361: case JvmOpCodes.ILOAD_0:
5362: case JvmOpCodes.ILOAD_1:
5363: case JvmOpCodes.ILOAD_2:
5364: case JvmOpCodes.ILOAD_3:
5365: return prev;
5366: }
5367:
5368: // attempt2
5369: prev = ifpos - 2;
5370: if (code[prev] == JvmOpCodes.ILOAD) {
5371: return prev;
5372: }
5373:
5374: return -1;
5375: }
5376:
5377: void addCorresPondingStorePosInCode(int lookfor, int loadpos,
5378: byte[] code, Hashtable map, int matchingindex,
5379: java.lang.String type, MethodInfo minfo) {
5380: for (int s = loadpos; s >= 0; s--) {
5381: if (isThisInstrStart(minfo.getInststartpos(), s)) {
5382: if (code[s] == lookfor) {
5383: if (type.indexOf("simple") >= 0) {
5384: int storepos = s;
5385: map.put(new Integer(storepos), new Integer(
5386: loadpos));
5387: break;
5388: } else {
5389: int t = s + 1;
5390: int curinstindex = code[t];
5391: if (curinstindex < 0)
5392: curinstindex += 256;
5393: if (matchingindex < 0)
5394: matchingindex += 256;
5395: if (curinstindex == matchingindex) {
5396: int storepos = s;
5397: map.put(new Integer(storepos), new Integer(
5398: loadpos));
5399: break;
5400: }
5401: }
5402: }
5403: }
5404: }
5405: }
5406:
5407: public Hashtable getMethod_name_storeNLoad_Map() {
5408: return method_name_storeNLoad_Map;
5409: }
5410:
5411: private Hashtable method_name_storeNLoad_Map = new Hashtable();
5412:
5413: private boolean isNextInstructionInvokeInterface(int nextInst) {
5414:
5415: if (nextInst == JvmOpCodes.INVOKEINTERFACE)
5416: return true;
5417: else
5418: return false;
5419: }
5420:
5421: private boolean isNextInstructionInvokeSpecial(int nextInst) {
5422:
5423: if (nextInst == JvmOpCodes.INVOKESPECIAL)
5424: return true;
5425: else
5426: return false;
5427: }
5428:
5429: private boolean isNextInstructionInvokeStatic(int nextInst) {
5430:
5431: if (nextInst == JvmOpCodes.INVOKESTATIC)
5432: return true;
5433: else
5434: return false;
5435: }
5436:
5437: private boolean isNextInstructionInvokeVirtual(int nextInst) {
5438:
5439: if (nextInst == JvmOpCodes.INVOKEVIRTUAL)
5440: return true;
5441: else
5442: return false;
5443: }
5444:
5445: boolean iamprimitive = false;
5446:
5447: boolean primitive = false;
5448:
5449: int numberOfBrackets = -1;
5450:
5451: private boolean AmIPrimitive(java.lang.String className) {
5452: if (className.equals("I") || className.equals("B")
5453: || className.equals("C") || className.equals("S")
5454: || className.equals("F") || className.equals("D")
5455: || className.equals("J") || className.equals("Z")) {
5456: return true;
5457: } else
5458: return false;
5459:
5460: }
5461:
5462: private boolean returnTypeAsObjectType;
5463:
5464: private void setReturnTypeAsObjectOrArrayType(boolean b) {
5465: returnTypeAsObjectType = b;
5466: }
5467:
5468: boolean isParameterArray = false;
5469:
5470: java.lang.String returnType = "";
5471:
5472: int returnTypeArrayDimension = -1;
5473:
5474: boolean returnTypeIsArray = false;
5475:
5476: ArrayList parsedSignature = null;
5477:
5478: public ArrayList getParsedSignatureAsList() {
5479: return parsedSignature;
5480: }
5481:
5482: public void parseDescriptor(java.lang.String descriptor) {
5483: ArrayList parameters = new ArrayList();
5484: parsedSignature = parameters;
5485: int charIndex = 0;
5486: java.lang.String parameterString = descriptor.substring(1,
5487: descriptor.lastIndexOf(")"));
5488: /*
5489: * java.lang.String returnString =
5490: * descriptor.substring(descriptor.lastIndexOf(")")+1);
5491: * if(returnString.trim().length() > 0){
5492: * if(returnString.trim().charAt(0)=='L' ||
5493: * returnString.trim().charAt(0)=='[')
5494: * this.setReturnTypeAsObjectOrArrayType(true); else
5495: * this.setReturnTypeAsObjectOrArrayType(false); }
5496: */
5497:
5498: java.lang.String arrString = "";
5499: // while(charIndex < parameterString.length())
5500: while (parameterString.length() > 0) {
5501: if (parameterString.startsWith("L")) {
5502: java.lang.String objectString = parameterString
5503: .substring(0, parameterString.indexOf(";"));
5504: objectString = objectString.replace('/', '.');
5505: parameters.add(objectString);
5506: charIndex = charIndex + (objectString.length() + 2);
5507: parameterString = parameterString
5508: .substring(parameterString.indexOf(";") + 1);
5509: } else {
5510: char parameterChar = parameterString.charAt(0);
5511: if (parameterChar == '[') {
5512: arrString = "";
5513: while (parameterString.startsWith("[")) {
5514: arrString += "[";
5515: parameterString = parameterString.substring(1,
5516: parameterString.length());
5517: isParameterArray = true;
5518: }
5519: java.lang.String objectString = "";
5520: if (parameterString.charAt(0) == 'L') {
5521: objectString = parameterString.substring(0,
5522: parameterString.indexOf(";"));
5523: parameterString = parameterString
5524: .substring(parameterString.indexOf(";") + 1);
5525: objectString = objectString.replace('/', '.');
5526: parameters.add(arrString + objectString);
5527: isParameterArray = false;
5528: }
5529: /*
5530: * while(objectString.startsWith("[")) { arrString += "[";
5531: * objectString =
5532: * objectString.substring(1,objectString.length()); }
5533: * objectString = objectString.substring(1); objectString =
5534: * objectString.replace('/','.');
5535: * parameters.add(objectString); charIndex = charIndex +
5536: * (objectString.length() + 2);
5537: * parameters.add(arrString+objectString);
5538: */
5539:
5540: } else {
5541: if (parameterChar == 'I') {
5542: if (isParameterArray) {
5543: parameters.add(arrString + "int");
5544: isParameterArray = false;
5545: } else {
5546: parameters.add("int");
5547: }
5548: }
5549: if (parameterChar == 'B') {
5550: if (isParameterArray) {
5551: parameters.add(arrString + "byte");
5552: isParameterArray = false;
5553: } else {
5554: parameters.add("byte");
5555: }
5556: }
5557: if (parameterChar == 'C') {
5558: if (isParameterArray) {
5559: parameters.add(arrString + "char");
5560: isParameterArray = false;
5561: } else {
5562: parameters.add("char");
5563: }
5564: }
5565: if (parameterChar == 'D') {
5566: if (isParameterArray) {
5567: parameters.add(arrString + "double");
5568: isParameterArray = false;
5569: } else {
5570: parameters.add("double");
5571: }
5572: }
5573: if (parameterChar == 'F') {
5574: if (isParameterArray) {
5575: parameters.add(arrString + "float");
5576: isParameterArray = false;
5577: } else {
5578: parameters.add("float");
5579: }
5580: }
5581: if (parameterChar == 'J') {
5582: if (isParameterArray) {
5583: parameters.add(arrString + "long");
5584: isParameterArray = false;
5585: } else {
5586: parameters.add("long");
5587: }
5588: }
5589: if (parameterChar == 'S') {
5590: if (isParameterArray) {
5591: parameters.add(arrString + "short");
5592: isParameterArray = false;
5593: } else {
5594: parameters.add("short");
5595: }
5596: }
5597: if (parameterChar == 'Z') {
5598: if (isParameterArray) {
5599: parameters.add(arrString + "boolean");
5600: isParameterArray = false;
5601: } else {
5602: parameters.add("boolean");
5603: }
5604: }
5605: parameterString = parameterString.substring(1);
5606: }
5607:
5608: }
5609: }
5610:
5611: /*
5612: * if(returnString.indexOf(";") !=-1) { returnString =
5613: * returnString.substring(0,returnString.indexOf(";")); }
5614: *
5615: * while(returnString.length() > 0) { // 4();
5616: * if(returnString.startsWith("L")) { //System.out.println(returnString + "
5617: * "+returnType.length()); returnType =
5618: * returnString.substring(1,returnString.length()); returnType =
5619: * returnType.replace('/','.'); returnString=""; } else {
5620: * if(returnString.equals("I")) { returnType = "int"; returnString = ""; }
5621: * if(returnString.equals("B")) { returnType = "byte"; returnString =
5622: * ""; } if(returnString.equals("C")) { returnType = "char";
5623: * returnString = ""; } if(returnString.equals("D")) { returnType =
5624: * "double"; returnString = ""; } if(returnString.equals("F")) {
5625: * returnType = "float"; returnString = ""; }
5626: * if(returnString.equals("J")) { returnType = "long"; returnString =
5627: * ""; } if(returnString.equals("S")) { returnType = "short";
5628: * returnString = ""; } if(returnString.equals("Z")) { returnType =
5629: * "boolean"; returnString = ""; } if(returnString.equals("V")) {
5630: * returnType = "void"; returnString = ""; }
5631: * if(returnString.startsWith("[")) { returnTypeIsArray = true;
5632: * returnTypeArrayDimension = returnString.lastIndexOf("[")+1;
5633: * if(returnString.indexOf("L")!=-1) { returnType =
5634: * returnString.substring(returnString.lastIndexOf("[")+2); returnType =
5635: * returnType.replace('/','.'); returnString = ""; //returnString
5636: * =returnType; } else { returnString =
5637: * returnString.substring(returnString.lastIndexOf("[")+1);
5638: * //returnString = ""; } } } }
5639: */
5640:
5641: }
5642:
5643: private int getLocalVarPosInCodeFromLoadInst(StringBuffer sb,
5644: int t, StringBuffer in, int where) {
5645:
5646: int retpos = -1;
5647: switch (t) {
5648:
5649: case JvmOpCodes.ALOAD:
5650: retpos = where;
5651: break;
5652: case JvmOpCodes.ALOAD_0:
5653: retpos = where;
5654: sb.append("simple");
5655: in.append("0");
5656: break;
5657: case JvmOpCodes.ALOAD_1:
5658: retpos = where;
5659: sb.append("simple");
5660: in.append("1");
5661: break;
5662: case JvmOpCodes.ALOAD_2:
5663: retpos = where;
5664: sb.append("simple");
5665: in.append("2");
5666:
5667: break;
5668: case JvmOpCodes.ALOAD_3:
5669: retpos = where;
5670: sb.append("simple");
5671: in.append("3");
5672:
5673: break;
5674: case JvmOpCodes.ILOAD:
5675: retpos = where;
5676:
5677: break;
5678: case JvmOpCodes.ILOAD_0:
5679: retpos = where;
5680: sb.append("simple");
5681: in.append("0");
5682:
5683: break;
5684: case JvmOpCodes.ILOAD_1:
5685: retpos = where;
5686: sb.append("simple");
5687: in.append("1");
5688: break;
5689: case JvmOpCodes.ILOAD_2:
5690: retpos = where;
5691: sb.append("simple");
5692: in.append("2");
5693: break;
5694: case JvmOpCodes.ILOAD_3:
5695: retpos = where;
5696: sb.append("simple");
5697: in.append("3");
5698: break;
5699:
5700: case JvmOpCodes.LLOAD:
5701: retpos = where;
5702:
5703: break;
5704: case JvmOpCodes.LLOAD_0:
5705: retpos = where;
5706: sb.append("simple");
5707: in.append("0");
5708: break;
5709: case JvmOpCodes.LLOAD_1:
5710: retpos = where;
5711: sb.append("simple");
5712: in.append("1");
5713: break;
5714: case JvmOpCodes.LLOAD_2:
5715: retpos = where;
5716: sb.append("simple");
5717: in.append("2");
5718: break;
5719: case JvmOpCodes.LLOAD_3:
5720: retpos = where;
5721: sb.append("simple");
5722: in.append("3");
5723: break;
5724:
5725: case JvmOpCodes.FLOAD:
5726: retpos = where;
5727: break;
5728: case JvmOpCodes.FLOAD_0:
5729: retpos = where;
5730: sb.append("simple");
5731: in.append("0");
5732: break;
5733: case JvmOpCodes.FLOAD_1:
5734: retpos = where;
5735: sb.append("simple");
5736: in.append("1");
5737: break;
5738: case JvmOpCodes.FLOAD_2:
5739: retpos = where;
5740: sb.append("simple");
5741: in.append("2");
5742: break;
5743: case JvmOpCodes.FLOAD_3:
5744: retpos = where;
5745: sb.append("simple");
5746: in.append("3");
5747: break;
5748:
5749: case JvmOpCodes.DLOAD:
5750: retpos = where;
5751: break;
5752: case JvmOpCodes.DLOAD_0:
5753: retpos = where;
5754: sb.append("simple");
5755: in.append("0");
5756: break;
5757: case JvmOpCodes.DLOAD_1:
5758: retpos = where;
5759: sb.append("simple");
5760: in.append("1");
5761: break;
5762: case JvmOpCodes.DLOAD_2:
5763: retpos = where;
5764: sb.append("simple");
5765: in.append("2");
5766: break;
5767: case JvmOpCodes.DLOAD_3:
5768: retpos = where;
5769: sb.append("simple");
5770: in.append("3");
5771: break;
5772:
5773: }
5774:
5775: return retpos;
5776:
5777: }
5778:
5779: private void registerStartOfInstuctionsForMethod(byte[] info,
5780: MethodInfo minfo) {
5781: int start = 0;
5782: ArrayList inststartspos = new ArrayList();
5783: HashMap map = ConsoleLauncher.getInstructionMap();
5784: int k = 0;
5785: while (true) {
5786: // Shutdown dd;
5787: java.lang.String deleteme = "";
5788: // deleteme.
5789: if (k >= info.length)
5790: break;
5791: inststartspos.add(new Integer(k));
5792: int inst = info[k];
5793: Integer skip = (Integer) map.get(new Integer(inst));
5794: int iskip = skip.intValue();
5795: boolean xx = false;
5796: // System.out.println(iskip+"iskip" +k+"-->k"+info.length+"length");
5797: if (iskip == -1) // lookup // TODO: verify increment
5798: {
5799: xx = true;
5800: int lookupSwitchPos = k;
5801: int leave_bytes = (4 - (k % 4)) - 1;
5802: for (int indx = 0; indx < leave_bytes; indx++) {
5803: k++;
5804: }
5805: // Read Default
5806: int Default = getSwitchOffset(info, k, "");// info[++i] << 24)
5807: // | (info[++i] <<
5808: // 16) | (info[++i]
5809: // << 8) |info[++i];
5810: k += 4;
5811: int numberOfLabels = (getSwitchOffset(info, k, "")); // info[++i]
5812: // <<
5813: // 24) |
5814: // (info[++i]
5815: // <<
5816: // 16) |
5817: // (info[++i]
5818: // << 8)
5819: // |info[++i];
5820: // int high=(info[++i] << 24) | (info[++i] << 16) | (info[++i]
5821: // << 8) |info[++i];
5822: // int numberOfOffsets=(high-low)+1;
5823: k += 4;
5824: int offsetValues[] = new int[numberOfLabels];
5825: int labels[] = new int[numberOfLabels];
5826:
5827: for (start = 0; start < numberOfLabels; start++) {
5828: int label = getSwitchOffset(info, k, "label");
5829: k += 4;
5830: int offsetVal = getSwitchOffset(info, k, "");// (info[++i]
5831: // << 24) |
5832: // (info[++i]
5833: // << 16) |
5834: // (info[++i]
5835: // << 8)
5836: // |info[++i];
5837: k += 4;
5838: labels[start] = label;
5839: offsetValues[start] = offsetVal;
5840:
5841: }
5842: // CharacterData d;
5843: }
5844: if (iskip == -2) // table
5845: {
5846: xx = true;
5847: int tableSwitchPos = k;
5848: int leave_bytes = (4 - (k % 4)) - 1;
5849: for (int indx = 0; indx < leave_bytes; indx++) {
5850: k++;
5851: }
5852: // Read Default
5853: int Default = getSwitchOffset(info, k, "");// (info[++i] << 24)
5854: // | (info[++i] <<
5855: // 16) | (info[++i]
5856: // << 8) |info[++i];
5857: k += 4;
5858: int low = getSwitchOffset(info, k, "label");// (info[++i] << 24)
5859: // | (info[++i] <<
5860: // 16) | (info[++i]
5861: // << 8) |info[++i];
5862: k += 4;
5863: int high = getSwitchOffset(info, k, "label");// (info[++i] <<
5864: // 24) |
5865: // (info[++i] <<
5866: // 16) |
5867: // (info[++i] <<
5868: // 8)
5869: // |info[++i];
5870: k += 4;
5871: int numberOfOffsets = (high - low) + 1;
5872: int[] offsetValues = new int[numberOfOffsets];
5873: for (start = 0; start < numberOfOffsets; start++) {
5874: int offsetVal = getSwitchOffset(info, k, "");
5875: k += 4;
5876: offsetValues[start] = offsetVal;
5877:
5878: }
5879:
5880: }
5881: if (iskip == -3) // TODO: wide
5882: {
5883:
5884: int nextinstcode = info[(k + 1)];
5885: if (nextinstcode == JvmOpCodes.IINC) {
5886: k += 3;
5887: } else {
5888: k += 5;
5889: }
5890: xx = true;
5891:
5892: }
5893: if (!xx) {
5894: int nextInstpos = k + iskip + 1;
5895: k = nextInstpos;
5896: } else
5897: k += 1;
5898:
5899: }
5900: minfo.setInststartpos(inststartspos);
5901:
5902: }
5903:
5904: private boolean isThisInstrStart(ArrayList list, int pos) {
5905: boolean ok = false;
5906: if (list == null)
5907: throw new NullPointerException("START POS IS NULL");
5908: if (list != null) {
5909: for (int k = 0; k < list.size(); k++) {
5910: Integer in = (Integer) list.get(k);
5911: if (in != null) {
5912: int i = in.intValue();
5913: if (i == pos)
5914: return !ok;
5915: }
5916: }
5917: }
5918: return ok;
5919:
5920: }
5921:
5922: private int getLoopConditionalEnd(Loop loop, MethodInfo minfo) {
5923: int i = -1;
5924: int start = loop.getStartIndex();
5925: byte code[] = minfo.getCode();
5926: if (code == null || start == -1)
5927: return i;
5928: int end = loop.getEndIndex();
5929: for (int x = start + 1; x < end; x++) {
5930: if (isThisInstrStart(minfo.getInststartpos(), x)) {
5931:
5932: boolean isif = isInstructionIF(code[x]);
5933: if (isif) {
5934:
5935: int ifjump = getJumpAddress(code, x);
5936: return ifjump;
5937: }
5938: }
5939:
5940: }
5941: return i;
5942: }
5943:
5944: private void resetEndOfLoops(ArrayList loops, MethodInfo minfo) {
5945: int allstarts[] = getALLLoopStarts(loops);
5946: for (int s = 0; s < allstarts.length; s++) {
5947: int cur = allstarts[s];
5948: ArrayList temp = getALLLoopsForLoopStart(cur, loops);
5949: if (temp != null) {
5950: int maxend = getMaxEndForLoops(temp);
5951: resetEndOFLoopsWRTnewmaxend(maxend, temp);
5952: // checkForInvalidEndOfLoop(temp,minfo);
5953: }
5954:
5955: }
5956:
5957: ArrayList unique = Loop.removeDuplicates(loops);
5958: if (loops != null && unique != null && loops.size() > 0
5959: && unique.size() > 0)
5960: minfo.setLoops(unique);
5961: int i = 0;
5962:
5963: }
5964:
5965: private int[] getALLLoopStarts(ArrayList loops) {
5966: int[] temp = new int[loops.size()];
5967: for (int x = 0; x < loops.size(); x++) {
5968: temp[x] = ((Loop) loops.get(x)).getStartIndex();
5969: }
5970: return temp;
5971: }
5972:
5973: private ArrayList getALLLoopsForLoopStart(int cur, ArrayList loops) {
5974: if (loops == null || loops.size() == 0)
5975: return null;
5976: ArrayList temp = new ArrayList();
5977: for (int x = 0; x < loops.size(); x++) {
5978: Loop l = (Loop) loops.get(x);
5979: int s = (l).getStartIndex();
5980: if (s == cur) {
5981: temp.add(l);
5982: }
5983:
5984: }
5985:
5986: if (temp.size() == 0)
5987: return null;
5988: return temp;
5989: }
5990:
5991: /***************************************************************************
5992: *
5993: * @param loops
5994: * ...> subset of loops
5995: * @return
5996: */
5997: private int getMaxEndForLoops(ArrayList loops) {
5998: int[] ends = new int[loops.size()];
5999: for (int z = 0; z < loops.size(); z++) {
6000: ends[z] = ((Loop) loops.get(z)).getEndIndex();
6001: }
6002: Arrays.sort(ends);
6003: return ends[ends.length - 1];
6004: }
6005:
6006: private void resetEndOFLoopsWRTnewmaxend(int maxend, ArrayList temp) {
6007: if (temp == null || temp.size() == 0)
6008: return;
6009: for (int z = 0; z < temp.size(); z++) {
6010: Loop cur = (Loop) temp.get(z);
6011: if (cur.getEndIndex() != maxend) {
6012: cur.setEndIndex(maxend);
6013: int brend = cur.getLoopEndForBracket();
6014: if (brend < maxend) {
6015: cur.setLoopEndForBracket(maxend);
6016: }
6017: }
6018: }
6019: }
6020:
6021: private void checkForInvalidEndOfLoop(ArrayList temp,
6022: MethodInfo minfo) {
6023: byte[] code = minfo.getCode();
6024: if (code == null)
6025: return;
6026: if (temp == null || temp.size() == 0)
6027: return;
6028: for (int z = 0; z < temp.size(); z++) {
6029:
6030: Loop loop = (Loop) temp.get(z);
6031: int end = loop.getEndIndex();
6032: if (isThisInstrStart(minfo.getInststartpos(), end)) {
6033: if (code[end] == JvmOpCodes.GOTO)
6034: return; // No need to reset
6035: boolean b = isInstructionIF(code[end]);
6036: if (b) // Need to reset
6037: {
6038: int j = end + 3;
6039: int reqdend = end;
6040: while (j < code.length) {
6041: if (code[j] == JvmOpCodes.GOTO) {
6042: /*
6043: * int jmp=getJumpAddress(code,j); if(jmp > )
6044: */
6045: reqdend = end;
6046: loop.setInfinite(true);
6047: break;
6048: }
6049:
6050: boolean r = checkForReturn(code, j, minfo);
6051: if (r) {
6052: reqdend = j;
6053: break;
6054: }
6055: r = isInstATHROW(minfo, j, code);
6056: if (r) {
6057: reqdend = j;
6058: break;
6059: }
6060: j++;
6061: }
6062: loop.setEndIndex(reqdend);
6063: int brend = loop.getLoopEndForBracket();
6064: if (brend < reqdend) {
6065: loop.setLoopEndForBracket(reqdend);
6066: }
6067: }
6068: }
6069:
6070: }
6071:
6072: }
6073:
6074: private boolean checkForReturn(byte[] code, int i, MethodInfo minfo) {
6075: boolean present = false;
6076: int jvmInst = code[i];
6077: boolean b = isThisInstrStart(minfo.getInststartpos(), i);
6078: if (b == false)
6079: return false;
6080: switch (jvmInst) {
6081: case JvmOpCodes.ARETURN:
6082: case JvmOpCodes.IRETURN:
6083: case JvmOpCodes.FRETURN:
6084: case JvmOpCodes.DRETURN:
6085: case JvmOpCodes.LRETURN:
6086: case JvmOpCodes.RETURN:
6087: present = true;
6088: break;
6089: default:
6090: present = false;
6091: break;
6092: }
6093: return present;
6094: }
6095:
6096: private boolean isInstATHROW(MethodInfo minfo, int i, byte[] code) {
6097:
6098: if (code == null)
6099: return false;
6100: boolean n = isThisInstrStart(minfo.getInststartpos(), i);
6101: if (!n)
6102: return false;
6103: if (code[i] == JvmOpCodes.ATHROW)
6104: return true;
6105: return false;
6106: }
6107:
6108: private ExceptionTable getTableWhoseHandlerIsFinallyForThisTry(
6109: int trystart, ArrayList trylist) {
6110:
6111: ExceptionTable table = null;
6112: for (int z = 0; z < trylist.size(); z++) {
6113:
6114: ExceptionTable temp = (ExceptionTable) trylist.get(z);
6115: int tempstart = temp.getStartOfGuardRegion();
6116: java.lang.String type = temp
6117: .getTypeOfHandlerForGuardRegion();
6118: if (type.equals("FinallyBlock")) {
6119:
6120: if (tempstart == trystart) {
6121: return temp;
6122: }
6123:
6124: }
6125:
6126: }
6127:
6128: return null;
6129:
6130: }
6131:
6132: private ArrayList getAllExceptionBlocksWithSameTryStart(
6133: ArrayList tables) {
6134: if (tables == null || tables.size() == 0)
6135: return null;
6136: ArrayList list = new ArrayList();
6137: for (int z = 0; z < tables.size(); z++) {
6138:
6139: TryBlock tryb = (TryBlock) tables.get(z);
6140: int trys = tryb.getStart();
6141: ExceptionTable except1 = tryb
6142: .getBiggestTableUsedToCreateTry();
6143: ArrayList sublist = new ArrayList();
6144: sublist.add(except1);
6145: for (int k = z + 1; k < tables.size(); k++) {
6146: TryBlock tryblock = (TryBlock) tables.get(k);
6147: if (tryblock != tryb) {
6148: int temp = tryblock.getStart();
6149: if (temp == trys) {
6150: ExceptionTable except2 = tryblock
6151: .getTableUsedToCreateTry();
6152: sublist.add(except2);
6153: }
6154: }
6155: }
6156: if (sublist.size() > 1) {
6157: list.add(sublist);
6158: }
6159:
6160: }
6161: return list;
6162: }
6163:
6164: // list: exceptiontables
6165: /**
6166: * @param list
6167: * @param tries
6168: */
6169: private void checkForIllegalTriesForList(ArrayList list,
6170: ArrayList tries) {
6171:
6172: if (list.size() < 2)
6173: return;
6174: int size = list.size();
6175: int ar[] = new int[size];
6176: HashMap map = new HashMap();
6177: for (int z = 0; z < size; z++) {
6178: ExceptionTable t = ((ExceptionTable) list.get(z));
6179: ar[z] = t.getEndOfGuardRegion();
6180: map.put("" + ar[z], t);
6181: }
6182: Arrays.sort(ar);
6183: int max = ar[size - 1];
6184: int next = ar[size - 2];
6185: ExceptionTable biggest = (ExceptionTable) map.get("" + max);
6186: if (biggest != null) {
6187: java.lang.String expname = biggest.getExceptionName();
6188: if (expname.equals("<any>") == false) {
6189: return;
6190: }
6191:
6192: // Need to do here
6193: // Compare the biggest table with its immediate next in sorted
6194: // list(By ends)-->(t)
6195: // Check whether this end of guards is after the end of handler for
6196: // table t.
6197: // If it is just return;
6198: // else
6199: // 1>need to link the end of hanlder for t accd to biggest table
6200: // 2>need to reset type of guard for biggest so as not to generate a
6201: // try
6202: // 3>need to get the try table for the biggest table
6203: // 4>need to link the finally with try of t
6204: // 5>remove this try from list
6205: // return
6206: ExceptionTable nextTable = (ExceptionTable) map.get(""
6207: + next);
6208: if (nextTable == null) {
6209: return;
6210: }
6211: int handlerend_next = nextTable
6212: .getEndOfHandlerForGuardRegion();
6213: int guardEnd_biggest = biggest.getEndOfGuardRegion();
6214: if (guardEnd_biggest < handlerend_next) {
6215: int handlerstart_biggest = biggest
6216: .getStartOfHandlerForGuardRegion();
6217: nextTable
6218: .setEndOfHandlerForGuardRegion(handlerstart_biggest); // point
6219: // 1
6220:
6221: biggest.setTypeOfGuardRegion(""); // point 2
6222:
6223: TryBlock tryblock_biggest = getTryBlockForExceptionTable(
6224: biggest, tries); // point 3
6225: if (tryblock_biggest != null) // shud never be null
6226: {
6227: FinallyBlock finblk_biggest = tryblock_biggest
6228: .getFinallyBlock();
6229: if (finblk_biggest != null) // shud never be null
6230: {
6231: TryBlock tryblock_next = getTryBlockForExceptionTable(
6232: nextTable, tries); // point 3
6233: CatchBlock cblk = tryblock_next
6234: .getLastCatchBlock();
6235: if (cblk != null) {
6236: cblk.setEnd(handlerstart_biggest);
6237: }
6238: if (tryblock_next != null)// shud never be null
6239: {
6240: FinallyBlock finblk_next = tryblock_next
6241: .getFinallyBlock();
6242: if (finblk_next == null) {
6243: tryblock_next
6244: .setFinallyBlock(finblk_biggest); // point
6245: // 4
6246: tryblock_next.setHasFinallyBlk(true);
6247: tries.remove(tryblock_biggest); // point 5
6248: } else {
6249: // A SCENARIO NOT THOUGHT OFF
6250: }
6251:
6252: }
6253:
6254: }
6255:
6256: }
6257:
6258: } else
6259: return;
6260: }
6261:
6262: }
6263:
6264: private TryBlock getTryBlockForExceptionTable(ExceptionTable table,
6265: ArrayList tries) {
6266:
6267: TryBlock block = null;
6268: if (tries == null || tries.size() == 0)
6269: return block;
6270: for (int z = 0; z < tries.size(); z++) {
6271: TryBlock t = (TryBlock) tries.get(z);
6272: ExceptionTable tb = t.getBiggestTableUsedToCreateTry();
6273: if (tb == table) {
6274: return t;
6275: }
6276:
6277: }
6278: return block;
6279: }
6280:
6281: public class SwitchCaseHelper {
6282: private int casestart = -1;
6283:
6284: private int caselabel = -1;
6285:
6286: private boolean hasBeenRegistered = false;
6287:
6288: int position = -1;
6289:
6290: public int getPos() {
6291: return position;
6292: }
6293:
6294: public SwitchCaseHelper(int cs, int cl, boolean registered,
6295: int pos) {
6296: casestart = cs;
6297: caselabel = cl;
6298: hasBeenRegistered = registered;
6299: position = pos;
6300: }
6301:
6302: public int getCaselabel() {
6303: return caselabel;
6304: }
6305:
6306: public void setCaselabel(int caselabel) {
6307: this .caselabel = caselabel;
6308: }
6309:
6310: public int getCasestart() {
6311: return casestart;
6312: }
6313:
6314: public void setCasestart(int casestart) {
6315: this .casestart = casestart;
6316: }
6317:
6318: public boolean isHasBeenRegistered() {
6319: return hasBeenRegistered;
6320: }
6321:
6322: public void setHasBeenRegistered(boolean hasBeenRegistered) {
6323: this .hasBeenRegistered = hasBeenRegistered;
6324: }
6325:
6326: }
6327:
6328: // Helper method makes use of SwitchCaseHelper class
6329: public int getCaseLabel(int casestart) {
6330: int i = -1;
6331: for (int z = 0; z < caseStartsLabels.size(); z++) {
6332: SwitchCaseHelper helper = (SwitchCaseHelper) caseStartsLabels
6333: .get(z);
6334: boolean b = helper.isHasBeenRegistered();
6335: if (!b && helper.getCasestart() == casestart) {
6336: i = helper.getCaselabel();
6337: helper.setHasBeenRegistered(true);
6338: break;
6339: }
6340: }
6341: return i;
6342: }
6343:
6344: private int getNextDifferentCaseStart(int[] sortedarray, int cur) {
6345: int pos = -1;
6346: for (int z = 0; z < sortedarray.length; z++) {
6347: if (cur == sortedarray[z]) {
6348: pos = z;
6349: break;
6350: }
6351:
6352: }
6353: if (pos == -1)
6354: return -1;
6355: pos++;
6356: for (; pos < sortedarray.length; pos++) {
6357: if (sortedarray[pos] != cur) {
6358: return sortedarray[pos];
6359: }
6360: }
6361: return -1;
6362: }
6363:
6364: // Call this method only if a case ends after default for switch
6365: private int findEndOfLastCaseForSwitch(int casestart, byte[] code,
6366: MethodInfo minfo) {
6367:
6368: int s = casestart;
6369: int len = code.length;
6370: int endOfCase = -1;
6371: for (; s < len; s++) {
6372: // System.out.println("s is "+s);
6373: int currentInstruction = getInstruction(code, s);
6374: /*
6375: * boolean IF=isInstructionIF(currentInstruction); if(IF) { int
6376: * ifPos=s; int jumpoffset=getJumpAddressForIf(ifPos,code); //TODO:
6377: * May lead to bugs if(jumpoffset > s) { s=jumpoffset; } else { //
6378: * s=s+1; } }
6379: */
6380: if (currentInstruction == JvmOpCodes.LOOKUPSWITCH) {
6381: int defaultjump = getDefaultAddressForSwitch(s, code);
6382: if (defaultjump > s) {
6383: s = defaultjump;
6384:
6385: } else {
6386: // s=s+1;
6387: }
6388: } else if (currentInstruction == JvmOpCodes.TABLESWITCH) {
6389: int defaultjump = getDefaultAddressForSwitch(s, code);
6390: if (defaultjump > s) {
6391: s = defaultjump;
6392:
6393: } else {
6394: // s=s+1;
6395: }
6396: }
6397: /*
6398: * else if(currentInstruction==JvmOpCodes.GOTO) {
6399: *
6400: * int gotoAddress=getGotoAddress(s,code,"normal");
6401: * if(gotoAddress!=-1 && gotoAddress > s) { s=gotoAddress; } // else
6402: * //s=s+1; }
6403: */
6404: // Detect here whether it is inside a try or start of Try or Catch
6405: // or Finally
6406: else if (minfo.getAllTryBlocksForMethod() != null
6407: && minfo.getAllTryBlocksForMethod().size() > 0) {
6408: ArrayList allTries = minfo.getAllTryBlocksForMethod();
6409: for (int st = 0; st < allTries.size(); st++) {
6410: TryBlock Try = (TryBlock) allTries.get(st);
6411: if (Try != null) {
6412: int tryStart = Try.getStart();
6413: if (tryStart == s
6414: || (s > tryStart && s <= Try.getEnd())) {
6415: FinallyBlock finallyBlk = Try
6416: .getFinallyBlock();
6417: if (finallyBlk != null) {
6418: int finallyEnd = finallyBlk.getEnd();
6419: s = finallyEnd; // what if finally end if not
6420: // set
6421: // TODO: check for -1 case
6422: break;
6423: } else {
6424: CatchBlock lastCatch = Try
6425: .getLastCatchBlock();
6426: int catchEnd = lastCatch.getEnd();
6427: s = catchEnd;
6428: break;
6429: }
6430: }
6431:
6432: }
6433:
6434: }
6435: }
6436:
6437: else if (currentInstruction == JvmOpCodes.ATHROW) {
6438: endOfCase = s;
6439: break;
6440: } else if (checkForReturn(code, s, minfo))// currentInstruction==JvmOpCodes.RETURN)
6441: {
6442: endOfCase = s;
6443: break;
6444: } else {
6445: // int dummy=s;
6446: // s=++s;
6447: }
6448:
6449: }
6450:
6451: // System.out.println();
6452: if (endOfCase == -1) {
6453: // switchBlk.setEndOfDefault(code.length-1); // TODO: Test This
6454: // vigorously
6455: return code.length - 1;
6456:
6457: } else {
6458: return endOfCase;
6459: }
6460:
6461: }
6462:
6463: private int getPositionForCaseLabel(int label) {
6464: if (caseLabelSorted != null) {
6465: for (int z = 0; z < caseLabelSorted.size(); z++) {
6466: Integer in = (Integer) caseLabelSorted.get(z);
6467: if (in.intValue() == label) {
6468: return z;
6469: }
6470: }
6471: }
6472: return -1;
6473: }
6474:
6475: private void checkEndOfSwitchAndCaseBlockWRTOuterSwitches(
6476: MethodInfo minfo) {
6477: ArrayList switches = minfo.getAllSwitchBlksForMethod();
6478: if (switches == null || switches.size() == 0)
6479: return;
6480: outer: for (int pos = 0; pos < switches.size(); pos++) {
6481: Switch blk = (Switch) switches.get(pos);
6482: Case lastcase = blk.getLastBlockForSwitch();
6483: int currentEnd = -1;
6484: int currentStart = -1;
6485: if (lastcase != null) {
6486: currentEnd = lastcase.getCaseEnd();
6487: currentStart = lastcase.getCaseStart();
6488: } else {
6489: currentEnd = blk.getDefaultEnd();
6490: currentStart = blk.getDefaultStart();
6491: }
6492:
6493: ArrayList outerSwitches = getOuterSwitches(blk, switches);
6494: if (outerSwitches.size() > 0) {
6495: Switch reqd = getLastStartSwitchInGroup(outerSwitches);
6496: if (reqd != null) {
6497: ArrayList cases = reqd.getAllCases();
6498: int[] sortedStarts = Switch
6499: .getSortedCaseStarts(cases);
6500: for (int p = 0; p < sortedStarts.length; p++) {
6501: int temp = sortedStarts[p];
6502: if (temp > currentStart && currentStart != -1) {
6503: if (currentEnd > temp) {
6504: if (lastcase != null) {
6505: lastcase.setCaseEnd(temp);
6506: continue outer;
6507: } else {
6508: blk.setEndOfDefault(temp);
6509: continue outer;
6510: }
6511: }
6512: }
6513: }
6514: }
6515: }
6516: }
6517: }
6518:
6519: private ArrayList getOuterSwitches(Switch block, ArrayList all) {
6520:
6521: ArrayList list = new ArrayList();
6522: int this Start = block.getStartOfSwitch();
6523: for (int pos = 0; pos < all.size(); pos++) {
6524: Switch blk = (Switch) all.get(pos);
6525: if (blk != block) {
6526:
6527: if (this Start > blk.getStartOfSwitch()
6528: && this Start < blk.getEndOfSwitch()) {
6529: list.add(blk);
6530: }
6531: }
6532: }
6533: return list;
6534: }
6535:
6536: private Switch getLastStartSwitchInGroup(ArrayList outerSwitches) {
6537: if (outerSwitches != null && outerSwitches.size() > 0) {
6538:
6539: if (outerSwitches.size() == 1) {
6540: return (Switch) outerSwitches.get(0);
6541: }
6542: int max = ((Switch) outerSwitches.get(0))
6543: .getStartOfSwitch();
6544: Switch reqd = (Switch) outerSwitches.get(0);
6545: for (int pos = 1; pos < outerSwitches.size(); pos++) {
6546: Switch blk = (Switch) outerSwitches.get(pos);
6547: if (blk.getStartOfSwitch() > max) {
6548: max = blk.getStartOfSwitch();
6549: reqd = blk;
6550: }
6551: }
6552: return reqd;
6553:
6554: }
6555: return null;
6556: }
6557:
6558: private boolean markLoopAsDoWhileType(int loopStart, byte[] info,
6559: MethodInfo minfo) {
6560: int current = loopStart;
6561: boolean gotoinst = current - 3 >= 0
6562: && info[current - 3] == JvmOpCodes.GOTO;
6563: ArrayList starts = minfo.getInststartpos();
6564: boolean isStart = isThisInstrStart(starts, current - 3);
6565: if (gotoinst && isStart) {
6566: int gotojump = getJumpAddress(info, current - 3);
6567: if (gotojump < current)
6568: return false;
6569: int nextInstPos = current;
6570: for (int k = gotojump; k < info.length; k++) {
6571: boolean b2 = isThisInstrStart(starts, k);
6572: if (b2) {
6573: boolean isif = isInstructionIF(info[k]);
6574: if (isif) {
6575: int offset = getJumpAddress(info, k);
6576: if (offset == nextInstPos) {
6577:
6578: return true;
6579: } else if (offset > k) {
6580: int ifatend = doesLoopEndAtIf(info,
6581: gotojump, nextInstPos, minfo);
6582: if (ifatend != -1) {
6583:
6584: return true;
6585: } else
6586: return false;
6587: } else {
6588: return false;
6589: }
6590:
6591: }
6592: }
6593: }
6594: return false;
6595:
6596: } else
6597: return false;
6598:
6599: }
6600:
6601: private int doesLoopEndAtIf(byte[] info, int from, int lookfor,
6602: MethodInfo minfo) {
6603: int i = -1;
6604: ArrayList starts = minfo.getInststartpos();
6605: for (int z = from; z < info.length; z++) {
6606: boolean start = isThisInstrStart(starts, z);
6607: if (start) {
6608: boolean b = isInstructionIF(info[z]);
6609: if (b) {
6610: int ifo = getJumpAddress(info, z);
6611: // Check 1
6612: if (ifo == lookfor) {
6613: return z;
6614: }
6615:
6616: if (ifo > z) {
6617: int x = ifo - 3;
6618: boolean s = isThisInstrStart(starts, x);
6619: if (s == false) {
6620: return i;
6621: } else {
6622: boolean isif = isInstructionIF(info[x]);
6623: if (isif) {
6624: int offset = getJumpAddress(info, x);
6625: if (offset == lookfor) {
6626: return x;
6627: }
6628: if (offset > x) {
6629: int j = doesLoopEndAtIf(info, ifo,
6630: lookfor, minfo);
6631: return j;
6632: } else {
6633: return i;
6634: }
6635:
6636: } else {
6637: return i;
6638: }
6639:
6640: }
6641:
6642: }
6643:
6644: }
6645:
6646: }
6647:
6648: }
6649:
6650: return i;
6651: }
6652: }
|