diff --git a/jode/jode/bytecode/Opcodes.java b/jode/jode/bytecode/Opcodes.java index 0cfbe5c..6b4bd73 100644 --- a/jode/jode/bytecode/Opcodes.java +++ b/jode/jode/bytecode/Opcodes.java @@ -28,23 +28,27 @@ import sun.tools.java.*; */ public abstract class Opcodes implements RuntimeConstants { - public final static Type ALL_INT_TYPE = MyType.tUInt; - public final static Type INT_TYPE = Type.tInt; - public final static Type LONG_TYPE = Type.tLong; - public final static Type FLOAT_TYPE = Type.tFloat; - public final static Type DOUBLE_TYPE = Type.tDouble; - public final static Type OBJECT_TYPE = MyType.tUObject; - public final static Type BOOLEAN_TYPE = Type.tBoolean; - public final static Type BYTE_TYPE = Type.tByte; - public final static Type CHAR_TYPE = Type.tChar; - public final static Type SHORT_TYPE = Type.tShort; - public final static Type VOID_TYPE = Type.tVoid; + public final static Type ALL_INT_TYPE = Type.tUInt; + public final static Type BOOL_INT_TYPE = Type.tBoolInt; + public final static Type INT_TYPE = Type.tInt; + public final static Type LONG_TYPE = Type.tLong; + public final static Type FLOAT_TYPE = Type.tFloat; + public final static Type DOUBLE_TYPE = Type.tDouble; + public final static Type OBJECT_TYPE = Type.tUObject; + public final static Type BOOLEAN_TYPE = Type.tBoolean; + public final static Type BYTEBOOL_TYPE = Type.tBoolByte; + public final static Type BYTE_TYPE = Type.tByte; + public final static Type CHAR_TYPE = Type.tChar; + public final static Type SHORT_TYPE = Type.tShort; + public final static Type VOID_TYPE = Type.tVoid; public final static Type types[][] = { - { ALL_INT_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE, OBJECT_TYPE }, + {BOOL_INT_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE, OBJECT_TYPE }, { INT_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE, OBJECT_TYPE, - BYTE_TYPE, CHAR_TYPE, SHORT_TYPE } + BYTEBOOL_TYPE, CHAR_TYPE, SHORT_TYPE }, + { BYTE_TYPE, CHAR_TYPE, SHORT_TYPE }, + { ALL_INT_TYPE, LONG_TYPE, FLOAT_TYPE, DOUBLE_TYPE, OBJECT_TYPE } }; @@ -90,7 +94,7 @@ public abstract class Opcodes implements RuntimeConstants { int[] cases, int[] dests) { return new FlowBlock(ca, addr, length, - new SwitchBlock(new NopOperator(MyType.tInt), + new SwitchBlock(new NopOperator(Type.tInt), cases, dests)); } @@ -132,8 +136,11 @@ public abstract class Opcodes implements RuntimeConstants { case opc_aconst_null: return createNormal (ca, addr, 1, new ConstOperator(OBJECT_TYPE, "null")); - case opc_iconst_m1: - case opc_iconst_0: case opc_iconst_1: case opc_iconst_2: + case opc_iconst_0: case opc_iconst_1: + return createNormal + (ca, addr, 1, new ConstOperator + (Type.tBoolInt, Integer.toString(opcode - opc_iconst_0))); + case opc_iconst_m1: case opc_iconst_2: case opc_iconst_3: case opc_iconst_4: case opc_iconst_5: return createNormal (ca, addr, 1, new ConstOperator @@ -160,7 +167,8 @@ public abstract class Opcodes implements RuntimeConstants { case opc_sipush: return createNormal (ca, addr, 3, new ConstOperator - (ALL_INT_TYPE, Integer.toString(stream.readShort()))); + (Type.tRange(Type.tInt, Type.tShort), + Integer.toString(stream.readShort()))); case opc_ldc: { int index = stream.readUnsignedByte(); return createNormal @@ -242,25 +250,25 @@ public abstract class Opcodes implements RuntimeConstants { case opc_irem: case opc_lrem: case opc_frem: case opc_drem: return createNormal (ca, addr, 1, new BinaryOperator - (types[0][(opcode - opc_iadd)%4], + (types[3][(opcode - opc_iadd)%4], (opcode - opc_iadd)/4+Operator.ADD_OP)); case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg: return createNormal (ca, addr, 1, new UnaryOperator - (types[0][opcode - opc_ineg], Operator.NEG_OP)); + (types[3][opcode - opc_ineg], Operator.NEG_OP)); case opc_ishl: case opc_lshl: case opc_ishr: case opc_lshr: case opc_iushr: case opc_lushr: return createNormal (ca, addr, 1, new ShiftOperator - (types[0][(opcode - opc_ishl)%2], + (types[3][(opcode - opc_ishl)%2], (opcode - opc_ishl)/2 + Operator.SHIFT_OP)); case opc_iand: case opc_land: case opc_ior : case opc_lor : case opc_ixor: case opc_lxor: return createNormal (ca, addr, 1, new BinaryOperator - (types[0][(opcode - opc_iand)%2], + (types[3][(opcode - opc_iand)%2], (opcode - opc_iand)/2 + Operator.AND_OP)); case opc_iinc: { int local = stream.readUnsignedByte(); @@ -271,6 +279,7 @@ public abstract class Opcodes implements RuntimeConstants { operation = Operator.NEG_OP; } LocalInfo li = ca.getLocalInfo(addr, local); + li.setType(ALL_INT_TYPE); return createNormal (ca, addr, 3, new IIncOperator (li, Integer.toString(value), @@ -285,36 +294,48 @@ public abstract class Opcodes implements RuntimeConstants { if (to >= from) to++; return createNormal - (ca, addr, 1, new ConvertOperator(types[0][from], - types[0][to])); + (ca, addr, 1, new ConvertOperator(types[3][from], + types[3][to])); } case opc_i2b: case opc_i2c: case opc_i2s: return createNormal (ca, addr, 1, new ConvertOperator - (ALL_INT_TYPE, types[1][(opcode-opc_i2b)+5])); + (ALL_INT_TYPE, types[2][opcode-opc_i2b])); case opc_lcmp: case opc_fcmpl: case opc_fcmpg: case opc_dcmpl: case opc_dcmpg: return createNormal (ca, addr, 1, new CompareToIntOperator - (types[0][(opcode-opc_lcmp+3)/2], (opcode-opc_lcmp+3)%2)); + (types[3][(opcode-opc_lcmp+3)/2], (opcode-opc_lcmp+3)%2)); case opc_ifeq: case opc_ifne: + return createIfGoto + (ca, addr, 3, addr+stream.readShort(), + new CompareUnaryOperator + (BOOL_INT_TYPE, opcode - opc_ifeq+Operator.COMPARE_OP)); case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: return createIfGoto (ca, addr, 3, addr+stream.readShort(), new CompareUnaryOperator (ALL_INT_TYPE, opcode - opc_ifeq+Operator.COMPARE_OP)); - case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt: - case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple: + case opc_if_icmpeq: case opc_if_icmpne: + return createIfGoto + (ca, addr, 3, addr+stream.readShort(), + new CompareBinaryOperator + (Type.tBoolInt, + opcode - opc_if_icmpeq+Operator.COMPARE_OP)); + case opc_if_icmplt: case opc_if_icmpge: + case opc_if_icmpgt: case opc_if_icmple: return createIfGoto (ca, addr, 3, addr+stream.readShort(), new CompareBinaryOperator - (ALL_INT_TYPE, opcode - opc_if_icmpeq+Operator.COMPARE_OP)); + (ALL_INT_TYPE, + opcode - opc_if_icmpeq+Operator.COMPARE_OP)); case opc_if_acmpeq: case opc_if_acmpne: return createIfGoto (ca, addr, 3, addr+stream.readShort(), new CompareBinaryOperator - (OBJECT_TYPE, opcode - opc_if_acmpeq+Operator.COMPARE_OP)); + (OBJECT_TYPE, + opcode - opc_if_acmpeq+Operator.COMPARE_OP)); case opc_goto: return createGoto (ca, addr, 3, addr+stream.readShort()); @@ -360,9 +381,9 @@ public abstract class Opcodes implements RuntimeConstants { } case opc_ireturn: case opc_lreturn: case opc_freturn: case opc_dreturn: case opc_areturn: { - Type retType = MyType.tSubType(MyType.intersection - (ca.getMethod().mdef.getType().getReturnType(), - types[0][opcode-opc_ireturn])); + Type retType = + Type.tSubType(Type.tType(ca.getMethod().mdef.getType() + .getReturnType())); return createBlock (ca, addr, 1, new ReturnBlock(new NopOperator(retType))); } @@ -405,7 +426,7 @@ public abstract class Opcodes implements RuntimeConstants { case opc_new: { ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant(stream.readUnsignedShort()); - Type type = MyType.tClassOrArray(cldec.getName()); + Type type = Type.tClassOrArray(cldec.getName()); return createNormal (ca, addr, 3, new NewOperator(type, ca.env.getTypeString(type))); } @@ -425,17 +446,17 @@ public abstract class Opcodes implements RuntimeConstants { } return createNormal (ca, addr, 2, - new NewArrayOperator(MyType.tArray(type), + new NewArrayOperator(Type.tArray(type), type.toString(), 1)); } case opc_anewarray: { ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant (stream.readUnsignedShort()); Identifier ident = cldec.getName(); - Type type = MyType.tClassOrArray(cldec.getName()); + Type type = Type.tClassOrArray(cldec.getName()); return createNormal (ca, addr, 3, new NewArrayOperator - (MyType.tArray(type), ca.env.getTypeString(type),1)); + (Type.tArray(type), ca.env.getTypeString(type),1)); } case opc_arraylength: return createNormal @@ -443,11 +464,11 @@ public abstract class Opcodes implements RuntimeConstants { case opc_athrow: return createBlock (ca, addr, 1, - new ThrowBlock(new NopOperator(MyType.tUObject))); + new ThrowBlock(new NopOperator(Type.tUObject))); case opc_checkcast: { ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant (stream.readUnsignedShort()); - Type type = MyType.tClassOrArray(cldec.getName()); + Type type = Type.tClassOrArray(cldec.getName()); return createNormal (ca, addr, 3, new CheckCastOperator (type, ca.env.getTypeString(type))); @@ -455,17 +476,17 @@ public abstract class Opcodes implements RuntimeConstants { case opc_instanceof: { ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant (stream.readUnsignedShort()); - Type type = MyType.tClassOrArray(cldec.getName()); + Type type = Type.tClassOrArray(cldec.getName()); return createNormal (ca, addr, 3, new InstanceOfOperator(type, ca.env.getTypeString(type))); } case opc_monitorenter: return createNormal(ca, addr, 1, - new MonitorEnterOperator()); + new MonitorEnterOperator()); case opc_monitorexit: return createNormal(ca, addr, 1, - new MonitorExitOperator()); + new MonitorExitOperator()); case opc_wide: { switch (opcode=stream.readUnsignedByte()) { case opc_iload: case opc_lload: @@ -492,6 +513,7 @@ public abstract class Opcodes implements RuntimeConstants { operation = Operator.NEG_OP; } LocalInfo li = ca.getLocalInfo(addr, local); + li.setType(ALL_INT_TYPE); return createNormal (ca, addr, 6, new IIncOperator (li, Integer.toString(value), @@ -508,11 +530,11 @@ public abstract class Opcodes implements RuntimeConstants { case opc_multianewarray: { ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant (stream.readUnsignedShort()); - Type type = MyType.tClassOrArray(cldec.getName()); + Type type = Type.tClassOrArray(cldec.getName()); int dimension = stream.readUnsignedByte(); Type baseType = type; for (int i=0; i 0) writer.print(modif+" "); - writer.print(env.getTypeString(fdef.getType(), fdef.getName())); + writer.print(env.getTypeString(Type.tType(fdef.getType()), + fdef.getName())); byte[] attrib = ((BinaryField) fdef).getAttribute(Constants.idConstantValue); if (attrib != null) { diff --git a/jode/jode/decompiler/ImportHandler.java b/jode/jode/decompiler/ImportHandler.java index 4bd835d..6e39e08 100644 --- a/jode/jode/decompiler/ImportHandler.java +++ b/jode/jode/decompiler/ImportHandler.java @@ -29,7 +29,7 @@ public class JodeEnvironment extends LoadEnvironment { JodeEnvironment() { super(null); - MyType.setEnvironment(this); + Type.setEnvironment(this); path = new ClassPath(System.getProperty("java.class.path")); } @@ -65,7 +65,7 @@ public class JodeEnvironment extends LoadEnvironment { } public String getTypeString(Type type, Identifier name) { - return type.typeString(name.toString(), false, false); + return type.toString() + " " + name.toString(); } public ClassDefinition getClassDefinition() { diff --git a/jode/jode/decompiler/LocalInfo.java b/jode/jode/decompiler/LocalInfo.java index e075f41..c427038 100644 --- a/jode/jode/decompiler/LocalInfo.java +++ b/jode/jode/decompiler/LocalInfo.java @@ -18,7 +18,9 @@ */ package jode; -import sun.tools.java.*; +import sun.tools.java.Identifier; +import java.util.Enumeration; +import java.util.Vector; /** * The LocalInfo represents a local variable of a method. @@ -37,6 +39,7 @@ public class LocalInfo { private Identifier name; private Type type; private LocalInfo shadow; + private Vector operators = new Vector(); /* The current implementation may use very much stack. This * should be changed someday. @@ -50,10 +53,14 @@ public class LocalInfo { */ public LocalInfo(int slot) { name = null; - type = MyType.tUnknown; + type = Type.tUnknown; this.slot = slot; } + public void setOperator(LocalVarOperator operator) { + getLocalInfo().operators.addElement(operator); + } + /** * Combines the LocalInfo with another. This will make this * a shadow object to the other local info. That is all member @@ -70,10 +77,16 @@ public class LocalInfo { if (this != li) { shadow = li; li.setType(type); + java.util.Enumeration enum = operators.elements(); + while (enum.hasMoreElements()) { + shadow.operators.addElement(enum.nextElement()); + } + /* Clear unused fields, to allow garbage collection. */ type = null; name = null; + operators = null; } } } @@ -139,15 +152,14 @@ public class LocalInfo { * @return The new type of the local. */ public Type setType(Type newType) { - if (shadow != null) { - while (shadow.shadow != null) { - shadow = shadow.shadow; - } - return shadow.setType(newType); + LocalInfo li = getLocalInfo(); + newType = li.type.intersection(newType); + if (!li.type.equals(newType)) { + li.type = newType; + java.util.Enumeration enum = li.operators.elements(); + while (enum.hasMoreElements()) + ((LocalVarOperator)enum.nextElement()).updateType(); } - this.type = MyType.intersection(this.type, newType); - if (this.type == MyType.tError) - System.err.println("Type error in "+getName()); return this.type; } diff --git a/jode/jode/decompiler/LocalVariableRangeList.java b/jode/jode/decompiler/LocalVariableRangeList.java index b0cbfac..1c740c4 100644 --- a/jode/jode/decompiler/LocalVariableRangeList.java +++ b/jode/jode/decompiler/LocalVariableRangeList.java @@ -20,7 +20,7 @@ package jode; import sun.tools.java.*; -public class LocalVariableRangeList implements LocalVariable { +public class LocalVariableRangeList { class MyLocalInfo extends LocalInfo { int start; @@ -80,8 +80,4 @@ public class LocalVariableRangeList implements LocalVariable { public LocalInfo getInfo(int addr) { return find(addr); } - - public void combine(int addr1, int addr2) { - throw new AssertError("combine called on RangeList"); - } } diff --git a/jode/jode/decompiler/LocalVariableTable.java b/jode/jode/decompiler/LocalVariableTable.java index 36742c2..fe874e2 100644 --- a/jode/jode/decompiler/LocalVariableTable.java +++ b/jode/jode/decompiler/LocalVariableTable.java @@ -18,7 +18,7 @@ */ package jode; -import sun.tools.java.*; +import sun.tools.java.Identifier; import java.io.*; public class LocalVariableTable { @@ -57,7 +57,7 @@ public class LocalVariableTable { Identifier.lookup((String) env.getConstantPool(). getValue(name_i)), - env.getConstantPool().getType(desc_i)); + Type.tType(env.getConstantPool().getType(desc_i))); if (Decompiler.showLVT) System.err.println(""+env.getConstantPool().getValue(name_i) +": "+env.getConstantPool().getType(desc_i) diff --git a/jode/jode/decompiler/MethodAnalyzer.java b/jode/jode/decompiler/MethodAnalyzer.java index 7b07cae..99a585f 100644 --- a/jode/jode/decompiler/MethodAnalyzer.java +++ b/jode/jode/decompiler/MethodAnalyzer.java @@ -26,7 +26,6 @@ public class MethodAnalyzer implements Analyzer, Constants { FieldDefinition mdef; JodeEnvironment env; CodeAnalyzer code = null; - LocalVariableAnalyzer lva; public MethodAnalyzer(FieldDefinition fd, JodeEnvironment e) { @@ -38,8 +37,6 @@ public class MethodAnalyzer implements Analyzer, Constants { new BinaryCode(bytecode, env.getConstantPool(), env); -// lva = new LocalVariableAnalyzer(env, mdef, bc.getMaxLocals()); -// lva.read(bc); code = new CodeAnalyzer(this, bc, env); } } @@ -58,13 +55,15 @@ public class MethodAnalyzer implements Analyzer, Constants { int offset = 0; if (!mdef.isStatic()) { LocalInfo clazz = code.getParamInfo(0); - clazz.setType(mdef.getClassDefinition().getType()); + clazz.setType(Type.tClass(mdef.getClassDefinition() + .getName().toString())); clazz.setName(Constants.idThis); offset++; } - Type[] paramTypes = mdef.getType().getArgumentTypes(); + sun.tools.java.Type[] paramTypes = mdef.getType().getArgumentTypes(); for (int i=0; i< paramTypes.length; i++) - code.getParamInfo(offset+i).setType(paramTypes[i]); + code.getParamInfo(offset+i).setType + (Type.tType(paramTypes[i].getTypeSignature())); // We do the code.analyze() in dumpSource, to get // immediate output. @@ -91,20 +90,21 @@ public class MethodAnalyzer implements Analyzer, Constants { if (mdef.isConstructor()) writer.print(mdef.getClassDeclaration().getName().toString()); else - writer.print(env.getTypeString(mdef.getType().getReturnType())+ - " "+ mdef.getName().toString()); + writer.print(env.getTypeString + (Type.tType(mdef.getType().getReturnType())) + + " " + mdef.getName().toString()); writer.print("("); - Type[] paramTypes = mdef.getType().getArgumentTypes(); + sun.tools.java.Type[] paramTypes = + mdef.getType().getArgumentTypes(); int offset = mdef.isStatic()?0:1; for (int i=0; i0) writer.print(", "); writer.print ((code == null)? - env.getTypeString(paramTypes[i]): - env.getTypeString - (paramTypes[i], - code.getParamInfo(i+offset).getName())); + env.getTypeString(Type.tType(paramTypes[i])): + env.getTypeString(Type.tType(paramTypes[i]), + code.getParamInfo(i+offset).getName())); } writer.print(")"); } diff --git a/jode/jode/expr/ArrayLengthOperator.java b/jode/jode/expr/ArrayLengthOperator.java index a06085e..5414596 100644 --- a/jode/jode/expr/ArrayLengthOperator.java +++ b/jode/jode/expr/ArrayLengthOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.*; public class ArrayLengthOperator extends Operator { @@ -26,7 +25,7 @@ public class ArrayLengthOperator extends Operator { public ArrayLengthOperator() { super(Type.tInt, 0); - arrayType = Type.tArray(MyType.tUnknown); + arrayType = Type.tArray(Type.tUnknown); } public int getPriority() { @@ -46,7 +45,7 @@ public class ArrayLengthOperator extends Operator { } public void setOperandType(Type[] types) { - arrayType = MyType.intersection(arrayType,types[0]); + arrayType = arrayType.intersection(types[0]); } public String toString(String[] operands) { diff --git a/jode/jode/expr/ArrayLoadOperator.java b/jode/jode/expr/ArrayLoadOperator.java index 902416e..e1fe934 100644 --- a/jode/jode/expr/ArrayLoadOperator.java +++ b/jode/jode/expr/ArrayLoadOperator.java @@ -18,8 +18,6 @@ */ package jode; -import sun.tools.java.Type; -import sun.tools.java.ArrayType; public class ArrayLoadOperator extends SimpleOperator { String value; @@ -27,7 +25,7 @@ public class ArrayLoadOperator extends SimpleOperator { public ArrayLoadOperator(Type type) { super(type, 0, 2); operandTypes[0] = Type.tArray(type); - operandTypes[1] = MyType.tUIndex; + operandTypes[1] = Type.tInt; } public int getPriority() { @@ -42,7 +40,7 @@ public class ArrayLoadOperator extends SimpleOperator { * Sets the return type of this operator. */ public void setType(Type type) { - if (type != this.type) { + if (!type.equals(this.type)) { super.setType(type); operandTypes[0] = Type.tArray(type); } @@ -50,12 +48,11 @@ public class ArrayLoadOperator extends SimpleOperator { public void setOperandType(Type[] t) { super.setOperandType(t); - try { - type = operandTypes[0].getElementType(); - } catch (sun.tools.java.CompilerError err) { - System.err.println("No Array type: "+operandTypes[0]); - type = Type.tError; - } + if (operandTypes[0] instanceof ArrayType) + type = type.intersection + (((ArrayType)operandTypes[0]).getElementType()); + else + throw new AssertError("No Array type: "+operandTypes[0]); } public String toString(String[] operands) { diff --git a/jode/jode/expr/ArrayStoreOperator.java b/jode/jode/expr/ArrayStoreOperator.java index 65f792b..4f76de6 100644 --- a/jode/jode/expr/ArrayStoreOperator.java +++ b/jode/jode/expr/ArrayStoreOperator.java @@ -18,15 +18,13 @@ */ package jode; -import sun.tools.java.Type; -import sun.tools.java.ArrayType; public class ArrayStoreOperator extends StoreInstruction { Type indexType; public ArrayStoreOperator(Type type, int operator) { super(type, operator); - indexType = MyType.tUIndex; + indexType = Type.tInt; } public ArrayStoreOperator(Type type) { @@ -66,15 +64,12 @@ public class ArrayStoreOperator extends StoreInstruction { } public void setLValueOperandType(Type[] t) { - indexType = MyType.intersection(indexType, t[1]); - Type arrayType = - MyType.intersection(t[0], Type.tArray(lvalueType)); - try { - lvalueType = arrayType.getElementType(); - } catch (sun.tools.java.CompilerError err) { - System.err.println("No Array type: "+arrayType); - lvalueType = Type.tError; - } + indexType = indexType.intersection(t[1]); + Type arrayType = t[0].intersection(Type.tArray(lvalueType)); + if (arrayType instanceof ArrayType) + lvalueType = ((ArrayType)arrayType).getElementType(); + else + throw new AssertError("No Array type: "+arrayType); } public String getLValueString(String[] operands) { diff --git a/jode/jode/expr/AssignOperator.java b/jode/jode/expr/AssignOperator.java index 003a013..e223beb 100644 --- a/jode/jode/expr/AssignOperator.java +++ b/jode/jode/expr/AssignOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class AssignOperator extends Operator { StoreInstruction store; diff --git a/jode/jode/expr/BinaryOperator.java b/jode/jode/expr/BinaryOperator.java index ff0b0ea..651dfef 100644 --- a/jode/jode/expr/BinaryOperator.java +++ b/jode/jode/expr/BinaryOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class BinaryOperator extends Operator { protected Type operandType; @@ -66,9 +65,9 @@ public class BinaryOperator extends Operator { } public void setOperandType(Type[] inputTypes) { - operandType = MyType.intersection - (operandType, MyType.intersection(inputTypes[0], - inputTypes[1])); + operandType = operandType + .intersection(inputTypes[0]) + .intersection(inputTypes[1]); type = operandType; } @@ -76,7 +75,7 @@ public class BinaryOperator extends Operator { * Sets the return type of this operator. */ public void setType(Type newType) { - type = operandType = MyType.intersection(operandType, newType); + type = operandType = operandType.intersection(newType); } public boolean equals(Object o) { diff --git a/jode/jode/expr/CheckCastOperator.java b/jode/jode/expr/CheckCastOperator.java index 898c51e..4523161 100644 --- a/jode/jode/expr/CheckCastOperator.java +++ b/jode/jode/expr/CheckCastOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class CheckCastOperator extends SimpleOperator { String typeString; @@ -37,7 +36,7 @@ public class CheckCastOperator extends SimpleOperator { * * The forgiving solution: */ - operandTypes[0] = MyType.tUnknown; + operandTypes[0] = Type.tUnknown; } public int getPriority() { diff --git a/jode/jode/expr/CompareBinaryOperator.java b/jode/jode/expr/CompareBinaryOperator.java index e95b695..a6c2e17 100644 --- a/jode/jode/expr/CompareBinaryOperator.java +++ b/jode/jode/expr/CompareBinaryOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class CompareBinaryOperator extends SimpleOperator { public CompareBinaryOperator(Type type, int op) { @@ -47,9 +46,8 @@ public class CompareBinaryOperator extends SimpleOperator { public void setOperandType(Type[] inputTypes) { super.setOperandType(inputTypes); Type operandType = - MyType.tSubType(MyType.intersection - (MyType.tSuperType(operandTypes[0]), - MyType.tSuperType(operandTypes[1]))); + Type.tSubType(Type.tSuperType(operandTypes[0]) + .intersection(Type.tSuperType(operandTypes[1]))); operandTypes[0] = operandTypes[1] = operandType; } diff --git a/jode/jode/expr/CompareToIntOperator.java b/jode/jode/expr/CompareToIntOperator.java index 80f4512..37d1f01 100644 --- a/jode/jode/expr/CompareToIntOperator.java +++ b/jode/jode/expr/CompareToIntOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class CompareToIntOperator extends SimpleOperator { public CompareToIntOperator(Type type, int lessGreater) { @@ -36,8 +35,7 @@ public class CompareToIntOperator extends SimpleOperator { public void setOperandType(Type[] inputTypes) { super.setOperandType(inputTypes); - Type operandType = - MyType.intersection(operandTypes[0],operandTypes[1]); + Type operandType = operandTypes[0].intersection(operandTypes[1]); operandTypes[0] = operandTypes[1] = operandType; } diff --git a/jode/jode/expr/CompareUnaryOperator.java b/jode/jode/expr/CompareUnaryOperator.java index 73181a5..896fed1 100644 --- a/jode/jode/expr/CompareUnaryOperator.java +++ b/jode/jode/expr/CompareUnaryOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class CompareUnaryOperator extends SimpleOperator { boolean objectType; @@ -26,7 +25,7 @@ public class CompareUnaryOperator extends SimpleOperator { public CompareUnaryOperator(Type type, int op) { super(Type.tBoolean, op, 1); operandTypes[0] = type; - objectType = (type == MyType.tUObject); + objectType = (type == Type.tUObject); } public int getPriority() { diff --git a/jode/jode/expr/ComplexExpression.java b/jode/jode/expr/ComplexExpression.java index a401cf5..1c8cccf 100644 --- a/jode/jode/expr/ComplexExpression.java +++ b/jode/jode/expr/ComplexExpression.java @@ -18,17 +18,16 @@ */ package jode; -import sun.tools.java.Type; import sun.tools.java.Constants; -import sun.tools.java.FieldDefinition; public class ComplexExpression extends Expression { Operator operator; Expression[] subExpressions; public ComplexExpression(Operator op, Expression[] sub) { - super(MyType.tUnknown); + super(Type.tUnknown); operator = op; + operator.parent = this; subExpressions = sub; operator.setExpression(this); if (subExpressions.length != op.getOperandCount()) @@ -122,9 +121,21 @@ public class ComplexExpression extends Expression { } } + public void updateType() { + updateSubTypes(); + if (subExpressions.length > 0) { + Type types[] = new Type[subExpressions.length]; + for (int i=0; i < types.length; i++) { + types[i] = subExpressions[i].getType(); + } + operator.setOperandType(types); + } + setType(operator.getType()); + } + public void setType(Type newType) { - newType = MyType.intersection(type, newType); - if (newType != type) { + newType = type.intersection(newType); + if (!newType.equals(type)) { type = newType; operator.setType(type); updateSubTypes(); @@ -143,8 +154,8 @@ public class ComplexExpression extends Expression { } String result = operator.toString(expr); if (Decompiler.isTypeDebugging) - result = "(("+operator.getType()+")"+result+")"; - else if (operator.getType() == MyType.tError) + result = "("+operator.getType()+") ("+result+")"; + else if (operator.getType() == Type.tError) result = "(/*type error */" + result+")"; return result; } @@ -170,12 +181,12 @@ public class ComplexExpression extends Expression { new EmptyStringOperator(); Expression simplifyStringBuffer() { - FieldDefinition field; + sun.tools.java.FieldDefinition field; if (operator instanceof InvokeOperator && (field = ((InvokeOperator)operator).getField()) - .getClassDefinition().getName() == - Constants.idJavaLangStringBuffer && - !((InvokeOperator)operator).isStatic() && + .getClassDefinition().getName() + == Constants.idJavaLangStringBuffer + && !((InvokeOperator)operator).isStatic() && field.getName() == Constants.idAppend && field.getType().getArgumentTypes().length == 1) { @@ -184,7 +195,7 @@ public class ComplexExpression extends Expression { return null; if (e.getOperator() instanceof EmptyStringOperator && - MyType.isOfType(subExpressions[1].getType(), Type.tString)) + subExpressions[1].getType().isOfType(Type.tString)) return subExpressions[1]; Expression[] exprs = { e, @@ -192,13 +203,12 @@ public class ComplexExpression extends Expression { return new ComplexExpression(new StringAddOperator(), exprs); } if (operator instanceof ConstructorOperator && - MyType.isOfType(operator.getType(), MyType.tStringBuffer)) { + operator.getType().isOfType(Type.tStringBuffer)) { /* subExpressions[0] is always a "new StringBuffer" */ if (subExpressions.length == 1) return emptyString; else if (subExpressions.length == 2 && - MyType.isOfType(subExpressions[1].getType(), - MyType.tString)) + subExpressions[1].getType().isOfType(Type.tString)) return (Expression) subExpressions[1].simplify(); } return null; @@ -206,7 +216,7 @@ public class ComplexExpression extends Expression { public Instruction simplify() { if (operator instanceof IfThenElseOperator && - operator.getType() == Type.tBoolean) { + operator.getType().isOfType(Type.tBoolean)) { if (subExpressions[1].getOperator() instanceof ConstOperator && subExpressions[2].getOperator() instanceof ConstOperator) { ConstOperator c1 = @@ -267,18 +277,7 @@ public class ComplexExpression extends Expression { return newOp.simplify(); } if (operator instanceof CompareUnaryOperator && - operator.getOperandType(0) != Type.tBoolean) { - if (subExpressions[0].getOperator() instanceof ConstOperator) { - ConstOperator c = - (ConstOperator) subExpressions[0].getOperator(); - if (c.getValue().equals("0") || c.getValue().equals("1")) { - Type[] newType = {Type.tBoolean}; - operator.setOperandType(newType); - } - } - } - if (operator instanceof CompareUnaryOperator && - operator.getOperandType(0) == Type.tBoolean) { + operator.getOperandType(0).isOfType(Type.tBoolean)) { /* xx == false */ if (operator.getOperatorIndex() == operator.EQUALS_OP) return subExpressions[0].negate().simplify(); @@ -288,24 +287,26 @@ public class ComplexExpression extends Expression { } if (operator instanceof InvokeOperator && - ((InvokeOperator)operator).getField(). - getName() == Constants.idToString && + ((InvokeOperator)operator).getField() + .getName() == Constants.idToString && !((InvokeOperator)operator).isStatic() && - ((InvokeOperator)operator).getField(). - getClassDefinition().getType() == MyType.tStringBuffer && + ((InvokeOperator)operator).getField() + .getClassDefinition().getName() + == Constants.idJavaLangStringBuffer && subExpressions.length == 1) { Instruction simple = subExpressions[0].simplifyStringBuffer(); if (simple != null) return simple; } if (operator instanceof InvokeOperator && - ((InvokeOperator)operator).getField(). - getName() == Constants.idValueOf && + ((InvokeOperator)operator).getField() + .getName() == Constants.idValueOf && ((InvokeOperator)operator).isStatic() && - ((InvokeOperator)operator).getField(). - getClassDefinition().getType() == MyType.tString && + ((InvokeOperator)operator).getField() + .getClassDefinition().getName() + == Constants.idJavaLangString && subExpressions.length == 1) { - if (subExpressions[0].getType() == MyType.tString) + if (subExpressions[0].getType() == Type.tString) return subExpressions[0].simplify(); else { Expression[] exprs = { diff --git a/jode/jode/expr/ConstOperator.java b/jode/jode/expr/ConstOperator.java index f8f06a4..d0405a1 100644 --- a/jode/jode/expr/ConstOperator.java +++ b/jode/jode/expr/ConstOperator.java @@ -18,14 +18,13 @@ */ package jode; -import sun.tools.java.Type; public class ConstOperator extends NoArgOperator { String value; public ConstOperator(Type type, String value) { super(type); - if (type == MyType.tString) + if (type == Type.tString) value = quoted(value); this.value = value; } @@ -67,7 +66,7 @@ public class ConstOperator extends NoArgOperator { } public String toString(String[] operands) { - if (type == Type.tBoolean) { + if (type.isOfType(Type.tBoolean)) { if (value.equals("0")) return "false"; else if (value.equals("1")) diff --git a/jode/jode/expr/ConstantArrayOperator.java b/jode/jode/expr/ConstantArrayOperator.java index e053402..f1351e6 100644 --- a/jode/jode/expr/ConstantArrayOperator.java +++ b/jode/jode/expr/ConstantArrayOperator.java @@ -18,14 +18,13 @@ */ package jode; -import sun.tools.java.Type; public class ConstantArrayOperator extends SimpleOperator { public ConstantArrayOperator(Type type, int size) { super(type, 0, size); for (int i=0; i< size; i++) - operandTypes[i] = MyType.tSubType(type.getElementType()); + operandTypes[i] = Type.tSubType(((ArrayType)type).getElementType()); } public int getPriority() { diff --git a/jode/jode/expr/ConstructorOperator.java b/jode/jode/expr/ConstructorOperator.java index 3411877..074a482 100644 --- a/jode/jode/expr/ConstructorOperator.java +++ b/jode/jode/expr/ConstructorOperator.java @@ -18,7 +18,7 @@ */ package jode; -import sun.tools.java.*; +import sun.tools.java.FieldDefinition; public class ConstructorOperator extends Operator { FieldDefinition field; @@ -44,8 +44,10 @@ public class ConstructorOperator extends Operator { public Type getOperandType(int i) { if (i == 0) - return field.getClassDeclaration().getType(); // or subtype? XXX - return MyType.tSubType(field.getType().getArgumentTypes()[i-1]); + return Type.tSubType(Type.tClass(field.getClassDeclaration() + .getName().toString())); + return Type.tSubType(Type.tType(field.getType() + .getArgumentTypes()[i-1])); } public void setOperandType(Type types[]) { diff --git a/jode/jode/expr/ConvertOperator.java b/jode/jode/expr/ConvertOperator.java index c33d806..835bf29 100644 --- a/jode/jode/expr/ConvertOperator.java +++ b/jode/jode/expr/ConvertOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class ConvertOperator extends Operator { Type from; @@ -45,7 +44,7 @@ public class ConvertOperator extends Operator { } public void setOperandType(Type[] inputTypes) { - from = MyType.intersection(from, inputTypes[0]); + from = from.intersection(inputTypes[0]); } public String toString(String[] operands) diff --git a/jode/jode/expr/DupOperator.java b/jode/jode/expr/DupOperator.java index 9a7fcfb..924e95f 100644 --- a/jode/jode/expr/DupOperator.java +++ b/jode/jode/expr/DupOperator.java @@ -18,13 +18,12 @@ */ package jode; -import sun.tools.java.Type; public class DupOperator extends Instruction { int count, depth; public DupOperator(int depth, int count) { - super(MyType.tUnknown); + super(Type.tUnknown); this.count = count; this.depth = depth; } diff --git a/jode/jode/expr/EmptyStringOperator.java b/jode/jode/expr/EmptyStringOperator.java index 1fff198..3b78879 100644 --- a/jode/jode/expr/EmptyStringOperator.java +++ b/jode/jode/expr/EmptyStringOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class EmptyStringOperator extends NoArgOperator { diff --git a/jode/jode/expr/Expression.java b/jode/jode/expr/Expression.java index 7d246d4..1c577be 100644 --- a/jode/jode/expr/Expression.java +++ b/jode/jode/expr/Expression.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class Expression extends Instruction { diff --git a/jode/jode/expr/GetFieldOperator.java b/jode/jode/expr/GetFieldOperator.java index 63d3a12..46f60c5 100644 --- a/jode/jode/expr/GetFieldOperator.java +++ b/jode/jode/expr/GetFieldOperator.java @@ -27,7 +27,7 @@ public class GetFieldOperator extends Operator { public GetFieldOperator(CodeAnalyzer codeAnalyzer, boolean staticFlag, FieldDefinition field) { - super(field.getType(), 0); + super(Type.tType(field.getType()), 0); this.codeAnalyzer = codeAnalyzer; this.staticFlag = staticFlag; this.field = field; @@ -54,7 +54,8 @@ public class GetFieldOperator extends Operator { /* shouldn't be called */ throw new RuntimeException("Field is static"); } - return MyType.tSubType(field.getClassDeclaration().getType()); + return Type.tSubType(Type.tClass(field.getClassDeclaration() + .getName().toString())); } public void setOperandType(Type types[]) { @@ -66,7 +67,9 @@ public class GetFieldOperator extends Operator { if (field.getClassDefinition() == codeAnalyzer.getClassDefinition()) return field.getName().toString(); object = - codeAnalyzer.getTypeString(field.getClassDeclaration().getType()); + codeAnalyzer.getTypeString + (Type.tClass(field.getClassDeclaration() + .getName().toString())); } else { if (operands[0].equals("this")) return field.getName().toString(); diff --git a/jode/jode/expr/IIncOperator.java b/jode/jode/expr/IIncOperator.java index 7a6bb46..88ac98d 100644 --- a/jode/jode/expr/IIncOperator.java +++ b/jode/jode/expr/IIncOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class IIncOperator extends NoArgOperator implements LocalVarOperator { @@ -26,9 +25,10 @@ implements LocalVarOperator { LocalInfo local; public IIncOperator(LocalInfo local, String value, int operator) { - super(MyType.tVoid, operator); + super(Type.tVoid, operator); this.local = local; this.value = value; + local.setOperator(this); } public String getValue() { @@ -43,19 +43,15 @@ implements LocalVarOperator { return true; } -// public void setLocalInfo(LocalInfo local) { -// local.setType(MyType.tUIndex); -// this.local = local; -// } + public void updateType() { + if (parent != null) + parent.updateType(); + } public LocalInfo getLocalInfo() { return local; } -// public int getSlot() { -// return slot; -// } - public int getPriority() { return 100; } diff --git a/jode/jode/expr/IfThenElseOperator.java b/jode/jode/expr/IfThenElseOperator.java index 8638442..cb8074b 100644 --- a/jode/jode/expr/IfThenElseOperator.java +++ b/jode/jode/expr/IfThenElseOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class IfThenElseOperator extends SimpleOperator { public IfThenElseOperator(Type type) { @@ -50,7 +49,7 @@ public class IfThenElseOperator extends SimpleOperator { public void setOperandType(Type[] inputTypes) { super.setOperandType(inputTypes); Type operandType = - MyType.intersection(operandTypes[1],operandTypes[2]); + type.intersection(operandTypes[1]).intersection(operandTypes[2]); type = operandTypes[1] = operandTypes[2] = operandType; } @@ -60,8 +59,8 @@ public class IfThenElseOperator extends SimpleOperator { */ public void setType(Type newType) { Type operandType = - MyType.intersection(operandTypes[1], newType); - if (type != operandType) { + type.intersection(operandTypes[1]).intersection(newType); + if (!type.equals(operandType)) { type = operandTypes[1] = operandTypes[2] = operandType; } } diff --git a/jode/jode/expr/InstanceOfOperator.java b/jode/jode/expr/InstanceOfOperator.java index 8092f58..c5fb338 100644 --- a/jode/jode/expr/InstanceOfOperator.java +++ b/jode/jode/expr/InstanceOfOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class InstanceOfOperator extends SimpleOperator { String typeString; @@ -32,11 +31,11 @@ public class InstanceOfOperator extends SimpleOperator { * If operand is of class type, it is probably a * super type, but who knows? * - * this.operandTypes[0] = MyType.tSuperType(type); + * this.operandTypes[0] = Type.tSuperType(type); * * The forgiving solution: */ - this.operandTypes[0] = MyType.tUnknown; + this.operandTypes[0] = Type.tUnknown; this.typeString = typeString; } public int getOperandCount() { diff --git a/jode/jode/expr/Instruction.java b/jode/jode/expr/Instruction.java index 9a7e820..ac84945 100644 --- a/jode/jode/expr/Instruction.java +++ b/jode/jode/expr/Instruction.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class Instruction { protected Type type; diff --git a/jode/jode/expr/InvokeOperator.java b/jode/jode/expr/InvokeOperator.java index 165b9c0..6146457 100644 --- a/jode/jode/expr/InvokeOperator.java +++ b/jode/jode/expr/InvokeOperator.java @@ -29,7 +29,8 @@ public class InvokeOperator extends Operator { public InvokeOperator(CodeAnalyzer codeAnalyzer, boolean staticFlag, boolean specialFlag, FieldDefinition field) { - super(field.getType().getReturnType(), 0); + super(Type.tType(field.getType().getReturnType().getTypeSignature()), + 0); this.codeAnalyzer = codeAnalyzer; this.staticFlag = staticFlag; this.specialFlag = specialFlag; @@ -45,7 +46,7 @@ public class InvokeOperator extends Operator { } public Type getClassType() { - return field.getClassDeclaration().getType(); + return Type.tClass(field.getClassDeclaration().getName().toString()); } public int getPriority() { @@ -65,10 +66,12 @@ public class InvokeOperator extends Operator { public Type getOperandType(int i) { if (!staticFlag) { if (i == 0) - return MyType.tSubType(field.getClassDeclaration().getType()); + return Type.tSubType(getClassType()); i--; } - return MyType.tSubType(field.getType().getArgumentTypes()[i]); + return Type.tSubType(Type.tType(field.getType(). + getArgumentTypes()[i]. + getTypeSignature())); } public void setOperandType(Type types[]) { @@ -86,27 +89,26 @@ public class InvokeOperator extends Operator { object = ""; else object = codeAnalyzer. - getTypeString(field.getClassDeclaration().getType()); + getTypeString(getClassType()); } else { if (operands[arg].equals("this")) { - if (specialFlag && - (field.getClassDeclaration() == - codeAnalyzer.getClassDefinition().getSuperClass() || - (field.getClassDeclaration().getName() == - Constants.idJavaLangObject && - codeAnalyzer.getClassDefinition().getSuperClass() == null))) + if (specialFlag + && (field.getClassDeclaration() + == codeAnalyzer.getClassDefinition().getSuperClass())) +// || (field.getClassDeclaration().getName() +// == Constants.idJavaLangObject +// && codeAnalyzer.getClassDefinition() +// .getSuperClass() == null))) object = "super"; else if (specialFlag) - object = "(("+codeAnalyzer.getTypeString - (field.getClassDeclaration().getType())+ - ") this)"; + object = "(("+codeAnalyzer.getTypeString(getClassType()) + + ") this)"; else object = ""; } else { if (specialFlag) - object = "(("+codeAnalyzer.getTypeString - (field.getClassDeclaration().getType())+ - ") "+operands[arg]+")"; + object = "((" + codeAnalyzer.getTypeString(getClassType()) + + ") " + operands[arg]+")"; else object = operands[arg]; } diff --git a/jode/jode/expr/LocalLoadOperator.java b/jode/jode/expr/LocalLoadOperator.java index 45d95b4..8e4d9ed 100644 --- a/jode/jode/expr/LocalLoadOperator.java +++ b/jode/jode/expr/LocalLoadOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class LocalLoadOperator extends ConstOperator implements LocalVarOperator { @@ -27,6 +26,7 @@ implements LocalVarOperator { public LocalLoadOperator(Type type, LocalInfo local) { super(type, ""); this.local = local; + local.setOperator(this); } public boolean isRead() { @@ -46,6 +46,12 @@ implements LocalVarOperator { return local.getLocalInfo(); } + public void updateType() { + super.setType(local.getType()); + if (parent != null) + parent.updateType(); + } + public Type getType() { // System.err.println("LocalLoad.getType of "+local.getName()+": "+local.getType()); return local.getType(); diff --git a/jode/jode/expr/LocalPostFixOperator.java b/jode/jode/expr/LocalPostFixOperator.java index f02d06a..32b9b60 100644 --- a/jode/jode/expr/LocalPostFixOperator.java +++ b/jode/jode/expr/LocalPostFixOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class LocalPostFixOperator extends NoArgOperator { IIncOperator iinc; diff --git a/jode/jode/expr/LocalStoreOperator.java b/jode/jode/expr/LocalStoreOperator.java index bbae3a6..eceefdd 100644 --- a/jode/jode/expr/LocalStoreOperator.java +++ b/jode/jode/expr/LocalStoreOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class LocalStoreOperator extends StoreInstruction implements LocalVarOperator { @@ -27,6 +26,7 @@ implements LocalVarOperator { public LocalStoreOperator(Type lvalueType, LocalInfo local, int operator) { super(lvalueType, operator); this.local = local; + local.setOperator(this); } public boolean isRead() { @@ -37,6 +37,11 @@ implements LocalVarOperator { return true; } + public void updateType() { + if (parent != null) + parent.updateType(); + } + public LocalInfo getLocalInfo() { return local.getLocalInfo(); } @@ -49,7 +54,7 @@ implements LocalVarOperator { public boolean setLValueType(Type type) { // System.err.println("LocalStore.setType of "+local.getName()+": "+local.getType()); return super.setLValueType - (local.setType(MyType.tSuperType(type))); + (local.setType(Type.tSuperType(type))); } // public int getSlot() { diff --git a/jode/jode/expr/LocalVarOperator.java b/jode/jode/expr/LocalVarOperator.java index d965ce7..8e1df34 100644 --- a/jode/jode/expr/LocalVarOperator.java +++ b/jode/jode/expr/LocalVarOperator.java @@ -22,9 +22,12 @@ package jode; public interface LocalVarOperator { public boolean isRead(); public boolean isWrite(); -// public int getSlot(); public LocalInfo getLocalInfo(); -// public void setLocalInfo(LocalInfo li); + /** + * This is called by the local info when the type + * of it changed + */ + public void updateType(); } diff --git a/jode/jode/expr/MonitorEnterOperator.java b/jode/jode/expr/MonitorEnterOperator.java index c3b344c..510fe58 100644 --- a/jode/jode/expr/MonitorEnterOperator.java +++ b/jode/jode/expr/MonitorEnterOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class MonitorEnterOperator extends SimpleOperator { public MonitorEnterOperator() { diff --git a/jode/jode/expr/MonitorExitOperator.java b/jode/jode/expr/MonitorExitOperator.java index 27d0e38..730f24b 100644 --- a/jode/jode/expr/MonitorExitOperator.java +++ b/jode/jode/expr/MonitorExitOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class MonitorExitOperator extends SimpleOperator { public MonitorExitOperator() { @@ -35,7 +34,7 @@ public class MonitorExitOperator extends SimpleOperator { } public Type getOperandType(int i) { - return MyType.tObject; + return Type.tObject; } public String toString(String[] operands) { diff --git a/jode/jode/expr/NewArrayOperator.java b/jode/jode/expr/NewArrayOperator.java index f119390..0c3654f 100644 --- a/jode/jode/expr/NewArrayOperator.java +++ b/jode/jode/expr/NewArrayOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class NewArrayOperator extends SimpleOperator { String baseTypeString; @@ -27,7 +26,7 @@ public class NewArrayOperator extends SimpleOperator { int dimensions) { super(arrayType, 0, dimensions); for (int i=0; i< dimensions; i++) { - operandTypes[i] = MyType.tUIndex; + operandTypes[i] = Type.tInt; } this.baseTypeString = baseTypeString; } diff --git a/jode/jode/expr/NewOperator.java b/jode/jode/expr/NewOperator.java index 60d3e87..9130a8b 100644 --- a/jode/jode/expr/NewOperator.java +++ b/jode/jode/expr/NewOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class NewOperator extends NoArgOperator { String typeString; diff --git a/jode/jode/expr/NoArgOperator.java b/jode/jode/expr/NoArgOperator.java index 422bcd3..b72dcca 100644 --- a/jode/jode/expr/NoArgOperator.java +++ b/jode/jode/expr/NoArgOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class NoArgOperator extends Operator { diff --git a/jode/jode/expr/NopOperator.java b/jode/jode/expr/NopOperator.java index 472edb3..400ca6a 100644 --- a/jode/jode/expr/NopOperator.java +++ b/jode/jode/expr/NopOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class NopOperator extends Instruction { public NopOperator(Type type) { @@ -26,7 +25,7 @@ public class NopOperator extends Instruction { } public NopOperator() { - this(MyType.tVoid); + this(Type.tVoid); } public boolean equals(Object o) { diff --git a/jode/jode/expr/Operator.java b/jode/jode/expr/Operator.java index e1619f8..9405b8b 100644 --- a/jode/jode/expr/Operator.java +++ b/jode/jode/expr/Operator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class Operator extends Expression { public final static int ADD_OP = 1; diff --git a/jode/jode/expr/PopOperator.java b/jode/jode/expr/PopOperator.java index 01572a1..b520e87 100644 --- a/jode/jode/expr/PopOperator.java +++ b/jode/jode/expr/PopOperator.java @@ -18,14 +18,13 @@ */ package jode; -import sun.tools.java.Type; public class PopOperator extends SimpleOperator { int count; public PopOperator(int count) { super(Type.tVoid, 0, 1); - operandTypes[0] = MyType.tUnknown; + operandTypes[0] = Type.tUnknown; this.count = count; } diff --git a/jode/jode/expr/PostFixOperator.java b/jode/jode/expr/PostFixOperator.java index a53601d..8021d7c 100644 --- a/jode/jode/expr/PostFixOperator.java +++ b/jode/jode/expr/PostFixOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class PostFixOperator extends Operator { StoreInstruction store; diff --git a/jode/jode/expr/PutFieldOperator.java b/jode/jode/expr/PutFieldOperator.java index 0e15255..1ee8c45 100644 --- a/jode/jode/expr/PutFieldOperator.java +++ b/jode/jode/expr/PutFieldOperator.java @@ -27,7 +27,7 @@ public class PutFieldOperator extends StoreInstruction { public PutFieldOperator(CodeAnalyzer codeAnalyzer, boolean staticFlag, FieldDefinition field) { - super(field.getType(), ASSIGN_OP); + super(Type.tType(field.getType()), ASSIGN_OP); this.codeAnalyzer = codeAnalyzer; this.staticFlag = staticFlag; this.field = field; @@ -55,7 +55,8 @@ public class PutFieldOperator extends StoreInstruction { /* shouldn't be called */ throw new AssertError("Field is static"); } - return MyType.tSubType(field.getClassDefinition().getType()); + return Type.tSubType(Type.tClass(field.getClassDefinition() + .getName().toString())); } public void setLValueOperandType(Type[] t) { @@ -72,9 +73,9 @@ public class PutFieldOperator extends StoreInstruction { if (field.getClassDefinition() == codeAnalyzer.getClassDefinition()) return field.getName().toString(); - object = - codeAnalyzer.getTypeString - (field.getClassDeclaration().getType())+"."; + object = codeAnalyzer.getTypeString + (Type.tClass(field.getClassDeclaration() + .getName().toString()))+"."; } else { if (operands[0].equals("this")) return field.getName().toString(); diff --git a/jode/jode/expr/ShiftOperator.java b/jode/jode/expr/ShiftOperator.java index fa977bc..1934b6c 100644 --- a/jode/jode/expr/ShiftOperator.java +++ b/jode/jode/expr/ShiftOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; /** * ShiftOpcodes are special, because their second operand is an UIndex @@ -28,7 +27,7 @@ public class ShiftOperator extends BinaryOperator { public ShiftOperator(Type type, int op) { super(type, op); - shiftType = MyType.tUIndex; + shiftType = Type.tInt; } public Type getOperandType(int i) { @@ -36,7 +35,7 @@ public class ShiftOperator extends BinaryOperator { } public void setOperandType(Type[] inputTypes) { - operandType = MyType.intersection(operandType, inputTypes[0]); - shiftType = MyType.intersection(shiftType, inputTypes[1]); + operandType = operandType.intersection(inputTypes[0]); + shiftType = shiftType .intersection(inputTypes[1]); } } diff --git a/jode/jode/expr/SimpleOperator.java b/jode/jode/expr/SimpleOperator.java index 3088c1a..6e8a40a 100644 --- a/jode/jode/expr/SimpleOperator.java +++ b/jode/jode/expr/SimpleOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class SimpleOperator extends Operator { protected Type[] operandTypes; @@ -42,7 +41,7 @@ public abstract class SimpleOperator extends Operator { public void setOperandType(Type[] t) { for (int i=0; i< operandTypes.length; i++) { - operandTypes[i] = MyType.intersection(operandTypes[i], t[i]); + operandTypes[i] = operandTypes[i].intersection(t[i]); } } } diff --git a/jode/jode/expr/StoreInstruction.java b/jode/jode/expr/StoreInstruction.java index 4d43f6e..41b75f2 100644 --- a/jode/jode/expr/StoreInstruction.java +++ b/jode/jode/expr/StoreInstruction.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public abstract class StoreInstruction extends Operator { @@ -27,7 +26,7 @@ public abstract class StoreInstruction extends Operator { public StoreInstruction(Type type, int operator) { super(Type.tVoid, operator); - lvalueType = MyType.tSubType(type); + lvalueType = Type.tSubType(type); lvCasts = lvalueType.toString(); } @@ -46,11 +45,6 @@ public abstract class StoreInstruction extends Operator { * @return true if the operand types changed */ public boolean setLValueType(Type type) { -// if (!MyType.isOfType(type, this.lvalueType)) { -// lvCasts = type.toString()+"/*invalid*/ <- " + lvCasts; -// } else if (type != this.lvalueType) { -// lvCasts = type.toString()+" <- " + lvCasts; -// } this.lvalueType = type; return false; } @@ -70,7 +64,7 @@ public abstract class StoreInstruction extends Operator { public Type getOperandType(int i) { if (i == getLValueOperandCount()) - return MyType.tSubType(getLValueType()); + return Type.tSubType(getLValueType()); else return getLValueOperandType(i); } @@ -78,9 +72,8 @@ public abstract class StoreInstruction extends Operator { public void setOperandType(Type[] t) { if (getLValueOperandCount() > 0) setLValueOperandType(t); - setLValueType(MyType.intersection - (lvalueType, - MyType.tSuperType(t[getLValueOperandCount()]))); + setLValueType(lvalueType.intersection + (Type.tSuperType(t[getLValueOperandCount()]))); } public int getOperandCount() { diff --git a/jode/jode/expr/StringAddOperator.java b/jode/jode/expr/StringAddOperator.java index b659cec..f8a7dc8 100644 --- a/jode/jode/expr/StringAddOperator.java +++ b/jode/jode/expr/StringAddOperator.java @@ -18,14 +18,13 @@ */ package jode; -import sun.tools.java.Type; public class StringAddOperator extends SimpleOperator { protected Type operandType; public StringAddOperator() { - super(MyType.tString, ADD_OP, 2); - operandTypes[1] = MyType.tUnknown; + super(Type.tString, ADD_OP, 2); + operandTypes[1] = Type.tUnknown; } public int getPriority() { diff --git a/jode/jode/expr/SwapOperator.java b/jode/jode/expr/SwapOperator.java index 7b6a151..ec21d52 100644 --- a/jode/jode/expr/SwapOperator.java +++ b/jode/jode/expr/SwapOperator.java @@ -21,7 +21,7 @@ package jode; public class SwapOperator extends Instruction { public SwapOperator() { - super(MyType.tVoid); + super(Type.tVoid); } public String toString() diff --git a/jode/jode/expr/UnaryOperator.java b/jode/jode/expr/UnaryOperator.java index 936aed0..8d65a4c 100644 --- a/jode/jode/expr/UnaryOperator.java +++ b/jode/jode/expr/UnaryOperator.java @@ -18,7 +18,6 @@ */ package jode; -import sun.tools.java.Type; public class UnaryOperator extends SimpleOperator { public UnaryOperator(Type type, int op) { @@ -38,7 +37,7 @@ public class UnaryOperator extends SimpleOperator { */ public void setType(Type type) { super.setType(type); - Type newOpType = MyType.intersection(type, operandTypes[0]); + Type newOpType = type.intersection(operandTypes[0]); operandTypes[0] = newOpType; } diff --git a/jode/jode/flow/BreakBlock.java b/jode/jode/flow/BreakBlock.java index 72331da..29a2673 100644 --- a/jode/jode/flow/BreakBlock.java +++ b/jode/jode/flow/BreakBlock.java @@ -44,6 +44,13 @@ public class BreakBlock extends StructuredBlock { } } + /** + * Tells if this block is empty and only changes control flow. + */ + public boolean isEmpty() { + return true; + } + /** * Returns the block where the control will normally flow to, when * this block is finished. diff --git a/jode/jode/flow/CaseBlock.java b/jode/jode/flow/CaseBlock.java index 464c94d..71312e9 100644 --- a/jode/jode/flow/CaseBlock.java +++ b/jode/jode/flow/CaseBlock.java @@ -49,7 +49,7 @@ public class CaseBlock extends StructuredBlock { /** * The type of the switch value. */ - sun.tools.java.Type type; + jode.Type type; public CaseBlock(int value) { this.value = value; diff --git a/jode/jode/flow/CatchBlock.java b/jode/jode/flow/CatchBlock.java index c79ec30..acc73bc 100644 --- a/jode/jode/flow/CatchBlock.java +++ b/jode/jode/flow/CatchBlock.java @@ -17,6 +17,7 @@ * $Id$ */ package jode.flow; +import jode.Type; import jode.LocalInfo; import sun.tools.java.Identifier; @@ -39,7 +40,7 @@ public class CatchBlock extends StructuredBlock { /** * The type of the exception. */ - sun.tools.java.Type exceptionType; + Type exceptionType; /** * The local containing the exception. @@ -166,8 +167,8 @@ public class CatchBlock extends StructuredBlock { } tryBlock.dumpSource(writer); writer.untab(); - writer.println("} catch ("+/*XXX*/exceptionType.typeString - (exceptionLocal.getName().toString())+") {"); + writer.println("} catch ("+/*XXX*/exceptionType.toString() + " " + + exceptionLocal.getName().toString()+ ") {"); writer.tab(); catchBlock.dumpSource(writer); if (!(outer instanceof CatchBlock diff --git a/jode/jode/flow/CombineIfGotoExpressions.java b/jode/jode/flow/CombineIfGotoExpressions.java index 35ba9de..f589a0a 100644 --- a/jode/jode/flow/CombineIfGotoExpressions.java +++ b/jode/jode/flow/CombineIfGotoExpressions.java @@ -21,7 +21,7 @@ package jode.flow; import java.util.Vector; import jode.Expression; import jode.ComplexExpression; -import jode.MyType; +import jode.Type; import jode.BinaryOperator; public class CombineIfGotoExpressions implements Transformation{ @@ -83,7 +83,7 @@ public class CombineIfGotoExpressions implements Transformation{ prevJump.prev.removeJump(); Expression cond = new ComplexExpression - (new BinaryOperator(MyType.tBoolean, operator), e); + (new BinaryOperator(Type.tBoolean, operator), e); cb.setInstruction(cond); cb.replace(cb.outer, cb); return true; diff --git a/jode/jode/flow/ContinueBlock.java b/jode/jode/flow/ContinueBlock.java index 0675c34..932f5c9 100644 --- a/jode/jode/flow/ContinueBlock.java +++ b/jode/jode/flow/ContinueBlock.java @@ -43,6 +43,13 @@ public class ContinueBlock extends StructuredBlock { } } + /** + * Tells if this block is empty and only changes control flow. + */ + public boolean isEmpty() { + return true; + } + /** * Returns the block where the control will normally flow to, when * this block is finished (not ignoring the jump after this block). diff --git a/jode/jode/flow/CreateAssignExpression.java b/jode/jode/flow/CreateAssignExpression.java index e64ef45..805b541 100644 --- a/jode/jode/flow/CreateAssignExpression.java +++ b/jode/jode/flow/CreateAssignExpression.java @@ -33,6 +33,7 @@ public class CreateAssignExpression implements Transformation{ InstructionContainer lastBlock; SequentialBlock opBlock; SequentialBlock sequBlock; + boolean isExpression = false; try { InstructionBlock ib; lastBlock = (InstructionContainer) flow.lastModified; @@ -43,6 +44,16 @@ public class CreateAssignExpression implements Transformation{ return false; ib = (InstructionBlock) opBlock.subBlocks[0]; + if (ib.getInstruction() instanceof DupOperator) { + DupOperator dup = (DupOperator) ib.getInstruction(); + if (dup.getDepth() != store.getLValueOperandCount() && + dup.getCount() != store.getLValueType().stackSize()) + return false; + opBlock = (SequentialBlock) lastBlock.outer; + ib = (InstructionBlock) opBlock.subBlocks[0]; + isExpression = true; + } + ComplexExpression binopExpr = (ComplexExpression) ib.getInstruction(); binop = (BinaryOperator) binopExpr.getOperator(); @@ -75,9 +86,14 @@ public class CreateAssignExpression implements Transformation{ opBlock.replace(sequBlock, opBlock); store.setOperatorIndex(store.OPASSIGN_OP+binop.getOperatorIndex()); - store.setLValueType(MyType.intersection(binop.getType(), - store.getLValueType())); - lastBlock.setInstruction(store); + store.setLValueType(binop.getType() + .intersection(store.getLValueType())); + + if (isExpression) + lastBlock.setInstruction + (new AssignOperator(store.getOperatorIndex(), store)); + else + lastBlock.setInstruction(store); lastBlock.replace(opBlock.subBlocks[1], lastBlock); return true; } @@ -103,7 +119,7 @@ public class CreateAssignExpression implements Transformation{ return false; } lastBlock.setInstruction - (new AssignOperator(Operator.ASSIGN_OP, store)); + (new AssignOperator(store.getOperatorIndex(), store)); lastBlock.replace(sequBlock, lastBlock); return true; diff --git a/jode/jode/flow/CreateConstantArray.java b/jode/jode/flow/CreateConstantArray.java index 8dfd989..8f20051 100644 --- a/jode/jode/flow/CreateConstantArray.java +++ b/jode/jode/flow/CreateConstantArray.java @@ -25,8 +25,7 @@ import jode.ArrayStoreOperator; import jode.NewArrayOperator; import jode.ConstantArrayOperator; import jode.ConstOperator; -import jode.MyType; -import sun.tools.java.Type; +import jode.Type; public class CreateConstantArray implements Transformation { @@ -60,7 +59,7 @@ public class CreateConstantArray implements Transformation { Expression indexexpr = (Expression) ib.getInstruction(); ConstOperator indexop = (ConstOperator) indexexpr.getOperator(); - if (!MyType.isOfType(indexop.getType(), MyType.tUInt)) + if (!indexop.getType().isOfType(Type.tUInt)) return false; int index = Integer.parseInt(indexop.getValue()); if (index >= 0 && consts == null) { @@ -71,7 +70,7 @@ public class CreateConstantArray implements Transformation { else { while (index < lastindex) { consts[lastindex--] = - new ConstOperator(MyType.tUnknown, "0"); + new ConstOperator(Type.tUnknown, "0"); } } consts[lastindex--] = lastconst; @@ -89,7 +88,7 @@ public class CreateConstantArray implements Transformation { return false; while (lastindex >= 0) { consts[lastindex--] = - new ConstOperator(MyType.tUnknown, "0"); + new ConstOperator(Type.tUnknown, "0"); } ComplexExpression newArrayExpr = (ComplexExpression) ib.getInstruction(); @@ -102,7 +101,7 @@ public class CreateConstantArray implements Transformation { (Expression) newArrayExpr.getSubExpressions()[0]; ConstOperator countop = (ConstOperator) countexpr.getOperator(); - if (!MyType.isOfType(countop.getType(), MyType.tUInt)) + if (!countop.getType().isOfType(Type.tUInt)) return false; int arraylength = Integer.parseInt(countop.getValue()); if (arraylength != consts.length) { @@ -111,7 +110,7 @@ public class CreateConstantArray implements Transformation { Expression[] newConsts = new Expression[arraylength]; System.arraycopy(consts, 0, newConsts, 0, consts.length); for (int i=consts.length; i 0)); @@ -455,7 +454,7 @@ public class FlowBlock { if (doWhileFalse != null) { doWhileFalse.replace(appendBlock, appendBlock); doWhileFalse.setBody(appendBlock); - doWhileFalse.removeJump(); + doWhileFalse.jump = null; } /* Now remove the jump of the appendBlock if it points to @@ -757,6 +756,13 @@ public class FlowBlock { checkConsistent(); +// TabbedPrintWriter writer = new jode.TabbedPrintWriter(System.err, " "); +// try { +// writer.println("XXXXXXXXXXXXXXXX"); +// writer.tab(); +// dumpSource(writer); +// } catch(java.io.IOException ex) {} + appendBlock = resolveRemaining(succ, appendBlock); } @@ -1110,6 +1116,11 @@ public class FlowBlock { /* the Block has no successor where t1 is applicable. * Finish this analyzation. */ + if (Decompiler.isFlowDebugging) { + writer.println("No more successors applicable: " + + start + " - " + end + "; " + + addr + " - " + (addr+length)); + } return changed; } else { /* Only do T1 transformation if the blocks are @@ -1190,8 +1201,15 @@ public class FlowBlock { return changed; else if (next.addr >= start) { - /* First analyze the next block. */ - changed = next.analyze(next.addr, end) || changed; + /* First analyze the next block. It may + * return early after a T2 trafo so call it + * until nothing more is possible. + */ + while (next.analyze(addr + length, end)) + changed = changed || true; + + if (next.addr != addr + length) + return changed; /* Check if next has only the previous case * and this case as predecessor. Otherwise @@ -1227,9 +1245,7 @@ public class FlowBlock { lastBlock = resolveRemaining(next, lastBlock); } - /* Set addr+length to (semi-)correct value */ - if (next.addr < addr) - addr = next.addr; + /* Set length to correct value */ length += next.length; lastBlock = next.block; diff --git a/jode/jode/flow/IfThenElseBlock.java b/jode/jode/flow/IfThenElseBlock.java index e7fd4bc..8525dab 100644 --- a/jode/jode/flow/IfThenElseBlock.java +++ b/jode/jode/flow/IfThenElseBlock.java @@ -104,7 +104,8 @@ public class IfThenElseBlock extends StructuredBlock { if (elseBlock != null) { writer.print(needBrace ? "} " : ""); if (elseBlock instanceof IfThenElseBlock - /* XXX && No variables are declared XXX*/) { + && (elseBlock.declare == null + || elseBlock.declare.isEmpty())) { needBrace = false; writer.print("else "); elseBlock.dumpSource(writer); diff --git a/jode/jode/flow/InstructionBlock.java b/jode/jode/flow/InstructionBlock.java index be01c8c..4e3999d 100644 --- a/jode/jode/flow/InstructionBlock.java +++ b/jode/jode/flow/InstructionBlock.java @@ -72,7 +72,7 @@ public class InstructionBlock extends InstructionContainer { .getLocalInfo().getType().toString()/*XXX*/ + " " + instr.toString() + ";"); } else { - if (instr.getType() != MyType.tVoid) + if (instr.getType() != Type.tVoid) writer.print("push "); writer.println(instr.toString()+";"); } diff --git a/jode/jode/flow/LoopBlock.java b/jode/jode/flow/LoopBlock.java index 9b96bdf..5051f3b 100644 --- a/jode/jode/flow/LoopBlock.java +++ b/jode/jode/flow/LoopBlock.java @@ -30,9 +30,9 @@ public class LoopBlock extends StructuredBlock implements BreakableBlock { public static final int FOR = 2; public static final Instruction TRUE = - new ConstOperator(MyType.tBoolean, "1"); + new ConstOperator(Type.tBoolean, "1"); public static final Instruction FALSE = - new ConstOperator(MyType.tBoolean, "0"); + new ConstOperator(Type.tBoolean, "0"); /** * The condition. Must be of boolean type. diff --git a/jode/jode/flow/RawTryCatchBlock.java b/jode/jode/flow/RawTryCatchBlock.java index 8a8d016..d53d89b 100644 --- a/jode/jode/flow/RawTryCatchBlock.java +++ b/jode/jode/flow/RawTryCatchBlock.java @@ -42,7 +42,7 @@ import jode.TabbedPrintWriter; public class RawTryCatchBlock extends StructuredBlock { - public RawTryCatchBlock(sun.tools.java.Type type, + public RawTryCatchBlock(jode.Type type, StructuredBlock tryBlock, Jump endDest, Jump catchDest) { this.type = type; @@ -89,7 +89,7 @@ public class RawTryCatchBlock extends StructuredBlock { * The type of the exception that is catched. This is null for a * synchronized/finally block */ - sun.tools.java.Type type; + jode.Type type; /** * Replaces the given sub block with a new block. diff --git a/jode/jode/flow/RemoveEmpty.java b/jode/jode/flow/RemoveEmpty.java index 50fe8ad..8988308 100644 --- a/jode/jode/flow/RemoveEmpty.java +++ b/jode/jode/flow/RemoveEmpty.java @@ -47,8 +47,7 @@ public class RemoveEmpty implements Transformation { if (prev.jump != null) return false; instr = (Instruction) prev.getInstruction(); - instr.setType(jode.MyType.intersection - (instr.getType(), prevInstr.getType())); + instr.setType(instr.getType().intersection(prevInstr.getType())); } catch (NullPointerException ex) { return false; } catch (ClassCastException ex) { diff --git a/jode/jode/flow/SequentialBlock.java b/jode/jode/flow/SequentialBlock.java index 86c1dfb..2b03aac 100644 --- a/jode/jode/flow/SequentialBlock.java +++ b/jode/jode/flow/SequentialBlock.java @@ -52,14 +52,22 @@ public class SequentialBlock extends StructuredBlock { * the behaviour is undefined, so take care. * @return null, if the control flows to another FlowBlock. */ public StructuredBlock getNextBlock(StructuredBlock subBlock) { - if (subBlock == subBlocks[0]) - return subBlocks[1]; + if (subBlock == subBlocks[0]) { + if (subBlocks[1].isEmpty()) + return subBlocks[1].getNextBlock(); + else + return subBlocks[1]; + } return getNextBlock(); } public FlowBlock getNextFlowBlock(StructuredBlock subBlock) { - if (subBlock == subBlocks[0]) - return null; + if (subBlock == subBlocks[0]) { + if (subBlocks[1].isEmpty()) + return subBlocks[1].getNextFlowBlock(); + else + return null; + } return getNextFlowBlock(); } diff --git a/jode/jode/flow/StructuredBlock.java b/jode/jode/flow/StructuredBlock.java index 56b587e..c99b82e 100644 --- a/jode/jode/flow/StructuredBlock.java +++ b/jode/jode/flow/StructuredBlock.java @@ -150,6 +150,13 @@ public abstract class StructuredBlock { return getNextFlowBlock(); } + /** + * Tells if this block is empty and only changes control flow. + */ + public boolean isEmpty() { + return false; + } + /** * Tells if the sub block is the single exit point of the current block. * @param subBlock the sub block. @@ -441,8 +448,8 @@ public abstract class StructuredBlock { public void dumpDeclaration(jode.TabbedPrintWriter writer, LocalInfo local) throws java.io.IOException { - writer.println(local.getType().typeString(local.getName().toString()) - + ";"); + writer.println(local.getType().toString() + " " + + local.getName().toString() + ";"); } /** diff --git a/jode/jode/flow/SwitchBlock.java b/jode/jode/flow/SwitchBlock.java index f6677d6..8d7c38b 100644 --- a/jode/jode/flow/SwitchBlock.java +++ b/jode/jode/flow/SwitchBlock.java @@ -141,7 +141,7 @@ implements BreakableBlock { public void setInstruction(jode.Instruction instr) { super.setInstruction(instr); - sun.tools.java.Type type = instr.getType(); + jode.Type type = instr.getType(); if (type != caseBlocks[0].type) { for (int i=0; i < caseBlocks.length; i++) caseBlocks[i].type = type; diff --git a/jode/jode/type/ClassInterfacesType.java b/jode/jode/type/ClassInterfacesType.java index 30ebe05..224bd99 100644 --- a/jode/jode/type/ClassInterfacesType.java +++ b/jode/jode/type/ClassInterfacesType.java @@ -33,24 +33,23 @@ import java.util.Stack; * interfaces or the class type or any of their super types. * * @author Jochen Hoenicke */ -public class ClassInterfacesType extends MyType { +public class ClassInterfacesType extends Type { Class clazz; Class ifaces[]; public final static Class cObject = new Object().getClass(); - public ClassInterfacesType(Type clazzType) { - super(104, "{"+clazzType.getTypeSignature()+"}"); + public ClassInterfacesType(String clazzName) { + super(TC_CLASS); try { - Class cdecl = - Class.forName(clazzType.getClassName().toString()); - if (cdecl.isInterface()) { - clazz = cObject; + Class clazz = Class.forName(clazzName); + if (clazz.isInterface()) { + this.clazz = cObject; ifaces = new Class[1]; - ifaces[0] = cdecl; + ifaces[0] = clazz; } else { - clazz = cdecl; + this.clazz = clazz; ifaces = new Class[0]; } } catch (ClassNotFoundException ex) { @@ -58,20 +57,31 @@ public class ClassInterfacesType extends MyType { } } - public ClassInterfacesType(Class clazz, - Class[] ifaces) { - super(104, "{}"); - StringBuffer sig = new StringBuffer("{"); - if (clazz != null) - sig.append("L").append(clazz.getName()).append(";"); - for (int i=0;i < ifaces.length; i++) - sig.append("L").append(ifaces[i].getName()).append(";"); - sig.append("}"); - typeSig = sig.toString(); + public ClassInterfacesType(Class clazz) { + super(TC_CLASS); + if (clazz.isInterface()) { + this.clazz = cObject; + ifaces = new Class[1]; + ifaces[0] = clazz; + } else { + this.clazz = clazz; + ifaces = new Class[0]; + } + } + + public ClassInterfacesType(Class clazz, Class[] ifaces) { + super(TC_CLASS); this.clazz = clazz; this.ifaces = ifaces; } + private static Type create(Class clazz, Class[] ifaces) { + /* Make sure that every {java.lang.Object} equals tObject */ + if (ifaces.length == 0 && (clazz == cObject || clazz == null)) + return tObject; + return new ClassInterfacesType(clazz, ifaces); + } + public final static boolean superClassOf(Class parent, Class clazz) { while (clazz != parent && clazz != null) { clazz = clazz.getSuperclass(); @@ -92,40 +102,51 @@ public class ClassInterfacesType extends MyType { } /** - * Checks if the given type range may be not empty. - * This means, that bottom.clazz is extended by top.clazz - * and that all interfaces in bottom are implemented by an - * interface or by top.clazz.

- * - * if that is true, a class range type is created, otherwise - * tError is returned. + * Create the type corresponding to the range from bottomType to + * this. Checks if the given type range may be not empty. This + * means, that bottom.clazz is extended by this.clazz and that all + * interfaces in bottom are implemented by an interface or by + * clazz. + * @param bottom the start point of the range + * @return the range type, or tError if range is empty. */ - public final static Type createRangeType(ClassInterfacesType bottom, - ClassInterfacesType top) { + public Type createRangeType(Type bottomType) { + + if (bottomType == tUnknown || bottomType == tObject) + return (this == tObject) ? tObject : tRange(tObject, this); + + if (bottomType.typecode != TC_CLASS) + return tError; + + ClassInterfacesType bottom = (ClassInterfacesType) bottomType; + if (bottom.clazz != null && bottom.clazz != cObject) { /* The searched type must be a class type. */ - if (top.ifaces.length != 0 - || !superClassOf(bottom.clazz,top.clazz)) + if (this.ifaces.length != 0 + || !superClassOf(bottom.clazz,this.clazz)) return tError; - /* All interfaces must be implemented by top.clazz + /* All interfaces must be implemented by this.clazz */ for (int i=0; i < bottom.ifaces.length; i++) { - if (!implementedBy(bottom.ifaces[i], top.clazz)) + if (!implementedBy(bottom.ifaces[i], this.clazz)) return tError; } - return new ClassRangeType - (bottom, new ClassInterfacesType(top.clazz, - new Class[0])); + + if (bottom.clazz == this.clazz + && bottom.ifaces.length == 0) + return bottom; + + return tRange(bottom, create(this.clazz, new Class[0])); } else { - /* Now bottom.clazz is null, find all top.class/interfaces - * that implement all bottom.ifaces. + /* Now bottom.clazz is null (or tObject), find all + * classes/interfaces that implement all bottom.ifaces. */ - Class clazz = top.clazz; + Class clazz = this.clazz; if (clazz != null) { for (int i=0; i < bottom.ifaces.length; i++) { if (!implementedBy(bottom.ifaces[i], clazz)) { @@ -136,46 +157,60 @@ public class ClassInterfacesType extends MyType { } Vector ifaces = new Vector(); big_loop: - for (int j=0; j < top.ifaces.length; j++) { + for (int j=0; j < this.ifaces.length; j++) { for (int i=0; i < bottom.ifaces.length; i++) { - if (!implementedBy(bottom.ifaces[i], top.ifaces[j])) + if (!implementedBy(bottom.ifaces[i], this.ifaces[j])) continue big_loop; } - ifaces.addElement(top.ifaces[j]); + ifaces.addElement(this.ifaces[j]); } + + /* If bottom and the new top are the same single interface + * return it. + */ + if (clazz == null + && bottom.ifaces.length == 1 && ifaces.size() == 1 + && bottom.ifaces[0] == ifaces.elementAt(0)) + return bottom; + Class[] ifaceArray = new Class[ifaces.size()]; - ifaces.copyInto(ifaceArray); - return new ClassRangeType - (bottom, new ClassInterfacesType(clazz, ifaceArray)); + ifaces.copyInto(ifaceArray); + return tRange(bottom, create(clazz, ifaceArray)); } } /** - * Returns the specialized type of t1 and t2. + * Returns the specialized type of this and type. * We have two classes and multiple interfaces. The result * should be the object that is the the child of both objects * and the union of all interfaces. */ - public static Type getSpecializedType(ClassInterfacesType t1, - ClassInterfacesType t2) { + public Type getSpecializedType(Type type) { + if (type.getTypeCode() == TC_UNKNOWN) + return this; + if (type.getTypeCode() == TC_ARRAY && this == tObject) + return type; + if (type.getTypeCode() != TC_CLASS) + return tError; + + ClassInterfacesType other = (ClassInterfacesType) type; Class clazz = null; Vector ifaces = new Vector(); - /* First determine the clazz, one of the two classes must be a sub * class of the other or null. */ - if (t1.clazz == null) - clazz = t2.clazz; - else if (t2.clazz == null) - clazz = t1.clazz; - else if (superClassOf(t1.clazz, t2.clazz)) - clazz = t2.clazz; - else if (superClassOf(t2.clazz, t1.clazz)) - clazz = t1.clazz; + if (this.clazz == null) + clazz = other.clazz; + else if (other.clazz == null) + clazz = this.clazz; + else if (superClassOf(this.clazz, other.clazz)) + clazz = other.clazz; + else if (superClassOf(other.clazz, this.clazz)) + clazz = this.clazz; else return tError; @@ -183,15 +218,15 @@ public class ClassInterfacesType extends MyType { * But we can simplify this, if an interface is implemented by * another or by the class, we can omit it. */ - big_loop_t1: - for (int i=0; i< t1.ifaces.length; i++) { - Class iface = t1.ifaces[i]; + big_loop_this: + for (int i=0; i< this.ifaces.length; i++) { + Class iface = this.ifaces[i]; if (clazz != null && implementedBy(iface, clazz)) { - continue big_loop_t1; + continue big_loop_this; } - for (int j=0; j"; StringBuffer sb = new StringBuffer("{"); String comma = ""; if (clazz != null) { @@ -324,14 +367,35 @@ public class ClassInterfacesType extends MyType { sb.append(comma).append(ifaces[i].getName()); comma = ", "; } - return sb.append("}").append(string).toString(); + return sb.append("}").toString(); } else { if (clazz != null) - return clazz.toString() + string; + return clazz.getName(); else if (ifaces.length > 0) - return ifaces[0].toString() + string; + return ifaces[0].getName(); else - return tError.toString() + string; + return "{}"; + } + } + + public boolean equals(Object o) { + if (o == this) + return true; + if (o instanceof ClassInterfacesType) { + ClassInterfacesType type = (ClassInterfacesType) o; + if (type.clazz == clazz + && type.ifaces.length == ifaces.length) { + big_loop: + for (int i=0; i< type.ifaces.length; i++) { + for (int j=0; j