📄 constantanalyzer.java
字号:
case opc_lneg: newValue = new Long (- ((Long)value.value).longValue()); break; case opc_fneg: newValue = new Float (- ((Float)value.value).floatValue()); break; case opc_dneg: newValue = new Double (- ((Double)value.value).doubleValue()); break; default: throw new jode.AssertError("Can't happen."); } info.constInfo = new ConstantInfo(CONSTANT, newValue); result = new ConstValue(newValue); result.addConstantListener(info.constInfo); value.addConstantListener(result); } else result = unknownValue[size-1]; mergeInfo(instr.getNextByAddr(), info.poppush(size, result)); break; } case opc_ishl: case opc_lshl: case opc_ishr: case opc_lshr: case opc_iushr: case opc_lushr: { int size = 1 + (opcode - opc_iadd & 1); ConstValue value1 = info.getStack(size+1); ConstValue value2 = info.getStack(1); if (value1.value != ConstValue.VOLATILE && value2.value != ConstValue.VOLATILE) { Object newValue; switch (opcode) { case opc_ishl: newValue = new Integer (((Integer)value1.value).intValue() << ((Integer)value2.value).intValue()); break; case opc_ishr: newValue = new Integer (((Integer)value1.value).intValue() >> ((Integer)value2.value).intValue()); break; case opc_iushr: newValue = new Integer (((Integer)value1.value).intValue() >>> ((Integer)value2.value).intValue()); break; case opc_lshl: newValue = new Long (((Long)value1.value).longValue() << ((Integer)value2.value).intValue()); break; case opc_lshr: newValue = new Long (((Long)value1.value).longValue() >> ((Integer)value2.value).intValue()); break; case opc_lushr: newValue = new Long (((Long)value1.value).longValue() >>> ((Integer)value2.value).intValue()); break; default: throw new jode.AssertError("Can't happen."); } info.constInfo = new ConstantInfo(CONSTANT, newValue); result = new ConstValue(newValue); result.addConstantListener(info.constInfo); value1.addConstantListener(result); value2.addConstantListener(result); } else result = unknownValue[size-1]; mergeInfo(instr.getNextByAddr(), info.poppush(size+1, result)); break; } case opc_iinc: { ConstValue local = info.getLocal(instr.getLocalSlot()); if (local.value != ConstValue.VOLATILE) { result = new ConstValue (new Integer(((Integer)local.value).intValue() + instr.getIncrement())); local.addConstantListener(result); } else result = unknownValue[0]; mergeInfo(instr.getNextByAddr(), info.copy().setLocal(instr.getLocalSlot(), result)); break; } case opc_i2l: case opc_i2f: case opc_i2d: case opc_l2i: case opc_l2f: case opc_l2d: case opc_f2i: case opc_f2l: case opc_f2d: case opc_d2i: case opc_d2l: case opc_d2f: { int insize = 1 + ((opcode - opc_i2l) / 3 & 1); ConstValue stack = info.getStack(insize); if (stack.value != ConstValue.VOLATILE) { Object newVal; switch(opcode) { case opc_l2i: case opc_f2i: case opc_d2i: newVal = new Integer(((Number)stack.value).intValue()); break; case opc_i2l: case opc_f2l: case opc_d2l: newVal = new Long(((Number)stack.value).longValue()); break; case opc_i2f: case opc_l2f: case opc_d2f: newVal = new Float(((Number)stack.value).floatValue()); break; case opc_i2d: case opc_l2d: case opc_f2d: newVal = new Double(((Number)stack.value).doubleValue()); break; default: throw new jode.AssertError("Can't happen."); } info.constInfo = new ConstantInfo(CONSTANT, newVal); result = new ConstValue(newVal); result.addConstantListener(info.constInfo); stack.addConstantListener(result); } else { switch (opcode) { case opc_i2l: case opc_f2l: case opc_d2l: case opc_i2d: case opc_l2d: case opc_f2d: result = unknownValue[1]; break; default: result = unknownValue[0]; } } mergeInfo(instr.getNextByAddr(), info.poppush(insize, result)); break; } case opc_i2b: case opc_i2c: case opc_i2s: { ConstValue stack = info.getStack(1); if (stack.value != ConstValue.VOLATILE) { int val = ((Integer)stack.value).intValue(); switch(opcode) { case opc_i2b: val = (byte) val; break; case opc_i2c: val = (char) val; break; case opc_i2s: val = (short) val; break; } Integer newVal = new Integer(val); info.constInfo = new ConstantInfo(CONSTANT, newVal); result = new ConstValue(newVal); stack.addConstantListener(info.constInfo); stack.addConstantListener(result); } else result = unknownValue[0]; mergeInfo(instr.getNextByAddr(), info.poppush(1, result)); break; } case opc_lcmp: { ConstValue val1 = info.getStack(4); ConstValue val2 = info.getStack(2); if (val1.value != ConstValue.VOLATILE && val2.value != ConstValue.VOLATILE) { long value1 = ((Long) val1.value).longValue(); long value2 = ((Long) val1.value).longValue(); Integer newVal = new Integer(value1 == value2 ? 0 : value1 < value2 ? -1 : 1); info.constInfo = new ConstantInfo(CONSTANT, newVal); result = new ConstValue(newVal); result.addConstantListener(info.constInfo); val1.addConstantListener(result); val2.addConstantListener(result); } else result = unknownValue[0]; mergeInfo(instr.getNextByAddr(), info.poppush(4, result)); break; } case opc_fcmpl: case opc_fcmpg: { ConstValue val1 = info.getStack(2); ConstValue val2 = info.getStack(1); if (val1.value != ConstValue.VOLATILE && val2.value != ConstValue.VOLATILE) { float value1 = ((Float) val1.value).floatValue(); float value2 = ((Float) val1.value).floatValue(); Integer newVal = new Integer (value1 == value2 ? 0 : ( opcode == opc_fcmpg ? (value1 < value2 ? -1 : 1) : (value1 > value2 ? 1 : -1))); info.constInfo = new ConstantInfo(CONSTANT, newVal); result = new ConstValue(newVal); result.addConstantListener(info.constInfo); val1.addConstantListener(result); val2.addConstantListener(result); } else result = unknownValue[0]; mergeInfo(instr.getNextByAddr(), info.poppush(2, result)); break; } case opc_dcmpl: case opc_dcmpg: { ConstValue val1 = info.getStack(4); ConstValue val2 = info.getStack(2); if (val1.value != ConstValue.VOLATILE && val2.value != ConstValue.VOLATILE) { double value1 = ((Double) val1.value).doubleValue(); double value2 = ((Double) val1.value).doubleValue(); Integer newVal = new Integer (value1 == value2 ? 0 : ( opcode == opc_dcmpg ? (value1 < value2 ? -1 : 1) : (value1 > value2 ? 1 : -1))); info.constInfo = new ConstantInfo(CONSTANT, newVal); result = new ConstValue(newVal); result.addConstantListener(info.constInfo); val1.addConstantListener(result); val2.addConstantListener(result); } else result = unknownValue[0]; mergeInfo(instr.getNextByAddr(), info.poppush(4, result)); break; } case opc_ifeq: case opc_ifne: case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: 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_acmpeq: case opc_if_acmpne: case opc_ifnull: case opc_ifnonnull: { int size = 1; ConstValue stacktop = info.getStack(1); ConstValue other = null; boolean known = stacktop.value != ConstValue.VOLATILE; if (opcode >= opc_if_icmpeq && opcode <= opc_if_acmpne) { other = info.getStack(2); size = 2; known &= other.value != ConstValue.VOLATILE; } if (known) { stacktop.addConstantListener(info); if (other != null) other.addConstantListener(info); Instruction pc = instr.getNextByAddr(); int opc_mask; if (opcode >= opc_if_acmpeq) { if (opcode >= opc_ifnull) { opc_mask = stacktop.value == null ? CMP_EQUAL_MASK : CMP_GREATER_MASK; opcode -= opc_ifnull; } else { opc_mask = stacktop.value == other.value ? CMP_EQUAL_MASK : CMP_GREATER_MASK; opcode -= opc_if_acmpeq; } } else { int value = ((Integer) stacktop.value).intValue(); if (opcode >= opc_if_icmpeq) { int val1 = ((Integer) other.value).intValue(); opc_mask = (val1 == value ? CMP_EQUAL_MASK : val1 < value ? CMP_LESS_MASK : CMP_GREATER_MASK); opcode -= opc_if_icmpeq; } else { opc_mask = (value == 0 ? CMP_EQUAL_MASK : value < 0 ? CMP_LESS_MASK : CMP_GREATER_MASK); opcode -= opc_ifeq; } } if ((opc_mask & (1<<opcode)) != 0) pc = instr.getSingleSucc(); info.constInfo = new ConstantInfo(CONSTANTFLOW, pc); mergeInfo(pc, info.pop(size)); } else { mergeInfo(instr.getNextByAddr(), info.pop(size)); mergeInfo(instr.getSingleSucc(), info.pop(size)); } break; } case opc_goto: mergeInfo(instr.getSingleSucc(), info.copy()); break; case opc_lookupswitch: { ConstValue stacktop = info.getStack(1); if (stacktop.value != ConstValue.VOLATILE) { stacktop.addConstantListener(info); Instruction pc; int value = ((Integer) stacktop.value).intValue(); int[] values = instr.getValues(); pc = instr.getSuccs()[values.length]; for (int i=0; i< values.length; i++) { if (values[i] == value) { pc = instr.getSuccs()[i]; break; } } info.constInfo = new ConstantInfo(CONSTANTFLOW, pc); mergeInfo(pc, info.pop(1)); } else { for (int i=0; i < instr.getSuccs().length; i++) mergeInfo(instr.getSuccs()[i], info.pop(1)); } break; } case opc_jsr:// dumpStackLocalInfo();// System.err.println(instr); if (instr.getSingleSucc().getOpcode() != opc_astore) throw new RuntimeException("Can't handle jsr to non astores"); StackLocalInfo oldJsrInfo = (StackLocalInfo) instr.getSingleSucc().getTmpInfo(); if (oldJsrInfo != null) { result = oldJsrInfo.getStack(1); if (oldJsrInfo.retInfo != null && result.value instanceof JSRTargetInfo) { mergeInfo(instr.getNextByAddr(), info.copy() .mergeRetLocals((JSRTargetInfo) result.value, oldJsrInfo.retInfo)); } } else { result = new ConstValue (new JSRTargetInfo(instr.getSingleSucc())); } mergeInfo(instr.getSingleSucc(), info.poppush(0, result)); break; case opc_ret: {// dumpStackLocalInfo();// System.err.println(instr); result = info.getLocal(instr.getLocalSlot()); JSRTargetInfo jsrInfo = (JSRTargetInfo) result.value; jsrInfo.setRetInfo(info); result.addConstantListener(info); Instruction jsrTarget = jsrInfo.jsrTarget; StackLocalInfo jsrTargetStackInfo = (StackLocalInfo) jsrTarget.getTmpInfo(); jsrTargetStackInfo.retInfo = info; jsrTargetStackInfo.constInfo.flags |= RETURNINGJSR; Instruction[] jsrs = jsrTarget.getPreds(); for (int i=0; i < jsrs.length; i++) { Instruction jsr = jsrs[i]; if (jsr.getTmpInfo() != null) { mergeInfo(jsr.getNextByAddr(), ((StackLocalInfo) jsr.getTmpInfo()).copy() .mergeRetLocals(jsrInfo, info)); } } break; } case opc_ireturn: case opc_lreturn: case opc_freturn: case opc_dreturn: case opc_areturn: case opc_return: case opc_athrow: break; case opc_putstatic: case opc_putfield: { FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr); Reference ref = instr.getReference(); int size = TypeSignature.getTypeSize(ref.getType()); if (fi != null && !fi.isNotConstant()) { ConstValue stacktop = info.getStack(size); Object fieldVal = fi.getConstant(); if (fieldVal == null) fieldVal = runtime.getDefaultValue(ref.getType()); if (stacktop.value == null ? fieldVal == null : stacktop.value.equals(fieldVal)) { stacktop.addConstantListener(info); } else { fi.setNotConstant(); fieldNotConstant(fi); } } size += (opcode == opc_putstatic) ? 0 : 1; mergeInfo(instr.getNextByAddr(), info.pop(size)); break; } case opc_getstatic: case opc_getfield: { int size = (opcode == opc_getstatic) ? 0 : 1; FieldIdentifier fi = (FieldIdentifier) canonizeReference(instr); Reference ref = instr.getReference(); int typesize = TypeSignature.getTypeSize(ref.getType()); if (fi != null) { if (fi.isNotConstant()) { fi.setReachable(); result = unknownValue[typesize - 1]; } else { Object obj = fi.getConstant(); if (obj == null) obj = runtime.getDefaultValue(ref.getType()); info.constInfo = new ConstantInfo(CONSTANT, obj); result = new ConstValue(obj); result.addConstantListener(info.constInfo); fi.addFieldListener(fieldListener); } } else result = unknownValue[typesize - 1]; mergeInfo(instr.getNextByAddr(), info.poppush(size, result)); break; } case opc_invokespecial: case opc_invokestatic: case opc_invokeinterface: case opc_invokevirtual: { canonizeReference(instr); Reference ref = instr.getReference(); boolean constant = true; int size = 0; Object cls = null; String[] paramTypes = TypeSignature.getParameterTypes(ref.getType()); Object[] args = new Object[paramTypes.length]; ConstValue clsValue = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -