/** * Parse a method declaration. The declaration should be in the following format: * * <p>fully-qualified-method-name (args) * * <p>where the arguments are comma separated and all arguments other than primitives should have * fully qualified names. Arrays are indicating by trailing brackets. For example: * * <p>int int[] int[][] java.lang.String java.util.Date[] * * <p>The arguments are translated into BCEL types and a MethodDef is returned. */ private MethodDef parse_method(StrTok st) { // Get the method name String method_name = st.need_word(); // Get the opening paren st.need("("); // Read the arguments ArrayList<String> args = new ArrayList<String>(); String tok = st.nextToken(); if (tok != ")") { st.pushBack(); do { tok = st.need_word(); args.add(tok); } while (st.nextToken() == ","); st.pushBack(); st.need(")"); } // Convert the arguments to Type Type[] targs = new Type[args.size()]; for (int ii = 0; ii < args.size(); ii++) { targs[ii] = BCELUtil.classname_to_type(args.get(ii)); } return new MethodDef(method_name, targs); }
public void dump(PrintWriter out, PrintWriter outLinkInfo) { int i; out.println("//"); out.println("//\t" + classRefAddress + ": " + clazz.getClassName() + " class info"); out.println("//"); out.println("\t\t" + instSize + ",\t//\tinstance size"); for (i = 0; i < clft.len; ++i) { if (!clft.isStatic[i]) { out.println("\t\t\t\t//\t" + clft.idx[i] + " " + clft.key[i]); } } // link info: class addresses outLinkInfo.println( "class " + clazz.getClassName() + " " + methodsAddress + " " + cpoolAddress); outLinkInfo.println(" -instSize " + instSize); out.println("\t\t" + staticValueVarAddress + ",\t//\tpointer to static primitive fields"); if (instSize > 31) { System.err.println("Error: Object of " + clazz.getClassName() + " to big! Size=" + instSize); System.exit(-1); } out.println("\t\t" + instGCinfo + ",\t//\tinstance GC info"); String supname = "null"; int superAddr = 0; if (superClass != null) { supname = superClass.clazz.getClassName(); superAddr = ((JopClassInfo) appInfo.cliMap.get(supname)).classRefAddress; } if (!clazz.isInterface()) { out.println("\t\t" + superAddr + ",\t//\tpointer to super class - " + supname); // link info: super address outLinkInfo.println(" -super " + superAddr); } else { out.println("\t\t" + (-interfaceID) + ",\t//\tinterface ID"); } boolean useSuperInterfaceTable = false; if ((iftableAddress == 0) && (superClass != null)) { iftableAddress = ((JopClassInfo) appInfo.cliMap.get(supname)).iftableAddress; useSuperInterfaceTable = true; } out.println("\t\t" + iftableAddress + ",\t//\tpointer to interface table"); if (!clazz.isInterface()) { out.println("//"); out.println("//\t" + methodsAddress + ": " + clazz.getClassName() + " method table"); out.println("//"); int addr = methodsAddress; for (i = 0; i < clvt.len; i++) { clvt.mi[i].dumpMethodStruct(out, addr); outLinkInfo.println(" -mtab " + clvt.mi[i].getFQMethodName() + " " + addr); addr += ClassStructConstants.METH_STR; } } else { out.println("//"); out.println("//\tno method table for interfaces"); out.println("//"); } out.println(); out.println("\t\t" + classRefAddress + ",\t//\tpointer back to class struct (cp-1)"); out.println(); out.println("//"); out.println("//\t" + cpoolAddress + ": " + clazz.getClassName() + " constants"); out.println("//"); // link info: constant pool mapping for (Entry<Integer, Integer> entry : cpoolMap.entrySet()) { outLinkInfo.println(" -constmap " + entry.getKey() + " " + entry.getValue()); } // constant pool length includes the length field // same is true for the index in the bytecodes: // The lowest constant has index 1. out.println("\t\t" + (cpoolArry.length + 1) + ",\t//\tconst pool length"); out.println(); for (i = 0; i < cpoolArry.length; ++i) { out.println("\t\t" + cpoolArry[i] + ",\t//\t" + cpoolComments[i]); } if (iftableAddress != 0 && !useSuperInterfaceTable) { out.println("//"); out.println( "//\t" + (iftableAddress - (interfaceCnt + 31) / 32) + ": " + clazz.getClassName() + " implements table"); out.println("//"); for (i = (interfaceCnt + 31) / 32 - 1; i >= 0; i--) { String comment = ""; int word = 0; int j; for (j = 31; j >= 0; j--) { word <<= 1; if ((i * 32 + j) < interfaceCnt) { if (implementsInterface(interfaceList.get(i * 32 + j))) { word |= 1; comment += interfaceList.get(i * 32 + j) + ", "; } ; } } out.println("\t\t" + word + ",\t//\t" + comment); } out.println("//"); out.println("//\t" + iftableAddress + ": " + clazz.getClassName() + " interface table"); out.println("//"); if (!clazz.isInterface()) { out.println("//\tTODO: is it enough to use methodId as key???"); out.println("//"); for (i = 0; i < listIT.size(); ++i) { IT it = (IT) listIT.get(i); int j; for (j = 0; j < clvt.len; j++) { if (clvt.key[j].equals(it.key)) { break; } } if (j != clvt.len) { out.print("\t\t" + (methodsAddress + j * ClassStructConstants.METH_STR) + ","); } else { out.print("\t\t" + 0 + ",\t"); } out.println("\t//\t" + it.meth.methodId); } } } }