/** * Constructor. * * @param code The {@link Code} attribute being decompiled. */ public Frame(Code code) { operandStack = new Stack<String>(); localVars = new LocalVarInfo[code.getMaxLocals()]; int i = 0; MethodInfo mi = code.getMethodInfo(); // Instance methods have an implicit first parameter of "this". if (!mi.isStatic()) { localVars[i++] = new LocalVarInfo("this", true); } // Name the passed-in local vars by their types. longs and doubles // take up two slots. String[] paramTypes = mi.getParameterTypes(); for (int param_i = 0; param_i < paramTypes.length; param_i++) { String type = paramTypes[param_i]; if (type.indexOf('.') > -1) { // Class types. type = type.substring(type.lastIndexOf('.') + 1); } String name = "localVar_" + type + "_" + param_i; localVars[i] = new LocalVarInfo(name, true); i++; if ("long".equals(type) || "double".equals(type)) { i++; // longs and doubles take up two slots. } } // NOTE: Other local vars will still be "null" here! We need to // infer their types from their usage during disassembly/decompilation. System.out.println("NOTE: " + (localVars.length - i) + " unknown localVars slots"); }
/** * Reads a <code>MethodInfo</code> from an input stream. * * @param cf The class file defining the method. * @param in The input stream to read from. * @return The method information read. * @throws IOException If an IO error occurs. */ public static MethodInfo read(ClassFile cf, DataInputStream in) throws IOException { int accessFlags = in.readUnsignedShort(); int nameIndex = in.readUnsignedShort(); int descriptorIndex = in.readUnsignedShort(); MethodInfo mi = new MethodInfo(cf, accessFlags, nameIndex, descriptorIndex); int attrCount = in.readUnsignedShort(); for (int j = 0; j < attrCount; j++) { AttributeInfo ai = mi.readAttribute(in); if (ai instanceof Signature) { mi.signatureAttr = (Signature) ai; } else if (ai instanceof Code) { mi.codeAttr = (Code) ai; } else if (ai != null) { mi.addAttribute(ai); } } return mi; }