private Collection<Statement> computeFactoryReturnStatements() { // todo: clean up logic with inheritance, delegation. HashSet<Statement> result = HashSetFactory.make(); for (CGNode n : builder.getCallGraph()) { if (n.getMethod() instanceof SyntheticMethod) { SyntheticMethod m = (SyntheticMethod) n.getMethod(); if (m.isFactoryMethod()) { result.add(new NormalReturnCallee(n)); } } } return result; }
private Collection<Statement> computeFactoryReturnStatements() { // todo: clean up logic with inheritance, delegation. HashSet<Statement> result = HashSetFactory.make(); for (CGNode n : builder.getCallGraph()) { if (n.getMethod() instanceof SyntheticMethod) { SyntheticMethod m = (SyntheticMethod) n.getMethod(); if (m.isFactoryMethod()) { result.add(new NormalReturnCallee(n)); } } } return result; }
/** * @param caller the caller node * @param iKey an abstraction of the receiver of the call (or null if not applicable) * @return the CGNode to which this particular call should dispatch. */ protected CGNode getTargetForCall(CGNode caller, CallSiteReference site, IClass recv, InstanceKey iKey[]) { IMethod targetMethod = options.getMethodTargetSelector().getCalleeTarget(caller, site, recv); // this most likely indicates an exclusion at work; the target selector // should have issued a warning if (targetMethod == null || targetMethod.isAbstract()) { return null; } Context targetContext = contextSelector.getCalleeTarget(caller, site, targetMethod, iKey); if (targetContext.isA(IllegalArgumentExceptionContext.class)) { return null; } try { return getCallGraph().findOrCreateNode(targetMethod, targetContext); } catch (CancelException e) { return null; } }
/** * @param caller the caller node * @param iKey an abstraction of the receiver of the call (or null if not applicable) * @return the CGNode to which this particular call should dispatch. */ protected CGNode getTargetForCall(CGNode caller, CallSiteReference site, IClass recv, InstanceKey iKey[]) { IMethod targetMethod = options.getMethodTargetSelector().getCalleeTarget(caller, site, recv); // this most likely indicates an exclusion at work; the target selector // should have issued a warning if (targetMethod == null || targetMethod.isAbstract()) { return null; } Context targetContext = contextSelector.getCalleeTarget(caller, site, targetMethod, iKey); if (targetContext.isA(IllegalArgumentExceptionContext.class)) { return null; } try { return getCallGraph().findOrCreateNode(targetMethod, targetContext); } catch (CancelException e) { return null; } }
@Override protected Collection<CGNode> getConstructorCallers(ScopeMappingInstanceKey smik, Pair<String, String> name) { // in JavaScript, the 'new' instruction is wrapped in a synthetic constructor method. we want the // caller of that constructor method, which we obtain from the context for the constructor method final Context creatorContext = smik.getCreator().getContext(); CGNode callerOfConstructor = (CGNode) creatorContext.get(ContextKey.CALLER); Collection<CGNode> result = null; if (callerOfConstructor != null) { return Collections.singleton(callerOfConstructor); } else { CallString cs = (CallString) creatorContext.get(CallStringContextSelector.CALL_STRING); if (cs != null) { IMethod[] methods = cs.getMethods(); assert methods.length == 1; IMethod m = methods[0]; result = builder.getCallGraph().getNodes(m.getReference()); } } if (result == null) { IClassHierarchy cha = smik.getCreator().getClassHierarchy(); MethodReference ref = MethodReference.findOrCreate(JavaScriptLoader.JS, TypeReference.findOrCreate(cha.getLoaders()[0].getReference(), name.snd), AstMethodReference.fnAtomStr, AstMethodReference.fnDesc.toString()); final IMethod method = cha.resolveMethod(ref); if (method != null) { return builder.getCallGraph().getNodes(method.getReference()); } } return result; }
@Override protected Collection<CGNode> getConstructorCallers(ScopeMappingInstanceKey smik, Pair<String, String> name) { // in JavaScript, the 'new' instruction is wrapped in a synthetic constructor method. we want the // caller of that constructor method, which we obtain from the context for the constructor method final Context creatorContext = smik.getCreator().getContext(); CGNode callerOfConstructor = (CGNode) creatorContext.get(ContextKey.CALLER); Collection<CGNode> result = null; if (callerOfConstructor != null) { return Collections.singleton(callerOfConstructor); } else { CallString cs = (CallString) creatorContext.get(CallStringContextSelector.CALL_STRING); if (cs != null) { IMethod[] methods = cs.getMethods(); assert methods.length == 1; IMethod m = methods[0]; result = builder.getCallGraph().getNodes(m.getReference()); } } if (result == null) { IClassHierarchy cha = smik.getCreator().getClassHierarchy(); MethodReference ref = MethodReference.findOrCreate(JavaScriptLoader.JS, TypeReference.findOrCreate(cha.getLoaders()[0].getReference(), name.snd), AstMethodReference.fnAtomStr, AstMethodReference.fnDesc.toString()); final IMethod method = cha.resolveMethod(ref); if (method != null) { return builder.getCallGraph().getNodes(method.getReference()); } } return result; }
@Override public void visitAstGlobalRead(AstGlobalRead instruction) { JSPointerAnalysisImpl jsAnalysis = (JSPointerAnalysisImpl) analysis; FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField()); assert !directGlobalObjectRef(field); IField f = jsAnalysis.builder.getCallGraph().getClassHierarchy().resolveField(field); assert f != null; MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); InstanceKey globalObj = ((AstSSAPropagationCallGraphBuilder) jsAnalysis.builder).getGlobalObject(JavaScriptTypes.jsName); PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(globalObj, f); if (fkey != null) { OrdinalSet<InstanceKey> pointees = analysis.getPointsToSet(fkey); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } pointsToSet = new OrdinalSet<>(S, analysis.getInstanceKeyMapping()); }
@Override public void visitAstGlobalRead(AstGlobalRead instruction) { JSPointerAnalysisImpl jsAnalysis = (JSPointerAnalysisImpl) analysis; FieldReference field = makeNonGlobalFieldReference(instruction.getDeclaredField()); assert !directGlobalObjectRef(field); IField f = jsAnalysis.builder.getCallGraph().getClassHierarchy().resolveField(field); assert f != null; MutableSparseIntSet S = MutableSparseIntSet.makeEmpty(); InstanceKey globalObj = ((AstSSAPropagationCallGraphBuilder) jsAnalysis.builder).getGlobalObject(JavaScriptTypes.jsName); PointerKey fkey = analysis.getHeapModel().getPointerKeyForInstanceField(globalObj, f); if (fkey != null) { OrdinalSet<InstanceKey> pointees = analysis.getPointsToSet(fkey); IntSet set = pointees.getBackingSet(); if (set != null) { S.addAll(set); } } pointsToSet = new OrdinalSet<>(S, analysis.getInstanceKeyMapping()); }
if (getBuilder().getCallGraph().getNumberOfNodes() >= getBuilder().getOptions().getMaxNumberOfNodes()) { if (DEBUG) { System.err.println("Bail out from call graph limit" + i);
if (getBuilder().getCallGraph().getNumberOfNodes() >= getBuilder().getOptions().getMaxNumberOfNodes()) { if (DEBUG) { System.err.println("Bail out from call graph limit" + i);