CodeAnalyzer merged into MethodAnalyzer

git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@893 379699f6-c40d-0410-875b-85095c16579e
stable
jochen 25 years ago
parent 939645e847
commit fe9868d0db
  1. 190
      jode/jode/decompiler/Opcodes.java
  2. 2
      jode/jode/expr/ClassFieldOperator.java
  3. 16
      jode/jode/expr/LocalLoadOperator.java
  4. 2
      jode/jode/expr/OuterLocalOperator.java
  5. 8
      jode/jode/flow/CreateNewConstructor.java
  6. 14
      jode/jode/flow/FlowBlock.java

@ -19,6 +19,7 @@
package jode.decompiler; package jode.decompiler;
import jode.type.Type; import jode.type.Type;
import jode.type.IntegerType;
import jode.type.MethodType; import jode.type.MethodType;
import jode.expr.*; import jode.expr.*;
import jode.flow.*; import jode.flow.*;
@ -32,6 +33,28 @@ import java.util.Vector;
*/ */
public abstract class Opcodes implements jode.bytecode.Opcodes { public abstract class Opcodes implements jode.bytecode.Opcodes {
private final static Type tIntHint
= new IntegerType(IntegerType.IT_I,
IntegerType.IT_I
| IntegerType.IT_B
| IntegerType.IT_C
| IntegerType.IT_S);
private final static Type tBoolIntHint
= new IntegerType(IntegerType.IT_I
| IntegerType.IT_Z,
IntegerType.IT_I
| IntegerType.IT_B
| IntegerType.IT_C
| IntegerType.IT_S
| IntegerType.IT_Z);
private final static int LOCAL_TYPES = 0;
private final static int ARRAY_TYPES = 1;
private final static int UNARY_TYPES = 2;
private final static int I2BCS_TYPES = 3;
private final static int BIN_TYPES = 4;
private final static int ZBIN_TYPES = 5;
private final static Type types[][] = { private final static Type types[][] = {
// Local types // Local types
{ Type.tBoolUInt, Type.tLong, Type.tFloat, Type.tDouble, { Type.tBoolUInt, Type.tLong, Type.tFloat, Type.tDouble,
@ -39,22 +62,24 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
// Array types // Array types
{ Type.tInt, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject, { Type.tInt, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject,
Type.tBoolByte, Type.tChar, Type.tShort }, Type.tBoolByte, Type.tChar, Type.tShort },
// ifld2ifld and shl types
{ Type.tInt, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject },
// i2bcs types // i2bcs types
{ Type.tByte, Type.tChar, Type.tShort }, { Type.tByte, Type.tChar, Type.tShort },
// add/sub/mul/div types // cmp/add/sub/mul/div types
{ Type.tInt, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject }, { tIntHint, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject },
// and/or/xor types // and/or/xor types
{ Type.tBoolInt, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject } { tBoolIntHint, Type.tLong, Type.tFloat, Type.tDouble, Type.tUObject }
}; };
private static StructuredBlock createNormal(CodeAnalyzer ca, private static StructuredBlock createNormal(MethodAnalyzer ma,
Instruction instr, Instruction instr,
Expression expr) Expression expr)
{ {
return new InstructionBlock(expr, new Jump(FlowBlock.NEXT_BY_ADDR)); return new InstructionBlock(expr, new Jump(FlowBlock.NEXT_BY_ADDR));
} }
private static StructuredBlock createSpecial(CodeAnalyzer ca, private static StructuredBlock createSpecial(MethodAnalyzer ma,
Instruction instr, Instruction instr,
int type, int type,
int stackcount, int param) int stackcount, int param)
@ -63,20 +88,20 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
new Jump(FlowBlock.NEXT_BY_ADDR)); new Jump(FlowBlock.NEXT_BY_ADDR));
} }
private static StructuredBlock createGoto(CodeAnalyzer ca, private static StructuredBlock createGoto(MethodAnalyzer ma,
Instruction instr) Instruction instr)
{ {
return new EmptyBlock(new Jump((FlowBlock)instr.succs[0].tmpInfo)); return new EmptyBlock(new Jump((FlowBlock)instr.succs[0].tmpInfo));
} }
private static StructuredBlock createJsr(CodeAnalyzer ca, private static StructuredBlock createJsr(MethodAnalyzer ma,
Instruction instr) Instruction instr)
{ {
return new JsrBlock(new Jump((FlowBlock)instr.succs[0].tmpInfo), return new JsrBlock(new Jump((FlowBlock)instr.succs[0].tmpInfo),
new Jump(FlowBlock.NEXT_BY_ADDR)); new Jump(FlowBlock.NEXT_BY_ADDR));
} }
private static StructuredBlock createIfGoto(CodeAnalyzer ca, private static StructuredBlock createIfGoto(MethodAnalyzer ma,
Instruction instr, Instruction instr,
Expression expr) Expression expr)
{ {
@ -85,21 +110,21 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
new Jump(FlowBlock.NEXT_BY_ADDR)); new Jump(FlowBlock.NEXT_BY_ADDR));
} }
private static StructuredBlock createSwitch(CodeAnalyzer ca, private static StructuredBlock createSwitch(MethodAnalyzer ma,
Instruction instr, Instruction instr,
int[] cases, FlowBlock[] dests) int[] cases, FlowBlock[] dests)
{ {
return new SwitchBlock(new NopOperator(Type.tUInt), cases, dests); return new SwitchBlock(new NopOperator(Type.tUInt), cases, dests);
} }
private static StructuredBlock createBlock(CodeAnalyzer ca, private static StructuredBlock createBlock(MethodAnalyzer ma,
Instruction instr, Instruction instr,
StructuredBlock block) StructuredBlock block)
{ {
return block; return block;
} }
private static StructuredBlock createRet(CodeAnalyzer ca, private static StructuredBlock createRet(MethodAnalyzer ma,
Instruction instr, Instruction instr,
LocalInfo local) LocalInfo local)
{ {
@ -110,7 +135,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
* Read an opcode out of a data input stream containing the bytecode. * Read an opcode out of a data input stream containing the bytecode.
* @param addr The current address. * @param addr The current address.
* @param stream The stream containing the java byte code. * @param stream The stream containing the java byte code.
* @param ca The Code Analyzer * @param ma The Method Analyzer
* (where further information can be get from). * (where further information can be get from).
* @return The FlowBlock representing this opcode * @return The FlowBlock representing this opcode
* or null if the stream is empty. * or null if the stream is empty.
@ -118,79 +143,80 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
* @exception ClassFormatError if an invalid opcode is detected. * @exception ClassFormatError if an invalid opcode is detected.
*/ */
public static StructuredBlock readOpcode(Instruction instr, public static StructuredBlock readOpcode(Instruction instr,
CodeAnalyzer ca) MethodAnalyzer ma)
throws ClassFormatError throws ClassFormatError
{ {
int opcode = instr.opcode; int opcode = instr.opcode;
switch (opcode) { switch (opcode) {
case opc_nop: case opc_nop:
return createBlock(ca, instr, new EmptyBlock return createBlock(ma, instr, new EmptyBlock
(new Jump(FlowBlock.NEXT_BY_ADDR))); (new Jump(FlowBlock.NEXT_BY_ADDR)));
case opc_ldc: case opc_ldc:
case opc_ldc2_w: case opc_ldc2_w:
return createNormal (ca, instr, new ConstOperator(instr.objData)); return createNormal (ma, instr, new ConstOperator(instr.objData));
case opc_iload: case opc_lload: case opc_iload: case opc_lload:
case opc_fload: case opc_dload: case opc_aload: case opc_fload: case opc_dload: case opc_aload:
return createNormal return createNormal
(ca, instr, new LocalLoadOperator (ma, instr, new LocalLoadOperator
(types[0][opcode-opc_iload], ca, (types[LOCAL_TYPES][opcode-opc_iload], ma,
ca.getLocalInfo(instr.addr, instr.localSlot))); ma.getLocalInfo(instr.addr, instr.localSlot)));
case opc_iaload: case opc_laload: case opc_iaload: case opc_laload:
case opc_faload: case opc_daload: case opc_aaload: case opc_faload: case opc_daload: case opc_aaload:
case opc_baload: case opc_caload: case opc_saload: case opc_baload: case opc_caload: case opc_saload:
return createNormal return createNormal
(ca, instr, new ArrayLoadOperator (ma, instr, new ArrayLoadOperator
(types[1][opcode - opc_iaload])); (types[ARRAY_TYPES][opcode - opc_iaload]));
case opc_istore: case opc_lstore: case opc_istore: case opc_lstore:
case opc_fstore: case opc_dstore: case opc_astore: case opc_fstore: case opc_dstore: case opc_astore:
return createNormal return createNormal
(ca, instr, new StoreInstruction (ma, instr, new StoreInstruction
(new LocalStoreOperator (new LocalStoreOperator
(types[0][opcode-opc_istore], (types[LOCAL_TYPES][opcode-opc_istore],
ca.getLocalInfo(instr.addr+instr.length,instr.localSlot)))); ma.getLocalInfo(instr.addr+instr.length,instr.localSlot))));
case opc_iastore: case opc_lastore: case opc_iastore: case opc_lastore:
case opc_fastore: case opc_dastore: case opc_aastore: case opc_fastore: case opc_dastore: case opc_aastore:
case opc_bastore: case opc_castore: case opc_sastore: case opc_bastore: case opc_castore: case opc_sastore:
return createNormal return createNormal
(ca, instr, new StoreInstruction (ma, instr, new StoreInstruction
(new ArrayStoreOperator(types[1][opcode - opc_iastore]))); (new ArrayStoreOperator
(types[ARRAY_TYPES][opcode - opc_iastore])));
case opc_pop: case opc_pop2: case opc_pop: case opc_pop2:
return createSpecial return createSpecial
(ca, instr, SpecialBlock.POP, opcode - opc_pop + 1, 0); (ma, instr, SpecialBlock.POP, opcode - opc_pop + 1, 0);
case opc_dup: case opc_dup_x1: case opc_dup_x2: case opc_dup: case opc_dup_x1: case opc_dup_x2:
case opc_dup2: case opc_dup2_x1: case opc_dup2_x2: case opc_dup2: case opc_dup2_x1: case opc_dup2_x2:
return createSpecial return createSpecial
(ca, instr, SpecialBlock.DUP, (ma, instr, SpecialBlock.DUP,
(opcode - opc_dup)/3+1, (opcode - opc_dup)%3); (opcode - opc_dup)/3+1, (opcode - opc_dup)%3);
case opc_swap: case opc_swap:
return createSpecial(ca, instr, SpecialBlock.SWAP, 1, 0); return createSpecial(ma, instr, SpecialBlock.SWAP, 1, 0);
case opc_iadd: case opc_ladd: case opc_fadd: case opc_dadd: case opc_iadd: case opc_ladd: case opc_fadd: case opc_dadd:
case opc_isub: case opc_lsub: case opc_fsub: case opc_dsub: case opc_isub: case opc_lsub: case opc_fsub: case opc_dsub:
case opc_imul: case opc_lmul: case opc_fmul: case opc_dmul: case opc_imul: case opc_lmul: case opc_fmul: case opc_dmul:
case opc_idiv: case opc_ldiv: case opc_fdiv: case opc_ddiv: case opc_idiv: case opc_ldiv: case opc_fdiv: case opc_ddiv:
case opc_irem: case opc_lrem: case opc_frem: case opc_drem: case opc_irem: case opc_lrem: case opc_frem: case opc_drem:
return createNormal return createNormal
(ca, instr, new BinaryOperator (ma, instr, new BinaryOperator
(types[3][(opcode - opc_iadd)%4], (types[BIN_TYPES][(opcode - opc_iadd)%4],
(opcode - opc_iadd)/4+Operator.ADD_OP)); (opcode - opc_iadd)/4+Operator.ADD_OP));
case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg: case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg:
return createNormal return createNormal
(ca, instr, new UnaryOperator (ma, instr, new UnaryOperator
(types[3][opcode - opc_ineg], Operator.NEG_OP)); (types[UNARY_TYPES][opcode - opc_ineg], Operator.NEG_OP));
case opc_ishl: case opc_lshl: case opc_ishl: case opc_lshl:
case opc_ishr: case opc_lshr: case opc_ishr: case opc_lshr:
case opc_iushr: case opc_lushr: case opc_iushr: case opc_lushr:
return createNormal return createNormal
(ca, instr, new ShiftOperator (ma, instr, new ShiftOperator
(types[3][(opcode - opc_ishl)%2], (types[UNARY_TYPES][(opcode - opc_ishl)%2],
(opcode - opc_ishl)/2 + Operator.SHIFT_OP)); (opcode - opc_ishl)/2 + Operator.SHIFT_OP));
case opc_iand: case opc_land: case opc_iand: case opc_land:
case opc_ior : case opc_lor : case opc_ior : case opc_lor :
case opc_ixor: case opc_lxor: case opc_ixor: case opc_lxor:
return createNormal return createNormal
(ca, instr, new BinaryOperator (ma, instr, new BinaryOperator
(types[4][(opcode - opc_iand)%2], (types[ZBIN_TYPES][(opcode - opc_iand)%2],
(opcode - opc_iand)/2 + Operator.AND_OP)); (opcode - opc_iand)/2 + Operator.AND_OP));
case opc_iinc: { case opc_iinc: {
int value = instr.intData; int value = instr.intData;
@ -199,10 +225,10 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
value = -value; value = -value;
operation = Operator.SUB_OP; operation = Operator.SUB_OP;
} }
LocalInfo li = ca.getLocalInfo(instr.addr, instr.localSlot); LocalInfo li = ma.getLocalInfo(instr.addr, instr.localSlot);
return createNormal return createNormal
(ca, instr, new IIncOperator (ma, instr, new IIncOperator
(new LocalStoreOperator(Type.tUInt, li), (new LocalStoreOperator(Type.tInt, li),
value, operation + Operator.OPASSIGN_OP)); value, operation + Operator.OPASSIGN_OP));
} }
case opc_i2l: case opc_i2f: case opc_i2d: case opc_i2l: case opc_i2f: case opc_i2d:
@ -214,56 +240,54 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
if (to >= from) if (to >= from)
to++; to++;
return createNormal return createNormal
(ca, instr, new ConvertOperator(types[3][from], (ma, instr, new ConvertOperator(types[UNARY_TYPES][from],
types[3][to])); types[UNARY_TYPES][to]));
} }
case opc_i2b: case opc_i2c: case opc_i2s: case opc_i2b: case opc_i2c: case opc_i2s:
return createNormal return createNormal
(ca, instr, new ConvertOperator (ma, instr, new ConvertOperator
(types[3][0], types[2][opcode-opc_i2b])); (types[UNARY_TYPES][0], types[I2BCS_TYPES][opcode-opc_i2b]));
case opc_lcmp: case opc_lcmp:
case opc_fcmpl: case opc_fcmpg: case opc_fcmpl: case opc_fcmpg:
case opc_dcmpl: case opc_dcmpg: case opc_dcmpl: case opc_dcmpg:
return createNormal return createNormal
(ca, instr, new CompareToIntOperator (ma, instr, new CompareToIntOperator
(types[3][(opcode-(opc_lcmp-3))/2], (types[BIN_TYPES][(opcode-(opc_lcmp-3))/2],
(opcode == opc_fcmpg || opcode == opc_dcmpg))); (opcode == opc_fcmpg || opcode == opc_dcmpg)));
case opc_ifeq: case opc_ifne: case opc_ifeq: case opc_ifne:
return createIfGoto return createIfGoto
(ca, instr, (ma, instr,
new CompareUnaryOperator new CompareUnaryOperator
(Type.tBoolUInt, opcode - (opc_ifeq-Operator.COMPARE_OP))); (Type.tBoolInt, opcode - (opc_ifeq-Operator.COMPARE_OP)));
case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle:
return createIfGoto return createIfGoto
(ca, instr, (ma, instr,
new CompareUnaryOperator new CompareUnaryOperator
(Type.tUInt, opcode - (opc_ifeq-Operator.COMPARE_OP))); (Type.tInt, opcode - (opc_ifeq-Operator.COMPARE_OP)));
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpeq: case opc_if_icmpne:
return createIfGoto return createIfGoto
(ca, instr, (ma, instr,
new CompareBinaryOperator new CompareBinaryOperator
(Type.tBoolInt, (tBoolIntHint, opcode - (opc_if_icmpeq-Operator.COMPARE_OP)));
opcode - (opc_if_icmpeq-Operator.COMPARE_OP)));
case opc_if_icmplt: case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmpge:
case opc_if_icmpgt: case opc_if_icmple: case opc_if_icmpgt: case opc_if_icmple:
return createIfGoto return createIfGoto
(ca, instr, (ma, instr,
new CompareBinaryOperator new CompareBinaryOperator
(Type.tUInt, (tIntHint, opcode - (opc_if_icmpeq-Operator.COMPARE_OP)));
opcode - (opc_if_icmpeq-Operator.COMPARE_OP)));
case opc_if_acmpeq: case opc_if_acmpne: case opc_if_acmpeq: case opc_if_acmpne:
return createIfGoto return createIfGoto
(ca, instr, (ma, instr,
new CompareBinaryOperator new CompareBinaryOperator
(Type.tUObject, (Type.tUObject,
opcode - (opc_if_acmpeq-Operator.COMPARE_OP))); opcode - (opc_if_acmpeq-Operator.COMPARE_OP)));
case opc_goto: case opc_goto:
return createGoto(ca, instr); return createGoto(ma, instr);
case opc_jsr: case opc_jsr:
return createJsr(ca, instr); return createJsr(ma, instr);
case opc_ret: case opc_ret:
return createRet return createRet
(ca, instr, ca.getLocalInfo(instr.addr, instr.localSlot)); (ma, instr, ma.getLocalInfo(instr.addr, instr.localSlot));
case opc_tableswitch: { case opc_tableswitch: {
int low = instr.intData; int low = instr.intData;
int[] cases = new int[instr.succs.length-1]; int[] cases = new int[instr.succs.length-1];
@ -273,7 +297,7 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
dests[i] = (FlowBlock) instr.succs[i].tmpInfo; dests[i] = (FlowBlock) instr.succs[i].tmpInfo;
} }
dests[cases.length] = (FlowBlock)instr.succs[cases.length].tmpInfo; dests[cases.length] = (FlowBlock)instr.succs[cases.length].tmpInfo;
return createSwitch(ca, instr, cases, dests); return createSwitch(ma, instr, cases, dests);
} }
case opc_lookupswitch: { case opc_lookupswitch: {
int[] cases = (int[]) instr.objData; int[] cases = (int[]) instr.objData;
@ -281,30 +305,30 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
for (int i=0; i < dests.length; i++) for (int i=0; i < dests.length; i++)
dests[i] = (FlowBlock) instr.succs[i].tmpInfo; dests[i] = (FlowBlock) instr.succs[i].tmpInfo;
dests[cases.length] = (FlowBlock)instr.succs[cases.length].tmpInfo; dests[cases.length] = (FlowBlock)instr.succs[cases.length].tmpInfo;
return createSwitch(ca, instr, cases, dests); return createSwitch(ma, instr, cases, dests);
} }
case opc_ireturn: case opc_lreturn: case opc_ireturn: case opc_lreturn:
case opc_freturn: case opc_dreturn: case opc_areturn: { case opc_freturn: case opc_dreturn: case opc_areturn: {
Type retType = Type.tSubType(ca.getMethod().getReturnType()); Type retType = Type.tSubType(ma.getReturnType());
return createBlock return createBlock
(ca, instr, new ReturnBlock(new NopOperator(retType))); (ma, instr, new ReturnBlock(new NopOperator(retType)));
} }
case opc_return: case opc_return:
return createBlock return createBlock
(ca, instr, new EmptyBlock(new Jump(FlowBlock.END_OF_METHOD))); (ma, instr, new EmptyBlock(new Jump(FlowBlock.END_OF_METHOD)));
case opc_getstatic: case opc_getstatic:
case opc_getfield: { case opc_getfield: {
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
return createNormal return createNormal
(ca, instr, new GetFieldOperator (ma, instr, new GetFieldOperator
(ca, opcode == opc_getstatic, ref)); (ma, opcode == opc_getstatic, ref));
} }
case opc_putstatic: case opc_putstatic:
case opc_putfield: { case opc_putfield: {
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
return createNormal return createNormal
(ca, instr, new StoreInstruction (ma, instr, new StoreInstruction
(new PutFieldOperator(ca, opcode == opc_putstatic, ref))); (new PutFieldOperator(ma, opcode == opc_putstatic, ref)));
} }
case opc_invokevirtual: case opc_invokevirtual:
case opc_invokespecial: case opc_invokespecial:
@ -312,51 +336,51 @@ public abstract class Opcodes implements jode.bytecode.Opcodes {
case opc_invokeinterface: { case opc_invokeinterface: {
Reference ref = (Reference) instr.objData; Reference ref = (Reference) instr.objData;
StructuredBlock block = createNormal StructuredBlock block = createNormal
(ca, instr, new InvokeOperator (ma, instr, new InvokeOperator
(ca, opcode == opc_invokestatic, (ma, opcode == opc_invokestatic,
opcode == opc_invokespecial, ref)); opcode == opc_invokespecial, ref));
return block; return block;
} }
case opc_new: { case opc_new: {
Type type = Type.tType((String) instr.objData); Type type = Type.tType((String) instr.objData);
ca.useType(type); ma.useType(type);
return createNormal(ca, instr, new NewOperator(type)); return createNormal(ma, instr, new NewOperator(type));
} }
case opc_arraylength: case opc_arraylength:
return createNormal return createNormal
(ca, instr, new ArrayLengthOperator()); (ma, instr, new ArrayLengthOperator());
case opc_athrow: case opc_athrow:
return createBlock return createBlock
(ca, instr, (ma, instr,
new ThrowBlock(new NopOperator(Type.tUObject))); new ThrowBlock(new NopOperator(Type.tUObject)));
case opc_checkcast: { case opc_checkcast: {
Type type = Type.tType((String) instr.objData); Type type = Type.tType((String) instr.objData);
ca.useType(type); ma.useType(type);
return createNormal return createNormal
(ca, instr, new CheckCastOperator(type)); (ma, instr, new CheckCastOperator(type));
} }
case opc_instanceof: { case opc_instanceof: {
Type type = Type.tType((String) instr.objData); Type type = Type.tType((String) instr.objData);
ca.useType(type); ma.useType(type);
return createNormal return createNormal
(ca, instr, new InstanceOfOperator(type)); (ma, instr, new InstanceOfOperator(type));
} }
case opc_monitorenter: case opc_monitorenter:
return createNormal(ca, instr, return createNormal(ma, instr,
new MonitorEnterOperator()); new MonitorEnterOperator());
case opc_monitorexit: case opc_monitorexit:
return createNormal(ca, instr, return createNormal(ma, instr,
new MonitorExitOperator()); new MonitorExitOperator());
case opc_multianewarray: { case opc_multianewarray: {
Type type = Type.tType((String) instr.objData); Type type = Type.tType((String) instr.objData);
ca.useType(type); ma.useType(type);
int dimension = instr.intData; int dimension = instr.intData;
return createNormal(ca, instr, return createNormal(ma, instr,
new NewArrayOperator(type, dimension)); new NewArrayOperator(type, dimension));
} }
case opc_ifnull: case opc_ifnonnull: case opc_ifnull: case opc_ifnonnull:
return createIfGoto return createIfGoto
(ca, instr, new CompareUnaryOperator (ma, instr, new CompareUnaryOperator
(Type.tUObject, opcode - (opc_ifnull-Operator.COMPARE_OP))); (Type.tUObject, opcode - (opc_ifnull-Operator.COMPARE_OP)));
default: default:
throw new jode.AssertError("Invalid opcode "+opcode); throw new jode.AssertError("Invalid opcode "+opcode);

@ -19,7 +19,7 @@
package jode.expr; package jode.expr;
import jode.type.Type; import jode.type.Type;
import jode.decompiler.CodeAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;
public class ClassFieldOperator extends NoArgOperator { public class ClassFieldOperator extends NoArgOperator {

@ -20,20 +20,20 @@
package jode.expr; package jode.expr;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.type.Type; import jode.type.Type;
import jode.decompiler.CodeAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.decompiler.ClassAnalyzer; import jode.decompiler.ClassAnalyzer;
import jode.decompiler.LocalInfo; import jode.decompiler.LocalInfo;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;
public class LocalLoadOperator extends Operator public class LocalLoadOperator extends Operator
implements LocalVarOperator { implements LocalVarOperator {
CodeAnalyzer codeAnalyzer; MethodAnalyzer methodAnalyzer;
LocalInfo local; LocalInfo local;
public LocalLoadOperator(Type type, CodeAnalyzer codeAnalyzer, public LocalLoadOperator(Type type, MethodAnalyzer methodAnalyzer,
LocalInfo local) { LocalInfo local) {
super(type); super(type);
this.codeAnalyzer = codeAnalyzer; this.methodAnalyzer = methodAnalyzer;
this.local = local; this.local = local;
local.setOperator(this); local.setOperator(this);
initOperands(0); initOperands(0);
@ -59,8 +59,8 @@ public class LocalLoadOperator extends Operator
return local.getLocalInfo(); return local.getLocalInfo();
} }
public void setCodeAnalyzer(CodeAnalyzer ca) { public void setMethodAnalyzer(MethodAnalyzer ma) {
codeAnalyzer = ca; methodAnalyzer = ma;
} }
public void setLocalInfo(LocalInfo newLocal) { public void setLocalInfo(LocalInfo newLocal) {
@ -78,8 +78,8 @@ public class LocalLoadOperator extends Operator
public void updateType() { public void updateType() {
if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0) if ((GlobalOptions.debuggingFlags & GlobalOptions.DEBUG_TYPES) != 0)
GlobalOptions.err.println("local "+local.getName()+" changed: " GlobalOptions.err.println("local "+local.getName()+" changed: "
+type+" to "+local.getType() +type+" to "+local.getType()
+" in "+parent); +" in "+parent);
updateParentType(local.getType()); updateParentType(local.getType());
} }

@ -20,7 +20,7 @@
package jode.expr; package jode.expr;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.type.Type; import jode.type.Type;
import jode.decompiler.CodeAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.decompiler.ClassAnalyzer; import jode.decompiler.ClassAnalyzer;
import jode.decompiler.LocalInfo; import jode.decompiler.LocalInfo;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;

@ -20,7 +20,7 @@
package jode.flow; package jode.flow;
import jode.expr.*; import jode.expr.*;
import jode.bytecode.Reference; import jode.bytecode.Reference;
import jode.decompiler.CodeAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.type.Type; import jode.type.Type;
public class CreateNewConstructor { public class CreateNewConstructor {
@ -81,12 +81,12 @@ public class CreateNewConstructor {
return false; return false;
/* Okay everything checked. */ /* Okay everything checked. */
CodeAnalyzer codeAna = constr.getCodeAnalyzer(); MethodAnalyzer methodAna = constr.getMethodAnalyzer();
Expression expr = ib.getInstruction(); Expression expr = ib.getInstruction();
Type appendType = appendCall.getMethodType().getParameterTypes()[0]; Type appendType = appendCall.getMethodType().getParameterTypes()[0];
if (!appendType.equals(Type.tString)) { if (!appendType.equals(Type.tString)) {
InvokeOperator valueOf = new InvokeOperator InvokeOperator valueOf = new InvokeOperator
(codeAna, true, false, (methodAna, true, false,
Reference.getReference("Ljava/lang/String;", "valueOf", Reference.getReference("Ljava/lang/String;", "valueOf",
"(" + appendType.getTypeSignature() "(" + appendType.getTypeSignature()
+ ")Ljava/lang/String;")); + ")Ljava/lang/String;"));
@ -94,7 +94,7 @@ public class CreateNewConstructor {
} }
ConstructorOperator newConstr = new ConstructorOperator ConstructorOperator newConstr = new ConstructorOperator
(Reference.getReference("Ljava/lang/StringBuffer;", "<init>", (Reference.getReference("Ljava/lang/StringBuffer;", "<init>",
"(Ljava/lang/String;)V"), codeAna, false); "(Ljava/lang/String;)V"), methodAna, false);
ic.setInstruction(newConstr.addOperand(expr)); ic.setInstruction(newConstr.addOperand(expr));
last.replace(sequBlock); last.replace(sequBlock);
return true; return true;

@ -22,7 +22,7 @@ import java.util.*;
import jode.GlobalOptions; import jode.GlobalOptions;
import jode.AssertError; import jode.AssertError;
import jode.decompiler.TabbedPrintWriter; import jode.decompiler.TabbedPrintWriter;
import jode.decompiler.CodeAnalyzer; import jode.decompiler.MethodAnalyzer;
import jode.decompiler.LocalInfo; import jode.decompiler.LocalInfo;
import jode.expr.Expression; import jode.expr.Expression;
import jode.expr.CombineableOperator; import jode.expr.CombineableOperator;
@ -55,10 +55,10 @@ public class FlowBlock {
} }
/** /**
* The code analyzer. This is used to pretty printing the * The method analyzer. This is used to pretty printing the
* Types and to get information about all locals in this code. * Types and to get information about all locals in this code.
*/ */
CodeAnalyzer code; MethodAnalyzer method;
/** /**
* The in locals. This are the locals, which are used in this * The in locals. This are the locals, which are used in this
@ -138,8 +138,8 @@ public class FlowBlock {
/** /**
* The default constructor. Creates a new empty flowblock. * The default constructor. Creates a new empty flowblock.
*/ */
public FlowBlock(CodeAnalyzer code, int addr, int length) { public FlowBlock(MethodAnalyzer method, int addr, int length) {
this.code = code; this.method = method;
this.addr = addr; this.addr = addr;
this.length = length; this.length = length;
} }
@ -148,9 +148,9 @@ public class FlowBlock {
* The default constructor. Creates a new flowblock containing * The default constructor. Creates a new flowblock containing
* only the given structured block. * only the given structured block.
*/ */
public FlowBlock(CodeAnalyzer code, int addr, int length, public FlowBlock(MethodAnalyzer method, int addr, int length,
StructuredBlock block) { StructuredBlock block) {
this.code = code; this.method = method;
this.addr = addr; this.addr = addr;
this.length = length; this.length = length;
setBlock(block); setBlock(block);

Loading…
Cancel
Save