static PathInstruction branch(AbstractInsnNode node, boolean branchTaken) { PathInstruction pi = new PathInstruction(node); pi.isBranch = true; pi.isBranchTaken = branchTaken; return pi; } }
@Override public MethodAnalysisResults createMethodAnalysisResults() { return new MethodAnalysisResults(); }
@Override public void addPath(MethodAnalysisResults methodAnalysisResults, List<MethodSideEffect> sideEffects, TypedValue returnValue, List<? extends TypedValue> conditions, PathAnalysisMethodChecker methodChecker) { methodAnalysisResults.addPath(sideEffects, returnValue, conditions); } }
private static MethodAnalysisResults analyzeLambda(MetamodelUtil metamodel, ClassLoader alternateClassLoader, boolean isObjectEqualsSafe, boolean isAllEqualsSafe, boolean isCollectionContainsSafe, String className, String methodName, String methodSignature) throws IOException, AnalyzerException { // Open up the corresponding class to analyze PathAnalysisFactory pathAnalysisFactory = new PathAnalysisFactory( metamodel.getMethodChecker(isObjectEqualsSafe, isAllEqualsSafe, isCollectionContainsSafe)); TransformationClassAnalyzer classAnalyzer = new TransformationClassAnalyzer(className, alternateClassLoader); MethodAnalysisResults analysis = classAnalyzer.analyzeLambdaMethod(methodName, methodSignature, pathAnalysisFactory); PathAnalysisSimplifier.cleanAndSimplify(analysis, metamodel.getComparisonMethods(isObjectEqualsSafe), metamodel.getComparisonStaticMethods(isObjectEqualsSafe), isAllEqualsSafe); return analysis; }
CFG cfg = new CFG(cl.name, m); if (hasLoops(cfg, visitStatus, 0)) return null; List<CodePath> paths = CodePath.breakIntoPaths(cfg, m, cl.name, MAX_PATHS); if (paths == null) return null; U analysis = pathAnalysisFactory.createMethodAnalysisResults(); for (CodePath path: paths) PathAnalysisMethodChecker methodChecker = pathAnalysisFactory.createMethodChecker(); path.calculateReturnValueAndConditions(cl, m, methodChecker); pathAnalysisFactory.addPath(analysis, pathResults.sideEffects, pathResults.returnValue, pathResults.conditions, methodChecker);
protected <U> ColumnExpressions<U> simplifyAndTranslatePathToColumns(LambdaAnalysis lambda, int pathIdx, SymbExToColumns translator, SymbExPassDown passdown) throws TypedValueVisitorException { return (ColumnExpressions<U>)PathAnalysisSimplifier .simplify(lambda.symbolicAnalysis.paths.get(pathIdx).getReturnValue(), config.getComparisonMethods(), config.getComparisonStaticMethods(), config.isAllEqualsSafe) .visit(translator, passdown); }
protected static void pathConditionsToClauses(PathAnalysis path, List<TypedValue> clauses) throws TypedValueVisitorException { for (TypedValue cmp: path.getConditions()) { clauses.add(cmp); } }
public static <T extends Annotation> T methodFindAnnotation(MethodSignature sig, Class<T> annotation) { try { Method m = asmMethodSignatureToReflectionMethod(sig); return m.getAnnotation(annotation); } catch (ClassNotFoundException | NoSuchMethodException e) { e.printStackTrace(); return null; } } }
public static TypedValue simplifyBoolean(TypedValue value, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { TypedValue simplifiedBooleanReturnValue = value .visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simplifiedBooleanReturnValue = simplifiedBooleanReturnValue.visit(new SymbExBooleanRewriter(), true); return simplifiedBooleanReturnValue; } // public TypedValue getSimplifiedIsTrueReturnValue()
boolean hasLoops(CFG cfg, int[]visitStatus, int index) { final int VISITING = 1; final int VISITED = 2; // reached an instruction with no successor (probably a return instruction) if (cfg.succsOf(index) == null) return false; // Check if we've visited the node and finished exploring all sub-branches if (visitStatus[index] == VISITED) return false; // Check if we've looped back to visit a node we haven't finished exploring if (visitStatus[index] == VISITING) return true; // Mark node as being explored visitStatus[index] = VISITING; // Visit successors of this node and see if we loop back for (int succ: cfg.succsOf(index)) if (hasLoops(cfg, visitStatus, succ)) return true; // Mark this node as having been explored successfully visitStatus[index] = VISITED; return false; } }
public void checkLambdaSideEffects(LambdaAnalysis lambda) throws QueryTransformException { for (PathAnalysis path: lambda.symbolicAnalysis.paths) { if (!path.getSideEffects().isEmpty()) throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); } }
public static Method asmMethodSignatureToReflectionMethod(MethodSignature m) throws ClassNotFoundException, NoSuchMethodException { Class<?> reflectedClass = Class.forName(m.getOwnerType().getClassName()); Type []argTypes = Type.getMethodType(m.desc).getArgumentTypes(); Class<?> []argClasses = new Class[argTypes.length]; for (int n = 0; n < argTypes.length; n++) argClasses[n] = asmTypeToClass(argTypes[n]); return reflectedClass.getMethod(m.name, argClasses); }
public void addPath(List<MethodSideEffect> sideEffects, TypedValue returnValue, List<? extends TypedValue> conditions) { PathAnalysis pathAnalysis = new PathAnalysis(sideEffects, returnValue, conditions); paths.add(pathAnalysis); } }
static List<CodePath> breakIntoPaths(CFG cfg, MethodNode m, String name, int maxPaths) { List<CodePath> paths = new ArrayList<CodePath>(); List<PathInstruction> instructions = new ArrayList<PathInstruction>(); if (!breakIntoPaths(paths, instructions, 0, cfg, m, maxPaths)) return null; return paths; }
public <T, U> U analyzeLambdaMethod(String methodName, String methodSignature, PathAnalysisSupplementalFactory<T, U> pathAnalysisFactory) throws AnalyzerException { MethodNode specificMethod = null; for (MethodNode m: (List<MethodNode>)cl.methods) { if (!m.name.equals(methodName) || !m.desc.equals(methodSignature)) continue; specificMethod = m; } if (specificMethod != null) return analyzeMethod(specificMethod, pathAnalysisFactory); return null; }
@Override public Boolean binaryOpValue(TypedValue.BinaryOperationValue val, Boolean in) { if ("AND".equals(val.operation) || "OR".equals(val.operation)) return true; if (val.left.getType() == Type.BOOLEAN_TYPE || val.right.getType() == Type.BOOLEAN_TYPE) return true; return defaultValue(val, in); }
private static MethodAnalysisResults analyzeLambda(MetamodelUtil metamodel, String className, String methodName, String methodSignature) { try { // Open up the corresponding class to analyze PathAnalysisFactory pathAnalysisFactory = new PathAnalysisFactory( new MethodChecker(metamodel)); TransformationClassAnalyzer classAnalyzer = new TransformationClassAnalyzer(className); MethodAnalysisResults analysis = classAnalyzer.analyzeLambdaMethod(methodName, methodSignature, pathAnalysisFactory); PathAnalysisSimplifier.cleanAndSimplify(analysis, Collections.emptyMap(), Collections.emptyMap(), false); return analysis; } catch (IOException e) { e.printStackTrace(); return null; } catch (AnalyzerException e) { e.printStackTrace(); return null; } }
public static TypedValue simplify(TypedValue value, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { TypedValue simplifiedBooleanReturnValue = value .visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simplifiedBooleanReturnValue = simplifiedBooleanReturnValue.visit(new SymbExBooleanRewriter(), false); return simplifiedBooleanReturnValue; // return value.visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods)), null); } // public TypedValue getIsTrueReturnValue()
private static MethodAnalysisResults analyzeLambdaClass(Class<?> lambdaClass, MetamodelUtil metamodel, LambdaAsClassAnalysisConfig lambdaAsClass, ClassLoader alternateClassLoader, boolean isObjectEqualsSafe, boolean isAllEqualsSafe, boolean isCollectionContainsSafe) throws IOException, AnalyzerException { // Open up the corresponding class to analyze TransformationClassAnalyzer classAnalyzer = new TransformationClassAnalyzer(lambdaClass.getName(), alternateClassLoader); Method matchingMethod = lambdaAsClass.findLambdaMethod(lambdaClass); if (matchingMethod == null) throw new AnalyzerException(null, "Could not find a lambda method with the expected name in the class"); PathAnalysisFactory pathAnalysisFactory = new PathAnalysisFactory( metamodel.getMethodChecker(isObjectEqualsSafe, isAllEqualsSafe, isCollectionContainsSafe)); MethodAnalysisResults analysis = classAnalyzer.analyzeLambdaMethod(matchingMethod.getName(), Type.getMethodDescriptor(matchingMethod), pathAnalysisFactory); PathAnalysisSimplifier.cleanAndSimplify(analysis, metamodel.getComparisonMethods(isObjectEqualsSafe), metamodel.getComparisonStaticMethods(isObjectEqualsSafe), isAllEqualsSafe); return analysis; }
public static List<TypedValue> simplifyBooleans(List<TypedValue> conditions, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonMethods, Map<MethodSignature, TypedValue.ComparisonValue.ComparisonOp> comparisonStaticMethods, boolean isAllEqualsConverted) { List<TypedValue> newConditions = new ArrayList<TypedValue>(); for (TypedValue cond: conditions) { TypedValue simpcond = cond.visit(new TypedValueRewriterWalker<Object, RuntimeException>(new SymbExSimplifier<Object>(comparisonMethods, comparisonStaticMethods, isAllEqualsConverted)), null); simpcond = simpcond.visit(new SymbExBooleanRewriter(), true); newConditions.add(simpcond); } return newConditions; }