/** * 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"); }
/** * If debugging was enabled during compilation, this method returns the name of the given * parameter to this method. Otherwise, <code>null</code> is returned. * * @param index The index of the parameter. * @return The name of the parameter, or <code>null</code>. */ public String getParameterName(int index) { if (index >= 0 && index < getParameterCount()) { if (codeAttr != null) { return codeAttr.getParameterName(index); } } return null; }
/** * Reads an attribute for this method from the specified input stream. * * @param in The input stream to read from. * @return The attribute read, possibly <code>null</code> if it was known to be unimportant for * our purposes. * @throws IOException If an IO error occurs. */ private AttributeInfo readAttribute(DataInputStream in) throws IOException { AttributeInfo ai = null; int attributeNameIndex = in.readUnsignedShort(); int attributeLength = in.readInt(); String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); if (CODE.equals(attrName)) { // 4.7.3 ai = Code.read(this, in); } else if (EXCEPTIONS.equals(attrName)) { // 4.7.4 int exceptionCount = in.readUnsignedShort(); int[] exceptionIndexTable = null; if (exceptionCount > 0) { exceptionIndexTable = new int[exceptionCount]; for (int i = 0; i < exceptionCount; i++) { exceptionIndexTable[i] = in.readUnsignedShort(); } } Exceptions e = new Exceptions(this, exceptionIndexTable); ai = e; } // TODO: Handle other Attribute types. // Attributes common to all members, or unhandled attributes. else { ai = super.readAttribute(in, attrName, attributeLength); // if (ai!=null) { // "Deprecated" attribute returns null // System.out.println("-------------- " + ai.getName()); // } } return ai; }