@Override public void visitJavaScriptInvoke(JavaScriptInvoke invk) { // check whether this instruction corresponds to a function expression/declaration if (isFunctionConstructorInvoke(invk)) { int defn = invk.getDef(); // the name of the function String fnName = symtab.getStringValue(invk.getUse(1)); IClass fnClass = cha.lookupClass(TypeReference.findOrCreate(JavaScriptTypes.jsLoader, fnName)); if (fnClass == null) { System.err.println( "cannot find " + fnName + " at " + ((AstMethod) method).getSourcePosition()); return; } IMethod fn = fnClass.getMethod(AstMethodReference.fnSelector); FuncVertex callee = factory.makeFuncVertex(fnClass); // look at all uses for (Iterator<SSAInstruction> uses = du.getUses(defn); uses.hasNext(); ) { SSAInstruction use = uses.next(); // check whether this is a local call if (use instanceof JavaScriptInvoke && ((JavaScriptInvoke) use).getFunction() == defn) { JavaScriptInvoke use_invk = (JavaScriptInvoke) use; // yes, so add edges from arguments to parameters... for (int i = 2; i < use_invk.getNumberOfParameters(); ++i) flowgraph.addEdge( factory.makeVarVertex(caller, use_invk.getUse(i)), factory.makeParamVertex(callee, i - 1)); // ...and from return to result flowgraph.addEdge( factory.makeRetVertex(callee), factory.makeVarVertex(caller, use.getDef())); // note: local calls are never qualified, so there is no flow into the receiver vertex } else { // no, it's a more complicated use, so add flows from/to unknown for (int i = 1; i < fn.getNumberOfParameters(); ++i) flowgraph.addEdge(factory.makeUnknownVertex(), factory.makeParamVertex(callee, i)); flowgraph.addEdge(factory.makeRetVertex(callee), factory.makeUnknownVertex()); } } } else { // this is a genuine function call; find out where the function came from SSAInstruction def = du.getDef(invk.getFunction()); // if it's not a local call, add flows from/to unknown if (!(def instanceof JavaScriptInvoke) || !isFunctionConstructorInvoke((JavaScriptInvoke) def)) { for (int i = 1; i < invk.getNumberOfParameters(); ++i) flowgraph.addEdge( factory.makeVarVertex(caller, invk.getUse(i)), factory.makeUnknownVertex()); flowgraph.addEdge( factory.makeUnknownVertex(), factory.makeVarVertex(caller, invk.getDef())); } } }
public LocalCallSSAVisitor(IMethod method, SymbolTable symtab, DefUse du, FlowGraph flowgraph) { super(method, symtab, du); this.flowgraph = flowgraph; this.factory = flowgraph.getVertexFactory(); this.caller = this.factory.makeFuncVertex(method.getDeclaringClass()); }