CFG createCFG(String className) throws ClassNotFoundException { CFG cfg = new CFG(); JavaClass jc = Repository.lookupClass(className); ClassGen cg = new ClassGen(jc); ConstantPoolGen cpg = cg.getConstantPool(); for (Method m : cg.getMethods()) { MethodGen mg = new MethodGen(m, cg.getClassName(), cpg); InstructionList il = mg.getInstructionList(); InstructionHandle[] handles = il.getInstructionHandles(); int prev = 0; for (InstructionHandle ih : handles) { int position = ih.getPosition(); cfg.addNode(position, m, jc); Instruction inst = ih.getInstruction(); boolean br = inst.getName().contains("if") || inst.getName().contains("goto"); boolean ret = inst.getName().contains("return"); boolean stat = inst.getName().contains("invokestatic"); int len = inst.getLength(); if (stat) { int index = inst.toString(true).indexOf(" "); String name = inst.toString(true).substring(index + 1); int tar = Integer.valueOf(name); INVOKESTATIC inv = new INVOKESTATIC(tar); name = inv.getMethodName(cpg); Method m2 = null; Method[] tm = cg.getMethods(); for (int i = 0; i < tm.length; i++) { if (tm[i].getName().equals(name)) { m2 = tm[i]; } } cfg.addEdge(position, m, jc, 0, m2, jc); cfg.addEdge(-1, m2, jc, position + len, m, jc); } if (!ret && !stat) { cfg.addEdge(position, position + len, m, jc); } if (br) { cfg.addEdge(position, position + len, m, jc); IF_ICMPGE comp = new IF_ICMPGE(ih); String name = comp.getTarget().toString(false); int index = name.indexOf(">"); name = name.substring(index + 2); int tar = Integer.valueOf(name); cfg.addEdge(position, tar, m, jc); } if (ret) { cfg.addEdge(position, -1, m, jc); } prev = position; } System.out.println(cfg.toString()); } return cfg; }
// Returns false on encountering something that can't be analyzed properly static boolean breakIntoPaths( List<CodePath> paths, List<PathInstruction> previousInstructions, int index, CFG cfg, MethodNode m, int maxPaths) { // Get the next instruction and check if we can handle it AbstractInsnNode instruction = m.instructions.get(index); // TODO: various control-flow instructions that we don't currently handle if (instruction instanceof LookupSwitchInsnNode) return false; if (instruction instanceof TableSwitchInsnNode) return false; if (instruction.getOpcode() == Opcodes.JSR) return false; if (instruction.getOpcode() == Opcodes.RET) return false; // Handle conditional branches specially if (instruction instanceof JumpInsnNode && instruction.getOpcode() != Opcodes.GOTO) { int nextIndex = index + 1; int branchIndex = index + 1; for (int next : cfg.succsOf(index)) if (next != nextIndex) branchIndex = next; // Add the instruction to the path, recurse, then remove the instruction previousInstructions.add(PathInstruction.branch(instruction, true)); if (!breakIntoPaths(paths, previousInstructions, branchIndex, cfg, m, maxPaths)) return false; previousInstructions.remove(previousInstructions.size() - 1); // Add the instruction to the path, recurse, then remove the instruction previousInstructions.add(PathInstruction.branch(instruction, false)); if (!breakIntoPaths(paths, previousInstructions, nextIndex, cfg, m, maxPaths)) return false; previousInstructions.remove(previousInstructions.size() - 1); } else if (cfg.succsOf(index) != null) { // Add the instruction to the path, recurse, then remove the instruction assert (cfg.succsOf(index).size() == 1); int nextIndex = cfg.succsOf(index).get(0); previousInstructions.add(new PathInstruction(instruction)); if (!breakIntoPaths(paths, previousInstructions, nextIndex, cfg, m, maxPaths)) return false; previousInstructions.remove(previousInstructions.size() - 1); } else { // We've reached the end of a path, so record it previousInstructions.add(new PathInstruction(instruction)); paths.add(new CodePath(previousInstructions)); previousInstructions.remove(previousInstructions.size() - 1); // Abort if there are too many paths if (paths.size() > maxPaths) return false; } return true; }
/** * Constructs a nullable set for the given grammar. * * @param g */ public NullableNonterminals(CFG g) { super(); // Construct Nullable Nonterminals List<Production> productions = g.productions(); boolean changing = true; while (changing) { changing = false; for (Production p : productions) { Token left = p.leftHandSide(); if (!nullable.contains(left)) { if (p.goesToEpsilon()) { nullable.add(left); changing = true; } else { List<Token> rhs = p.rightHandSide(); boolean all_nullable = true; for (Token right : rhs) { if (!nullable.contains(right)) { all_nullable = false; break; } } if (all_nullable) { nullable.add(left); changing = true; } } } } } // --------------------------------------------------------------------- /* * Stores an immutable version of the non-terminal set to avoid * accidentally mutating it later. */ this.nullable = Collections.unmodifiableSortedSet(nullable); }
/** @author thomas */ @PlainStorage public interface MyInterface extends ConfigInterface { public static final MyInterface CFG = JsonConfig.create(MyInterface.class); @SuppressWarnings("unchecked") public static final StorageHandler<MyInterface> SH = (StorageHandler<MyInterface>) CFG._getStorageHandler(); @DefaultBooleanValue(value = true) public boolean getB2(); @DefaultBooleanArrayValue(value = {true, false, true}) public boolean[] getBooleanArray(); @DefaultByteValue(value = 0) public byte getByte(); @DefaultByteArrayValue(value = {1, 2, 3}) public byte[] getByteArray(); @DefaultFactory(DefaultD.class) public double getD(); @DefaultDoubleArrayValue(value = {1.0d, 2.0d, 3.0d}) public double[] getDoubleArray(); public void setDoubleArray(double[] arr); @DefaultEnumValue(value = "A") public Type getEnum(); @DefaultFloatValue(value = 0.5f) public float getFloat(); @DefaultFloatArrayValue(value = {1.0f, 2.0f, 3.0f}) public Float[] getFloatArray(); /** @return */ public ArrayList<TestObject> getGenericList(); public static final IntegerKeyHandler INT = CFG._getStorageHandler().getKeyHandler("Int", IntegerKeyHandler.class); @DefaultIntValue(value = 2) @SpinnerValidator(min = 1, max = 10, step = 1) public int getInt(); @DefaultIntArrayValue(value = {1, 2, 3}) public int[] getIntArray(); @DefaultLongValue(value = 0l) public long getL(); @DefaultLongArrayValue(value = {1, 2, 3}) public long[] getLongArray(); // @DefaultJsonObject(value = "{\"a\":5}") public TestObject getObject(); public HashSet<String> getSet(); public void setSet(HashSet<String> set); public ArrayList<TestObject[]> getStorableArrayList(); // public Object[] getObjectArray(); @DefaultStringValue(value = "test") public String getString(); @DefaultStringArrayValue(value = {"test", "testb"}) public String[] getStringArray(); @DefaultEnumArrayValue( value = {"org.appwork.storage.config.test.Type.A", "org.appwork.storage.config.test.Type.B"}) public Type[] getTypeArray(); /** @param list */ @CryptedStorage( key = { 0x01, 0x02, 0x11, 0x01, 0x01, 0x54, 0x01, 0x01, 0x01, 0x01, 0x12, 0x01, 0x01, 0x01, 0x22, 0x01 }) public void setGenericList(ArrayList<TestObject> list); public void setInt(int i); /** @param is */ public void setIntArray(int[] is); class DefFac extends AbstractDefaultFactory<TestObject> { @Override public TestObject getDefaultValue() { // TODO Auto-generated method stub return null; } } class DefValid extends AbstractValidator<TestObject> { /* * (non-Javadoc) * * @see * org.appwork.storage.config.annotations.AbstractValidator#validate * (java.lang.Object) */ @Override public void validate(TestObject object) throws ValidationException { System.out.println("CHECK " + object); } } /** @param o */ @DefaultFactory(org.appwork.storage.config.test.MyInterface.DefFac.class) @ValidatorFactory(org.appwork.storage.config.test.MyInterface.DefValid.class) public void setObject(TestObject o); @DefaultFactory(MyDefaultCreator.class) public ArrayList<Integer> getDefault(); }