diff --git a/jode/ChangeLog b/jode/ChangeLog index 67c67a2..c7871b1 100644 --- a/jode/ChangeLog +++ b/jode/ChangeLog @@ -1,3 +1,28 @@ +2004-08-05 Jochen Hoenicke + + * build.xml: replace execon with apply. + * src/net/sf/jode/bytecode/ClassInfo.java (readAttributes): + read in signature attribute (not yet published, though). + * src/net/sf/jode/bytecode/MethodInfo.java (readAttributes): + likewise. + * src/net/sf/jode/bytecode/FieldInfo.java (readAttributes): + likewise. + * src/net/sf/jode/bytecode/ClassInfo.java (mergeModifiers): + only check the traditional modifiers for equality. + * src/net/sf/jode/bytecode/ConstantPool.java (getConstant): + Support for CLASS constants (jdk1.5) added. + * src/net/sf/jode/bytecode/BasicBlockReader.java (readCode): + opc_ldc, opc_ldc_w: Support for CLASS constants added. + * src/net/sf/jode/decompiler/Opcodes.java (addOpcode): + likewise. + * src/net/sf/jode/expr/InvokeOperator.java + (simplifyStringBuffer, simplifyString): + Also handle StringBuilder (jdk1.5). + * src/net/sf/jode/type/Type.java (tStringBuilder): new field. + * src/net/sf/jode/swingui/Main.java (main): handle debug + options. + + 2004-01-31 Jochen Hoenicke * src/net/sf/jode/jvm/SyntheticAnalyzer.java (checkGetClass): diff --git a/jode/build.xml b/jode/build.xml index 1daddd1..a2b3bd5 100644 --- a/jode/build.xml +++ b/jode/build.xml @@ -67,25 +67,25 @@ - + - + - + - + diff --git a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java index eff49f4..4a4cad1 100644 --- a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java +++ b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java @@ -544,7 +544,7 @@ class BasicBlockReader implements Opcodes { case opc_ldc: { int index = input.readUnsignedByte(); int tag = cp.getTag(index); - if (tag != cp.STRING + if (tag != cp.STRING && tag != cp.CLASS && tag != cp.INTEGER && tag != cp.FLOAT) throw new ClassFormatException ("wrong constant tag: "+tag); @@ -556,7 +556,7 @@ class BasicBlockReader implements Opcodes { case opc_ldc_w: { int index = input.readUnsignedShort(); int tag = cp.getTag(index); - if (tag != cp.STRING + if (tag != cp.STRING && tag != cp.CLASS && tag != cp.INTEGER && tag != cp.FLOAT) throw new ClassFormatException ("wrong constant tag: "+tag); diff --git a/jode/src/net/sf/jode/bytecode/ClassInfo.java b/jode/src/net/sf/jode/bytecode/ClassInfo.java index 4152931..b6706e1 100644 --- a/jode/src/net/sf/jode/bytecode/ClassInfo.java +++ b/jode/src/net/sf/jode/bytecode/ClassInfo.java @@ -252,6 +252,11 @@ public final class ClassInfo extends BinaryInfo implements Comparable { private MethodInfo[] methods; private String sourceFile; private boolean hasInnerClassesAttr; + + /** + * The type signature that also contains template information. + */ + private String signature; private final static ClassInfo[] EMPTY_INNER = new ClassInfo[0]; @@ -394,7 +399,8 @@ public final class ClassInfo extends BinaryInfo implements Comparable { /****** READING CLASS FILES ***************************************/ - private static int javaModifiersToBytecode(int javaModifiers) { + private static int javaModifiersToBytecode(int javaModifiers) + { int modifiers = javaModifiers & (Modifier.FINAL | 0x20 /*ACC_SUPER*/ | Modifier.INTERFACE @@ -406,7 +412,9 @@ public final class ClassInfo extends BinaryInfo implements Comparable { return modifiers; } - private void mergeModifiers(int newModifiers) { + private void mergeModifiers(int newModifiers) + throws ClassFormatException + { if (modifiers == -1) { modifiers = newModifiers; return; @@ -417,18 +425,18 @@ public final class ClassInfo extends BinaryInfo implements Comparable { } int oldSimple = javaModifiersToBytecode(modifiers); - if (((oldSimple ^ newModifiers) & ~0x20) == 0) { + if (((oldSimple ^ newModifiers) & 0xfdf) == 0) { modifiers |= newModifiers & 0x20; return; } int newSimple = javaModifiersToBytecode(newModifiers); - if (((newSimple ^ modifiers) & ~0x20) == 0) { + if (((newSimple ^ modifiers) & 0xfdf) == 0) { modifiers = newModifiers | (modifiers & 0x20); return; } - throw new ClassFormatError + throw new ClassFormatException ("modifiers in InnerClass info doesn't match: " + modifiers + "<->" + newModifiers); } @@ -566,6 +574,8 @@ public final class ClassInfo extends BinaryInfo implements Comparable { if (length != 0) throw new ClassFormatException ("Deprecated attribute has wrong length"); + } else if (name.equals("Signature")) { + signature = cp.getUTF8(input.readUnsignedShort()); } else super.readAttribute(name, length, cp, input, howMuch); } diff --git a/jode/src/net/sf/jode/bytecode/ConstantPool.java b/jode/src/net/sf/jode/bytecode/ConstantPool.java index 843ce73..0560cfb 100644 --- a/jode/src/net/sf/jode/bytecode/ConstantPool.java +++ b/jode/src/net/sf/jode/bytecode/ConstantPool.java @@ -151,12 +151,15 @@ public class ConstantPool { if (i == 0) throw new ClassFormatException("null constant"); switch (tags[i]) { - case ConstantPool.INTEGER: - case ConstantPool.FLOAT: - case ConstantPool.LONG: - case ConstantPool.DOUBLE: + case INTEGER: + case FLOAT: + case LONG: + case DOUBLE: return constants[i]; - case ConstantPool.STRING: + case CLASS: + return Reference.getReference(getClassType(i), + "class", "Ljava/lang/Class;"); + case STRING: return getUTF8(indices1[i]); } throw new ClassFormatException("Tag mismatch: "+tags[i]); diff --git a/jode/src/net/sf/jode/bytecode/FieldInfo.java b/jode/src/net/sf/jode/bytecode/FieldInfo.java index d643282..a9e829f 100644 --- a/jode/src/net/sf/jode/bytecode/FieldInfo.java +++ b/jode/src/net/sf/jode/bytecode/FieldInfo.java @@ -67,6 +67,10 @@ public final class FieldInfo extends BinaryInfo implements Comparable { Object constant; boolean syntheticFlag; boolean deprecatedFlag; + /** + * The type signature that also contains template information. + */ + private String signature; /** * Creates a new empty field info. @@ -109,6 +113,8 @@ public final class FieldInfo extends BinaryInfo implements Comparable { if (length != 0) throw new ClassFormatException ("Deprecated attribute has wrong length"); + } else if (name.equals("Signature")) { + signature = cp.getUTF8(input.readUnsignedShort()); } else super.readAttribute(name, length, cp, input, howMuch); } diff --git a/jode/src/net/sf/jode/bytecode/MethodInfo.java b/jode/src/net/sf/jode/bytecode/MethodInfo.java index e2127e8..9684896 100644 --- a/jode/src/net/sf/jode/bytecode/MethodInfo.java +++ b/jode/src/net/sf/jode/bytecode/MethodInfo.java @@ -71,6 +71,10 @@ public final class MethodInfo extends BinaryInfo implements Comparable { String[] exceptions; boolean syntheticFlag; boolean deprecatedFlag; + /** + * The type signature that also contains template information. + */ + private String signature; public MethodInfo() { } @@ -106,6 +110,8 @@ public final class MethodInfo extends BinaryInfo implements Comparable { if (length != 0) throw new ClassFormatException ("Deprecated attribute has wrong length"); + } else if (name.equals("Signature")) { + signature = cp.getUTF8(input.readUnsignedShort()); } else super.readAttribute(name, length, cp, input, howMuch); } diff --git a/jode/src/net/sf/jode/decompiler/Opcodes.java b/jode/src/net/sf/jode/decompiler/Opcodes.java index c3ed904..6130dcc 100644 --- a/jode/src/net/sf/jode/decompiler/Opcodes.java +++ b/jode/src/net/sf/jode/decompiler/Opcodes.java @@ -147,9 +147,17 @@ public abstract class Opcodes implements net.sf.jode.bytecode.Opcodes { break; case opc_ldc: case opc_ldc2_w: - flow.appendBlock - (createNormal(ma, instr, - new ConstOperator(instr.getConstant()))); + { + Expression expr; + if (instr.getConstant() instanceof Reference) { + Reference ref = (Reference) instr.getConstant(); + expr = new ClassFieldOperator + (Type.tType(cp, ref.getClazz())); + } else { + expr = new ConstOperator(instr.getConstant()); + } + flow.appendBlock(createNormal(ma, instr, expr)); + } break; case opc_iload: case opc_lload: case opc_fload: case opc_dload: case opc_aload: { diff --git a/jode/src/net/sf/jode/expr/InvokeOperator.java b/jode/src/net/sf/jode/expr/InvokeOperator.java index 7464803..e85cc98 100644 --- a/jode/src/net/sf/jode/expr/InvokeOperator.java +++ b/jode/src/net/sf/jode/expr/InvokeOperator.java @@ -517,7 +517,8 @@ public final class InvokeOperator extends Operator } public Expression simplifyStringBuffer() { - if (getClassType().equals(Type.tStringBuffer)) { + if (getClassType().equals(Type.tStringBuffer) + || getClassType().equals(Type.tStringBuilder)) { if (isConstructor() && subExpressions[0] instanceof NewOperator) { if (methodType.getParameterTypes().length == 0) @@ -548,7 +549,7 @@ public final class InvokeOperator extends Operator Expression secondOp = subExpressions[1]; Type[] paramTypes = new Type[] { - Type.tStringBuffer, secondOp.getType().getCanonic() + getClassType(), secondOp.getType().getCanonic() }; if (needsCast(1, paramTypes)) { Type castType = methodType.getParameterTypes()[0]; @@ -568,7 +569,8 @@ public final class InvokeOperator extends Operator public Expression simplifyString() { if (getMethodName().equals("toString") && !isStatic() - && getClassType().equals(Type.tStringBuffer) + && (getClassType().equals(Type.tStringBuffer) + || getClassType().equals(Type.tStringBuilder)) && subExpressions.length == 1) { Expression simple = subExpressions[0].simplifyStringBuffer(); if (simple != null) diff --git a/jode/src/net/sf/jode/swingui/Main.java b/jode/src/net/sf/jode/swingui/Main.java index 7468c95..56ecd50 100644 --- a/jode/src/net/sf/jode/swingui/Main.java +++ b/jode/src/net/sf/jode/swingui/Main.java @@ -436,7 +436,11 @@ public class Main || params[i].equals("--cp") || params[i].equals("-c")) cp = params[++i]; - else if (params[i].startsWith("-")) { + else if (params[i].equals("--debug") + || params[i].equals("--D")) { + String arg = params[++i]; + GlobalOptions.setDebugging(arg); + } else if (params[i].startsWith("-")) { if (!params[i].equals("--help") && !params[i].equals("-h")) System.err.println("Unknown option: "+params[i]); diff --git a/jode/src/net/sf/jode/type/Type.java b/jode/src/net/sf/jode/type/Type.java index 80270fb..b42a340 100644 --- a/jode/src/net/sf/jode/type/Type.java +++ b/jode/src/net/sf/jode/type/Type.java @@ -192,6 +192,14 @@ public class Type { tSystemClass("java.lang.StringBuffer", tObject, new ClassType[] { tSerializable }, true, false); + /** + * This type represents the singleton set containing + * java.lang.StringBuffer. + */ + public static final SystemClassType tStringBuilder = + tSystemClass("java.lang.StringBuilder", + tObject, new ClassType[] { tSerializable }, + true, false); /** * This type represents the singleton set containing * java.lang.Class.