private static void clearRegisterLoad(List<Item> list, int register) { for (int pos=0; pos<list.size(); pos++) { Item i = list.get(pos); if(i != null && (i.registerNumber == register || i.fieldLoadedFromRegister == register)) { i = new Item(i); if (i.registerNumber == register) { i.registerNumber = -1; } if (i.fieldLoadedFromRegister == register) { i.fieldLoadedFromRegister = -1; } list.set(pos, i); } } }
public Item getStackItem(int stackOffset) { if (stackOffset < 0 || stackOffset >= stack.size()) { AnalysisContext.logError("Can't get stack offset " + stackOffset + " from " + stack.toString() + " @ " + v.getPC() + " in " + v.getFullyQualifiedMethodName(), new IllegalArgumentException(stackOffset + " is not a value stack offset")); return new Item("Lfindbugs/OpcodeStackError;"); } int tos = stack.size() - 1; int pos = tos - stackOffset; try { return stack.get(pos); } catch (ArrayIndexOutOfBoundsException e) { throw new ArrayIndexOutOfBoundsException("Requested item at offset " + stackOffset + " in a stack of size " + stack.size() + ", made request for position " + pos); } }
private void pushByDoubleMath(int seen, Item it, Item it2) { Item result; @SpecialKind int specialKind = Item.FLOAT_MATH; if ((it.getConstant() instanceof Double) && it2.getConstant() instanceof Double) { if (seen == Const.DADD) { result = new Item("D", Double.valueOf(constantToDouble(it2) + constantToDouble(it))); } else if (seen == Const.DSUB) { result = new Item("D", Double.valueOf(constantToDouble(it2) - constantToDouble(it))); } else if (seen == Const.DMUL) { result = new Item("D", Double.valueOf(constantToDouble(it2) * constantToDouble(it))); } else if (seen == Const.DDIV) { result = new Item("D", Double.valueOf(constantToDouble(it2) / constantToDouble(it))); } else if (seen == Const.DREM) { result = new Item("D", Double.valueOf(constantToDouble(it2) % constantToDouble(it))); } else { result = new Item("D"); // ? } } else { result = new Item("D"); if (seen == Const.DDIV) { specialKind = Item.NASTY_FLOAT_MATH; } } result.setSpecialKind(specialKind); push(result); }
private void handleFcmp(int opcode) { Item it = pop(); Item it2 = pop(); if ((it.getConstant() != null) && it2.getConstant() != null) { float f = constantToFloat(it); float f2 = constantToFloat(it2); if (Float.isNaN(f) || Float.isNaN(f2)) { if (opcode == Const.FCMPG) { push(new Item("I", Integer.valueOf(1))); } else { push(new Item("I", Integer.valueOf(-1))); } } if (f2 < f) { push(new Item("I", Integer.valueOf(-1))); } else if (f2 > f) { push(new Item("I", Integer.valueOf(1))); } else { push(new Item("I", Integer.valueOf(0))); } } else { push(new Item("I")); } }
private void pushByInvoke(DismantleBytecode dbc, boolean popThis) { String signature = dbc.getSigConstantOperand(); if (Const.CONSTRUCTOR_NAME.equals(dbc.getNameConstantOperand()) && signature.endsWith(")V") && popThis) { pop(PreorderVisitor.getNumberArguments(signature)); Item constructed = pop(); if (getStackDepth() > 0) { Item next = getStackItem(0); if (constructed.equals(next)) { next = new Item(next); next.source = XFactory.createReferencedXMethod(dbc); next.pc = dbc.getPC(); replace(0, next); } } return; } pop(PreorderVisitor.getNumberArguments(signature) + (popThis ? 1 : 0)); pushBySignature(new SignatureParser(signature).getReturnTypeSignature(), dbc); }
private void pushByConstant(DismantleBytecode dbc, Constant c) { if (c instanceof ConstantClass) { push(new Item("Ljava/lang/Class;", ((ConstantClass) c).getConstantValue(dbc.getConstantPool()))); } else if (c instanceof ConstantInteger) { push(new Item("I", Integer.valueOf(((ConstantInteger) c).getBytes()))); } else if (c instanceof ConstantString) { int s = ((ConstantString) c).getStringIndex(); push(new Item("Ljava/lang/String;", getStringFromIndex(dbc, s))); } else if (c instanceof ConstantFloat) { push(new Item("F", Float.valueOf(((ConstantFloat) c).getBytes()))); } else if (c instanceof ConstantDouble) { push(new Item("D", Double.valueOf(((ConstantDouble) c).getBytes()))); } else if (c instanceof ConstantLong) { push(new Item("J", Long.valueOf(((ConstantLong) c).getBytes()))); } else { throw new UnsupportedOperationException("StaticConstant type not expected"); } }
private void handleLcmp() { Item it = pop(); Item it2 = pop(); if ((it.getConstant() != null) && it2.getConstant() != null) { long l = constantToLong(it); long l2 = constantToLong(it2); if (l2 < l) { push(new Item("I", Integer.valueOf(-1))); } else if (l2 > l) { push(new Item("I", Integer.valueOf(1))); } else { push(new Item("I", Integer.valueOf(0))); } } else { push(new Item("I")); } }
private void pushByLocalLoad(String signature, int register) { Item oldItem = new Item(getLVValue(register)); Item newItem = oldItem; if ("Ljava/lang/Object;".equals(newItem.signature) && !"Ljava/lang/Object;".equals(signature)) { newItem = new Item(oldItem); newItem.signature = signature; } if (newItem.getRegisterNumber() < 0) { if (newItem == oldItem) { newItem = new Item(oldItem); } newItem.registerNumber = register; } push(newItem); }
private void pushBySignature(String s, DismantleBytecode dbc) { if ("V".equals(s)) { return; } Item item = new Item(s, (Object) null); if (dbc != null) { item.setPC(dbc.getPC()); } if ("B".equals(s)) { item.setSpecialKind(Item.SIGNED_BYTE); } else if ("C".equals(s)) { item.setSpecialKind(Item.NON_NEGATIVE); } push(item); }
@Test public void testDefinedItemKindIsUsedInToStringMethod() { int defined = OpcodeStack.Item.defineSpecialKind(NEW_ITEM_KIND_NAME); OpcodeStack.Item intItem = new OpcodeStack.Item("I"); intItem.setSpecialKind(defined); String result = intItem.toString(); assertTrue("Item.toString() does not use proper name of special kind:" + result, result.contains(NEW_ITEM_KIND_NAME)); } }
@Test public void testMergeIntAndZero() { OpcodeStack.Item intItem = new OpcodeStack.Item("I"); OpcodeStack.Item zeroItem = new OpcodeStack.Item("I", 0); OpcodeStack.Item m1 = OpcodeStack.Item.merge(intItem, zeroItem); assertNull(m1.getConstant()); OpcodeStack.Item m2 = OpcodeStack.Item.merge(zeroItem, intItem); assertNull(m2.getConstant()); }
public Item cloneAndSetSpecialKind(@SpecialKind int specialKind) { Item that = new Item(this); that.specialKind = specialKind; return that; }
public static Item typeOnly(String signature) { Item it = new Item(signature, UNKNOWN); it.setSpecialKind(TYPE_ONLY); return it; } public Item(Item it) {
public static Item initialArgument(String signature, int reg) { Item it = new Item(signature); it.setInitialParameter(true); it.registerNumber = reg; return it; } public Item(String signature) {
@Test public void testMergeTypeOnly() { OpcodeStack.Item intOnly = OpcodeStack.Item.typeOnly("I"); OpcodeStack.Item zeroItem = new OpcodeStack.Item("I", 0); OpcodeStack.Item m1 = OpcodeStack.Item.merge(intOnly, zeroItem); assertEquals(0,m1.getConstant()); OpcodeStack.Item m2 = OpcodeStack.Item.merge(zeroItem, intOnly); assertEquals(0,m2.getConstant()); }
public static Item nullItem(String signature) { Item item = new Item(signature); item.constValue = null; item.setNull(true); return item; }
public OpcodeStack.Item getSummary(XField field) { if (field == null) { return new OpcodeStack.Item(); } OpcodeStack.Item result = summary.get(field); if (result == null || field.isVolatile()) { String signature = field.getSignature(); return new OpcodeStack.Item(signature); } return result; }
private void pushByLocalStore(int register) { Item it = new Item(pop()); if (it.getRegisterNumber() != register) { clearRegisterLoad(lvValues, register); clearRegisterLoad(stack, register); } if (it.registerNumber == -1) { it.registerNumber = register; } setLVValue(register, it); }
@Override public void sawOpcode(int seen) { if (seen != Const.PUTFIELD) { return; } XField xFieldOperand = getXFieldOperand(); if (xFieldOperand != null && xFieldOperand.equals(targetField) && stack.getStackItem(1).getRegisterNumber() == 0) { putfields.put(getPC(), new OpcodeStack.Item(stack.getStackItem(0))); } }