private boolean hasManyPreceedingNullTests(int pc) { int ifNullTests = 0; BitSet seen = new BitSet(); try { for (Iterator<Location> i = classContext.getCFG(method).locationIterator(); i.hasNext();) { Location loc = i.next(); int pc2 = loc.getHandle().getPosition(); if (pc2 >= pc || pc2 < pc - 30) continue; Instruction ins = loc.getHandle().getInstruction(); if ((ins instanceof IFNONNULL || ins instanceof IFNULL || ins instanceof NullnessConversationInstruction) && !seen.get(pc2)) { ifNullTests++; seen.set(pc2); } } boolean result = ifNullTests > 2; // System.out.println("Preceeding null tests " + ifNullTests + " " + // ifNonnullTests + " " + result); return result; } catch (CFGBuilderException e) { return false; } }
public static boolean isNullCheck(InstructionHandle h, ConstantPoolGen cpg) { if (!(h.getInstruction() instanceof IFNONNULL)) return false; h = h.getNext(); final Instruction newInstruction = h.getInstruction(); if (!(newInstruction instanceof NEW)) return false; final ObjectType loadClassType = ((NEW) newInstruction).getLoadClassType(cpg); if (!loadClassType.getClassName().equals("java.lang.NullPointerException")) return false; h = h.getNext(); return check(h, NULLCHECK1) || check(h, NULLCHECK2); }
@Override public MatchResult match(InstructionHandle handle, ConstantPoolGen cpg, ValueNumberFrame before, ValueNumberFrame after, BindingSet bindingSet) throws DataflowAnalysisException { // Instruction must be IFNULL or IFNONNULL. Instruction ins = handle.getInstruction(); if (!(ins instanceof IFNULL || ins instanceof IFNONNULL)) return null; // Ensure reference used is consistent with previous uses of // same variable. LocalVariable ref = new LocalVariable(before.getTopValue()); return addOrCheckDefinition(ref, bindingSet); }
private void generateMethods(RootClass k, ConstantPoolGen cp, InstructionList il, InstructionFactory factory, ClassGen cg, String className) { RootMember[] members = k.getMembers(); for (int i = 0; i < members.length; i++) { BasicMember member = (BasicMember) members[i]; TLeaf leaf = (TLeaf) lMap.get(member); if (leaf == null) continue; String leafClassName = leaf.getClass().getName(); Type type = member.getJavaType(); Type arrayType = new ArrayType(type, 1); MethodGen mg = new MethodGen(ACC_PUBLIC, type, new Type[] { Type.INT }, new String[] { "index" }, nameMangler.mangleMember(member.getName()), className, il, cp); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField(className, member.getName(), arrayType)); il.append(InstructionFactory.DUP); BranchHandle bh = il.append(new IFNONNULL(null)); il.append(InstructionFactory.POP); il.append(factory.createGetStatic(className, member.getName() + "Leaf", new ObjectType(leafClassName))); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField("org.dianahep.root4j.core.Clones2", "hollowIndex", Type.LONG)); // BasicRootClass varClass = (BasicRootClass) member.getType(); il.append(factory.createInvoke(leafClassName, "setPosition", new ObjectType("org.dianahep.root4j.core.RootInput"), new Type[] { Type.LONG }, INVOKEVIRTUAL)); il.append(InstructionConstants.ALOAD_0); il.append(factory.createGetField("org.dianahep.root4j.core.Clones2", "size", Type.INT)); il.append((Instruction) factory.createNewArray(type, (short) 1)); il.append(InstructionConstants.DUP_X1); il.append(factory.createInvoke("org.dianahep.root4j.core.RootInput", "readFixedArray", Type.VOID, new Type[] { arrayType }, INVOKEINTERFACE)); il.append(InstructionConstants.DUP); il.append(InstructionConstants.ALOAD_0); il.append(InstructionConstants.SWAP); il.append(factory.createPutField(className, member.getName(), arrayType)); bh.setTarget(il.append(InstructionConstants.ILOAD_1)); il.append(InstructionFactory.createArrayLoad(type)); il.append(InstructionFactory.createReturn(type)); mg.setMaxStack(); mg.setMaxLocals(); cg.addMethod(mg.getMethod()); il.dispose(); } }