|
|
@ -28,13 +28,15 @@ import sun.tools.java.*; |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public abstract class Opcodes implements RuntimeConstants { |
|
|
|
public abstract class Opcodes implements RuntimeConstants { |
|
|
|
|
|
|
|
|
|
|
|
public final static Type ALL_INT_TYPE = MyType.tUInt; |
|
|
|
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 INT_TYPE = Type.tInt; |
|
|
|
public final static Type LONG_TYPE = Type.tLong; |
|
|
|
public final static Type LONG_TYPE = Type.tLong; |
|
|
|
public final static Type FLOAT_TYPE = Type.tFloat; |
|
|
|
public final static Type FLOAT_TYPE = Type.tFloat; |
|
|
|
public final static Type DOUBLE_TYPE = Type.tDouble; |
|
|
|
public final static Type DOUBLE_TYPE = Type.tDouble; |
|
|
|
public final static Type OBJECT_TYPE = MyType.tUObject; |
|
|
|
public final static Type OBJECT_TYPE = Type.tUObject; |
|
|
|
public final static Type BOOLEAN_TYPE = Type.tBoolean; |
|
|
|
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 BYTE_TYPE = Type.tByte; |
|
|
|
public final static Type CHAR_TYPE = Type.tChar; |
|
|
|
public final static Type CHAR_TYPE = Type.tChar; |
|
|
|
public final static Type SHORT_TYPE = Type.tShort; |
|
|
|
public final static Type SHORT_TYPE = Type.tShort; |
|
|
@ -42,9 +44,11 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final static Type types[][] = { |
|
|
|
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, |
|
|
|
{ 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) |
|
|
|
int[] cases, int[] dests) |
|
|
|
{ |
|
|
|
{ |
|
|
|
return new FlowBlock(ca, addr, length, |
|
|
|
return new FlowBlock(ca, addr, length, |
|
|
|
new SwitchBlock(new NopOperator(MyType.tInt), |
|
|
|
new SwitchBlock(new NopOperator(Type.tInt), |
|
|
|
cases, dests)); |
|
|
|
cases, dests)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -132,8 +136,11 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_aconst_null: |
|
|
|
case opc_aconst_null: |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 1, new ConstOperator(OBJECT_TYPE, "null")); |
|
|
|
(ca, addr, 1, new ConstOperator(OBJECT_TYPE, "null")); |
|
|
|
case opc_iconst_m1: |
|
|
|
case opc_iconst_0: case opc_iconst_1: |
|
|
|
case opc_iconst_0: case opc_iconst_1: case opc_iconst_2: |
|
|
|
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: |
|
|
|
case opc_iconst_3: case opc_iconst_4: case opc_iconst_5: |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 1, new ConstOperator |
|
|
|
(ca, addr, 1, new ConstOperator |
|
|
@ -160,7 +167,8 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_sipush: |
|
|
|
case opc_sipush: |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, new ConstOperator |
|
|
|
(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: { |
|
|
|
case opc_ldc: { |
|
|
|
int index = stream.readUnsignedByte(); |
|
|
|
int index = stream.readUnsignedByte(); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
@ -242,25 +250,25 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
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, addr, 1, new BinaryOperator |
|
|
|
(ca, addr, 1, new BinaryOperator |
|
|
|
(types[0][(opcode - opc_iadd)%4], |
|
|
|
(types[3][(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, addr, 1, new UnaryOperator |
|
|
|
(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_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, addr, 1, new ShiftOperator |
|
|
|
(ca, addr, 1, new ShiftOperator |
|
|
|
(types[0][(opcode - opc_ishl)%2], |
|
|
|
(types[3][(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, addr, 1, new BinaryOperator |
|
|
|
(ca, addr, 1, new BinaryOperator |
|
|
|
(types[0][(opcode - opc_iand)%2], |
|
|
|
(types[3][(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 local = stream.readUnsignedByte(); |
|
|
|
int local = stream.readUnsignedByte(); |
|
|
@ -271,6 +279,7 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
operation = Operator.NEG_OP; |
|
|
|
operation = Operator.NEG_OP; |
|
|
|
} |
|
|
|
} |
|
|
|
LocalInfo li = ca.getLocalInfo(addr, local); |
|
|
|
LocalInfo li = ca.getLocalInfo(addr, local); |
|
|
|
|
|
|
|
li.setType(ALL_INT_TYPE); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, new IIncOperator |
|
|
|
(ca, addr, 3, new IIncOperator |
|
|
|
(li, Integer.toString(value), |
|
|
|
(li, Integer.toString(value), |
|
|
@ -285,36 +294,48 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
if (to >= from) |
|
|
|
if (to >= from) |
|
|
|
to++; |
|
|
|
to++; |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 1, new ConvertOperator(types[0][from], |
|
|
|
(ca, addr, 1, new ConvertOperator(types[3][from], |
|
|
|
types[0][to])); |
|
|
|
types[3][to])); |
|
|
|
} |
|
|
|
} |
|
|
|
case opc_i2b: case opc_i2c: case opc_i2s: |
|
|
|
case opc_i2b: case opc_i2c: case opc_i2s: |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 1, new ConvertOperator |
|
|
|
(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_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, addr, 1, new CompareToIntOperator |
|
|
|
(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: |
|
|
|
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: |
|
|
|
case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: |
|
|
|
return createIfGoto |
|
|
|
return createIfGoto |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
new CompareUnaryOperator |
|
|
|
new CompareUnaryOperator |
|
|
|
(ALL_INT_TYPE, opcode - opc_ifeq+Operator.COMPARE_OP)); |
|
|
|
(ALL_INT_TYPE, opcode - opc_ifeq+Operator.COMPARE_OP)); |
|
|
|
case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmplt: |
|
|
|
case opc_if_icmpeq: case opc_if_icmpne: |
|
|
|
case opc_if_icmpge: case opc_if_icmpgt: case opc_if_icmple: |
|
|
|
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 |
|
|
|
return createIfGoto |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
new CompareBinaryOperator |
|
|
|
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: |
|
|
|
case opc_if_acmpeq: case opc_if_acmpne: |
|
|
|
return createIfGoto |
|
|
|
return createIfGoto |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
(ca, addr, 3, addr+stream.readShort(), |
|
|
|
new CompareBinaryOperator |
|
|
|
new CompareBinaryOperator |
|
|
|
(OBJECT_TYPE, opcode - opc_if_acmpeq+Operator.COMPARE_OP)); |
|
|
|
(OBJECT_TYPE, |
|
|
|
|
|
|
|
opcode - opc_if_acmpeq+Operator.COMPARE_OP)); |
|
|
|
case opc_goto: |
|
|
|
case opc_goto: |
|
|
|
return createGoto |
|
|
|
return createGoto |
|
|
|
(ca, addr, 3, addr+stream.readShort()); |
|
|
|
(ca, addr, 3, addr+stream.readShort()); |
|
|
@ -360,9 +381,9 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
} |
|
|
|
} |
|
|
|
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 = MyType.tSubType(MyType.intersection |
|
|
|
Type retType = |
|
|
|
(ca.getMethod().mdef.getType().getReturnType(), |
|
|
|
Type.tSubType(Type.tType(ca.getMethod().mdef.getType() |
|
|
|
types[0][opcode-opc_ireturn])); |
|
|
|
.getReturnType())); |
|
|
|
return createBlock |
|
|
|
return createBlock |
|
|
|
(ca, addr, 1, new ReturnBlock(new NopOperator(retType))); |
|
|
|
(ca, addr, 1, new ReturnBlock(new NopOperator(retType))); |
|
|
|
} |
|
|
|
} |
|
|
@ -405,7 +426,7 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_new: { |
|
|
|
case opc_new: { |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) |
|
|
|
ca.env.getConstant(stream.readUnsignedShort()); |
|
|
|
ca.env.getConstant(stream.readUnsignedShort()); |
|
|
|
Type type = MyType.tClassOrArray(cldec.getName()); |
|
|
|
Type type = Type.tClassOrArray(cldec.getName()); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, new NewOperator(type, ca.env.getTypeString(type))); |
|
|
|
(ca, addr, 3, new NewOperator(type, ca.env.getTypeString(type))); |
|
|
|
} |
|
|
|
} |
|
|
@ -425,17 +446,17 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
} |
|
|
|
} |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 2, |
|
|
|
(ca, addr, 2, |
|
|
|
new NewArrayOperator(MyType.tArray(type), |
|
|
|
new NewArrayOperator(Type.tArray(type), |
|
|
|
type.toString(), 1)); |
|
|
|
type.toString(), 1)); |
|
|
|
} |
|
|
|
} |
|
|
|
case opc_anewarray: { |
|
|
|
case opc_anewarray: { |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
Identifier ident = cldec.getName(); |
|
|
|
Identifier ident = cldec.getName(); |
|
|
|
Type type = MyType.tClassOrArray(cldec.getName()); |
|
|
|
Type type = Type.tClassOrArray(cldec.getName()); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, new NewArrayOperator |
|
|
|
(ca, addr, 3, new NewArrayOperator |
|
|
|
(MyType.tArray(type), ca.env.getTypeString(type),1)); |
|
|
|
(Type.tArray(type), ca.env.getTypeString(type),1)); |
|
|
|
} |
|
|
|
} |
|
|
|
case opc_arraylength: |
|
|
|
case opc_arraylength: |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
@ -443,11 +464,11 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_athrow: |
|
|
|
case opc_athrow: |
|
|
|
return createBlock |
|
|
|
return createBlock |
|
|
|
(ca, addr, 1, |
|
|
|
(ca, addr, 1, |
|
|
|
new ThrowBlock(new NopOperator(MyType.tUObject))); |
|
|
|
new ThrowBlock(new NopOperator(Type.tUObject))); |
|
|
|
case opc_checkcast: { |
|
|
|
case opc_checkcast: { |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
Type type = MyType.tClassOrArray(cldec.getName()); |
|
|
|
Type type = Type.tClassOrArray(cldec.getName()); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, new CheckCastOperator |
|
|
|
(ca, addr, 3, new CheckCastOperator |
|
|
|
(type, ca.env.getTypeString(type))); |
|
|
|
(type, ca.env.getTypeString(type))); |
|
|
@ -455,7 +476,7 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_instanceof: { |
|
|
|
case opc_instanceof: { |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
Type type = MyType.tClassOrArray(cldec.getName()); |
|
|
|
Type type = Type.tClassOrArray(cldec.getName()); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 3, |
|
|
|
(ca, addr, 3, |
|
|
|
new InstanceOfOperator(type, ca.env.getTypeString(type))); |
|
|
|
new InstanceOfOperator(type, ca.env.getTypeString(type))); |
|
|
@ -492,6 +513,7 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
operation = Operator.NEG_OP; |
|
|
|
operation = Operator.NEG_OP; |
|
|
|
} |
|
|
|
} |
|
|
|
LocalInfo li = ca.getLocalInfo(addr, local); |
|
|
|
LocalInfo li = ca.getLocalInfo(addr, local); |
|
|
|
|
|
|
|
li.setType(ALL_INT_TYPE); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 6, new IIncOperator |
|
|
|
(ca, addr, 6, new IIncOperator |
|
|
|
(li, Integer.toString(value), |
|
|
|
(li, Integer.toString(value), |
|
|
@ -508,11 +530,11 @@ public abstract class Opcodes implements RuntimeConstants { |
|
|
|
case opc_multianewarray: { |
|
|
|
case opc_multianewarray: { |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
ClassDeclaration cldec = (ClassDeclaration) ca.env.getConstant |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
(stream.readUnsignedShort()); |
|
|
|
Type type = MyType.tClassOrArray(cldec.getName()); |
|
|
|
Type type = Type.tClassOrArray(cldec.getName()); |
|
|
|
int dimension = stream.readUnsignedByte(); |
|
|
|
int dimension = stream.readUnsignedByte(); |
|
|
|
Type baseType = type; |
|
|
|
Type baseType = type; |
|
|
|
for (int i=0; i<dimension; i++) |
|
|
|
for (int i=0; i<dimension; i++) |
|
|
|
baseType = baseType.getElementType(); |
|
|
|
baseType = ((ArrayType)baseType).getElementType(); |
|
|
|
return createNormal |
|
|
|
return createNormal |
|
|
|
(ca, addr, 4, |
|
|
|
(ca, addr, 4, |
|
|
|
new NewArrayOperator |
|
|
|
new NewArrayOperator |
|
|
|