private void addParamEdges(LocalPointerKey pk, CGNode node) { // get parameter position: value number - 1? int paramPos = pk.getValueNumber() - 1; // iterate over callers for (CGNode caller : cg) { // TODO we don't need to add the graph if null is passed // as the argument addSubgraphForNode(caller); IR ir = caller.getIR(); for (Iterator<CallSiteReference> iterator = ir.iterateCallSites(); iterator.hasNext(); ) { CallSiteReference call = iterator.next(); if (cg.getPossibleTargets(caller, call).contains(node)) { SSAAbstractInvokeInstruction[] callInstrs = ir.getCalls(call); for (int i = 0; i < callInstrs.length; i++) { SSAAbstractInvokeInstruction callInstr = callInstrs[i]; PointerKey actualPk = heapModel.getPointerKeyForLocal(caller, callInstr.getUse(paramPos)); assert containsNode(actualPk); assert containsNode(pk); addEdge(pk, actualPk); } } } } }
@Override public IFigure getTooltip(Object element) { if (element instanceof BasicBlock) { BasicBlock bb = (BasicBlock) element; IR ir = irView.getIR(); IDocument doc = irView.getDocument(); IMethod method = ir.getMethod(); StringBuffer result = new StringBuffer(); int start = bb.getFirstInstructionIndex(); int end = bb.getLastInstructionIndex(); SSAInstruction[] instructions = ir.getInstructions(); for (int j = start; j <= end; j++) { if (instructions[j] != null) { int sourceLineNum = method.getLineNumber(j); int lineNumber = sourceLineNum - 1; // IDocument indexing is 0-based try { int lineOffset = doc.getLineOffset(lineNumber); int lineLength = doc.getLineLength(lineNumber); String sourceCode = doc.get(lineOffset, lineLength).trim(); result.append(sourceCode); } catch (BadLocationException e) { } result.append("\n"); } } return new Label(result.toString()); } return null; }
private Set<CGNode> findLoopingMethods(IProgressMonitor progress) throws CancelException { CallGraph cg = sdg.getCallGraph(); Set<CGNode> loops = HashSetFactory.make(); progress.subTask("Searching methods with potential endless loops"); for (CGNode node : cg) { IR ir = node.getIR(); if (ir != null) { ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg = ir.getControlFlowGraph(); final boolean ac = Acyclic.isAcyclic(cfg, cfg.entry()); if (!ac && !loopsAreSimple(ir)) { loops.add(node); } } else { // Conservatively assume that methods may not terminate, iff we dont // have their code loops.add(node); } progress.worked(1); } progress.done(); return loops; }
// add inter-procedural flow for local calls private void resolveLocalCalls(FlowGraph flowgraph) { for (IClass klass : cha) { for (IMethod method : klass.getDeclaredMethods()) { if (filterFunction(method)) { IR ir = cache.getIR(method); ir.visitAllInstructions( new LocalCallSSAVisitor(method, ir.getSymbolTable(), cache.getDefUse(ir), flowgraph)); } } } }
private void addMatchHelper(LocalPointerKey pk, Collection<MemoryAccess> writes) { for (MemoryAccess a : writes) { addSubgraphForNode(a.getNode()); } for (MemoryAccess a : writes) { IR ir = a.getNode().getIR(); SSAPutInstruction s = (SSAPutInstruction) ir.getInstructions()[a.getInstructionIndex()]; PointerKey r = heapModel.getPointerKeyForLocal(a.getNode(), s.getVal()); assert containsNode(r); assert containsNode(pk); addMatchEdge(pk, r); } }
@Override public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) { if (site.getDeclaredTarget().equals(JavaScriptMethods.ctorReference)) { assert cha.isSubclassOf(receiver, cha.lookupClass(JavaScriptTypes.Root)); IR callerIR = caller.getIR(); SSAAbstractInvokeInstruction callStmts[] = callerIR.getCalls(site); assert callStmts.length == 1; int nargs = callStmts[0].getNumberOfParameters(); return findOrCreateConstructorMethod(callerIR, callStmts[0], receiver, nargs - 1); } else { return base.getCalleeTarget(caller, site, receiver); } }
private void addArrayMatchEdges(LocalPointerKey pk) { Collection<MemoryAccess> arrayWrites = fam.getArrayWrites(null); for (MemoryAccess a : arrayWrites) { addSubgraphForNode(a.getNode()); } for (MemoryAccess a : arrayWrites) { IR ir = a.getNode().getIR(); SSAArrayStoreInstruction s = (SSAArrayStoreInstruction) ir.getInstructions()[a.getInstructionIndex()]; PointerKey r = heapModel.getPointerKeyForLocal(a.getNode(), s.getValue()); assert containsNode(r); assert containsNode(pk); addMatchEdge(pk, r); } }
public StatementVisitor(CGNode node, IR ir, DefUse du) { this.node = node; this.ir = ir; this.symbolTable = ir.getSymbolTable(); assert symbolTable != null; this.du = du; }
/** Add pointer flow constraints based on instructions in a given node */ protected void addNodeInstructionConstraints(CGNode node, IR ir, DefUse du) { StatementVisitor v = makeVisitor((ExplicitCallGraph.ExplicitNode) node, ir, du); ControlFlowGraph<SSAInstruction, ISSABasicBlock> cfg = ir.getControlFlowGraph(); for (ISSABasicBlock b : cfg) { addBlockInstructionConstraints(node, cfg, b, v); } }
@SuppressWarnings("unchecked") public void setIR(IR ir) { this.lineToPosition = HashMapFactory.make(); this.pcToLine = HashMapFactory.make(); this.lineToPc = HashMapFactory.make(); int firstLineWithPosition = NA; try { methodName.setText("IR: " + ir.getMethod()); irLineList.clear(); BufferedReader br = new BufferedReader(new StringReader(ir.toString())); int lineNum = 0; int position = NA; String line; while ((line = br.readLine()) != null) { irLineList.addElement(line); int pc = parseIrLine(line); if (pc != NA) { IMethod m = ir.getMethod(); int newPosition = m.getLineNumber(pc); if (newPosition != -1) { position = newPosition; } lineToPc.put(lineNum, pc); pcToLine.put(pc, lineNum); if (position != NA) { lineToPosition.put(lineNum, position); if (firstLineWithPosition == NA) { firstLineWithPosition = lineNum; } } } lineNum++; } } catch (IOException e) { // ??? assert false; } // focusing on the first line with position if (firstLineWithPosition != NA) { irLines.setSelectedIndex(firstLineWithPosition); irLines.ensureIndexIsVisible(firstLineWithPosition); } }
/** * add nodes for parameters and return values * * @param node */ private void addNodesForParameters(CGNode node) { // TODO Auto-generated method stub IR ir = node.getIR(); TypeInference ti = TypeInference.make(ir, false); SymbolTable symbolTable = ir.getSymbolTable(); for (int i = 0; i < symbolTable.getNumberOfParameters(); i++) { int parameter = symbolTable.getParameter(i); TypeAbstraction t = ti.getType(parameter); if (t != null) { PointerKey paramPk = heapModel.getPointerKeyForLocal(node, parameter); addNode(paramPk); params.put(paramPk, node); } } addNode(heapModel.getPointerKeyForReturnValue(node)); addNode(heapModel.getPointerKeyForExceptionalReturnValue(node)); }
/** * Add constraints to represent the flow of exceptions to the exceptional return value for this * node */ protected void addNodePassthruExceptionConstraints(CGNode node, IR ir) { // add constraints relating to thrown exceptions that reach the exit block. List<ProgramCounter> peis = SSAPropagationCallGraphBuilder.getIncomingPEIs(ir, ir.getExitBlock()); PointerKey exception = heapModel.getPointerKeyForExceptionalReturnValue(node); IClass c = node.getClassHierarchy().lookupClass(TypeReference.JavaLangThrowable); addExceptionDefConstraints(ir, node, peis, exception, Collections.singleton(c)); }
private List<String> getVariableNamesForDefs(Pair<? extends SSAInstruction, Integer> pair) { List<String> names = new ArrayList<String>(); SSAInstruction instr = pair.fst; Integer index = pair.snd; int numDefs = instr.getNumberOfDefs(); for (int i = 0; i < numDefs; i++) { int def = instr.getDef(i); String[] localNames = ir.getLocalNames(index, def); names.addAll(Arrays.asList(localNames)); } return names; }
private void debugPrintIR(IR ir) { if (DEBUG) { if (ir == null) { System.err.println("\n No statements\n"); } else { try { System.err.println(ir.toString()); } catch (Error e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
private static String SSAValuesToLocalVariables( SSAInstruction instr, int instructionIndex, IR ir) { StringBuilder sb = new StringBuilder(); int numDefs = instr.getNumberOfDefs(); sb.append("[DEF: "); for (int i = 0; i < numDefs; i++) { int def = instr.getDef(i); sb.append( String.format("v%s=%s, ", def, Arrays.toString(ir.getLocalNames(instructionIndex, def)))); } sb.append("]"); int numUses = instr.getNumberOfUses(); sb.append("[USE: "); for (int i = 0; i < numUses; i++) { int def = instr.getUse(i); sb.append( String.format("v%s=%s, ", def, Arrays.toString(ir.getLocalNames(instructionIndex, def)))); } sb.append("]"); return sb.toString(); }
/** * Compute the set of PointerKeys each statement refs.Be careful to avoid eager PDG construction * here! That means .. don't iterate over SDG statements! */ public static Map<Statement, Set<PointerKey>> scanForRef( SDG sdg, PointerAnalysis pa, ModRef modRef) { if (pa == null) { throw new IllegalArgumentException("null pa"); } ExtendedHeapModel h = new DelegatingExtendedHeapModel(pa.getHeapModel()); Map<Statement, Set<PointerKey>> result = HashMapFactory.make(); for (CGNode n : sdg.getCallGraph()) { IR ir = n.getIR(); if (ir != null) { for (int i = 0; i < ir.getInstructions().length; i++) { SSAInstruction st = ir.getInstructions()[i]; if (st != null) { Set<PointerKey> mod = modRef.getRef(n, h, pa, st, null); if (!mod.isEmpty()) { NormalStatement normal = new NormalStatement(n, i); result.put(normal, mod); } } } } } return result; }
/** * Generate constraints which assign exception values into an exception pointer * * @param node governing node * @param peis list of PEI instructions * @param exceptionVar PointerKey representing a pointer to an exception value * @param catchClasses the types "caught" by the exceptionVar */ private void addExceptionDefConstraints( IR ir, CGNode node, List<ProgramCounter> peis, PointerKey exceptionVar, Set<IClass> catchClasses) { for (ProgramCounter peiLoc : peis) { SSAInstruction pei = ir.getPEI(peiLoc); if (pei instanceof SSAAbstractInvokeInstruction) { SSAAbstractInvokeInstruction s = (SSAAbstractInvokeInstruction) pei; PointerKey e = heapModel.getPointerKeyForLocal(node, s.getException()); addNode(exceptionVar); addNode(e); addEdge(exceptionVar, e); } else if (pei instanceof SSAAbstractThrowInstruction) { SSAAbstractThrowInstruction s = (SSAAbstractThrowInstruction) pei; PointerKey e = heapModel.getPointerKeyForLocal(node, s.getException()); addNode(exceptionVar); addNode(e); addEdge(exceptionVar, e); } // Account for those exceptions for which we do not actually have a // points-to set for // the pei, but just instance keys Collection<TypeReference> types = pei.getExceptionTypes(); if (types != null) { for (TypeReference type : types) { if (type != null) { InstanceKey ik = heapModel.getInstanceKeyForPEI(node, peiLoc, type); assert ik instanceof ConcreteTypeKey : "uh oh: need to implement getCaughtException constraints for instance " + ik; ConcreteTypeKey ck = (ConcreteTypeKey) ik; IClass klass = ck.getType(); if (PropagationCallGraphBuilder.catches(catchClasses, klass, cha)) { addNode(exceptionVar); addNode(ik); addEdge(exceptionVar, ik); } } } } } }
private static List<Pair<CGNode, SSACheckCastInstruction>> findFailingCasts( CallGraph cg, DemandRefinementPointsTo dmp) { final IClassHierarchy cha = dmp.getClassHierarchy(); List<Pair<CGNode, SSACheckCastInstruction>> failing = new ArrayList<Pair<CGNode, SSACheckCastInstruction>>(); int numSafe = 0, numMightFail = 0; outer: for (Iterator<? extends CGNode> nodeIter = cg.iterator(); nodeIter.hasNext(); ) { CGNode node = nodeIter.next(); TypeReference declaringClass = node.getMethod().getReference().getDeclaringClass(); // skip library classes if (declaringClass.getClassLoader().equals(ClassLoaderReference.Primordial)) { continue; } IR ir = node.getIR(); if (ir == null) continue; SSAInstruction[] instrs = ir.getInstructions(); for (int i = 0; i < instrs.length; i++) { if (numSafe + numMightFail > MAX_CASTS) break outer; SSAInstruction instruction = instrs[i]; if (instruction instanceof SSACheckCastInstruction) { SSACheckCastInstruction castInstr = (SSACheckCastInstruction) instruction; final TypeReference[] declaredResultTypes = castInstr.getDeclaredResultTypes(); boolean primOnly = true; for (TypeReference t : declaredResultTypes) { if (!t.isPrimitiveType()) { primOnly = false; } } if (primOnly) { continue; } System.err.println("CHECKING " + castInstr + " in " + node.getMethod()); PointerKey castedPk = heapModel.getPointerKeyForLocal(node, castInstr.getUse(0)); Predicate<InstanceKey> castPred = new Predicate<InstanceKey>() { @Override public boolean test(InstanceKey ik) { TypeReference ikTypeRef = ik.getConcreteType().getReference(); for (TypeReference t : declaredResultTypes) { if (cha.isAssignableFrom(cha.lookupClass(t), cha.lookupClass(ikTypeRef))) { return true; } } return false; } }; long startTime = System.currentTimeMillis(); Pair<PointsToResult, Collection<InstanceKey>> queryResult = dmp.getPointsTo(castedPk, castPred); long runningTime = System.currentTimeMillis() - startTime; System.err.println("running time: " + runningTime + "ms"); final FieldRefinePolicy fieldRefinePolicy = dmp.getRefinementPolicy().getFieldRefinePolicy(); switch (queryResult.fst) { case SUCCESS: System.err.println("SAFE: " + castInstr + " in " + node.getMethod()); if (fieldRefinePolicy instanceof ManualFieldPolicy) { ManualFieldPolicy hackedFieldPolicy = (ManualFieldPolicy) fieldRefinePolicy; System.err.println(hackedFieldPolicy.getHistory()); } System.err.println("TRAVERSED " + dmp.getNumNodesTraversed() + " nodes"); numSafe++; break; case NOMOREREFINE: if (queryResult.snd != null) { System.err.println( "MIGHT FAIL: no more refinement possible for " + castInstr + " in " + node.getMethod()); } else { System.err.println( "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod()); } failing.add(Pair.make(node, castInstr)); numMightFail++; break; case BUDGETEXCEEDED: System.err.println( "MIGHT FAIL: exceeded budget for " + castInstr + " in " + node.getMethod()); failing.add(Pair.make(node, castInstr)); numMightFail++; break; default: Assertions.UNREACHABLE(); } } } // break outer; } System.err.println("TOTAL SAFE: " + numSafe); System.err.println("TOTAL MIGHT FAIL: " + numMightFail); return failing; }
/** Taken from com.ibm.wala.viz.PDFViewUtil */ @Override public String getText(Object element) { if (element instanceof BasicBlock) { BasicBlock bb = (BasicBlock) element; IR ir = irView.getIR(); StringBuilder result = new StringBuilder(); int start = bb.getFirstInstructionIndex(); int end = bb.getLastInstructionIndex(); result.append("BB").append(bb.getNumber()); if (bb.isEntryBlock()) { result.append(" (en)\n"); } else if (bb.isExitBlock()) { result.append(" (ex)\n"); } if (bb instanceof ExceptionHandlerBasicBlock) { result.append("<Handler>"); } result.append("\n"); for (Iterator<SSAPhiInstruction> it = bb.iteratePhis(); it.hasNext(); ) { SSAPhiInstruction phi = it.next(); if (phi != null) { result.append(phi.toString(ir.getSymbolTable())).append("\n"); } } if (bb instanceof ExceptionHandlerBasicBlock) { ExceptionHandlerBasicBlock ebb = (ExceptionHandlerBasicBlock) bb; SSAGetCaughtExceptionInstruction s = ebb.getCatchInstruction(); if (s != null) { result.append(s.toString(ir.getSymbolTable())).append("\n"); } else { result.append(" No catch instruction. Unreachable?\n"); } } SSAInstruction[] instructions = ir.getInstructions(); IMethod method = ir.getMethod(); for (int j = start; j <= end; j++) { if (instructions[j] != null) { String x; int sourceLineNum = method.getLineNumber(j); x = String.format( j + " [L%03d] " + instructions[j].toString(ir.getSymbolTable()), sourceLineNum); String padded = String.format("%1$-35s", x); result.append(padded); result.append("\n"); result.append(SSAValuesToLocalVariables(instructions[j], j, ir)); result.append("\n"); } } for (Iterator<SSAPiInstruction> it = bb.iteratePis(); it.hasNext(); ) { SSAPiInstruction pi = it.next(); if (pi != null) { result.append(" " + pi.toString(ir.getSymbolTable())).append("\n"); } } return result.toString(); } if (element instanceof EntityConnectionData) { return "\n"; } return ""; }
private void run(IProgressMonitor progress) throws CancelException { final Map<PDGNode, PDGNode[]> entry2out = new HashMap<PDGNode, PDGNode[]>(); // add out nodes for each non-primitive parameter for (final PDG pdg : sdg.getAllPDGs()) { // primitive types nodes are null final PDGNode[] formOuts = new PDGNode[pdg.params.length]; for (int i = 0; i < pdg.params.length; i++) { final PDGNode formIn = pdg.params[i]; final TypeReference type = pdg.getParamType(i); if (createOutputParamFor(type)) { final PDGNode formOut = pdg.addOutputFieldChildTo( pdg.entry, formIn.getLabel(), formIn.getBytecodeName(), formIn.getBytecodeIndex(), formIn.getTypeRef()); formOuts[i] = formOut; } } entry2out.put(pdg.entry, formOuts); for (final PDGNode call : pdg.getCalls()) { final PDGNode[] actIns = pdg.getParamIn(call); final PDGNode[] actOuts = new PDGNode[actIns.length]; for (int i = 0; i < actIns.length; i++) { final PDGNode actIn = actIns[i]; final TypeReference type = pdg.getParamType(call, i); if (createOutputParamFor(type)) { final PDGNode actOut = pdg.addOutputFieldChildTo( call, actIn.getLabel(), actIn.getBytecodeName(), actIn.getBytecodeIndex(), actIn.getTypeRef()); actOuts[i] = actOut; } } entry2out.put(call, actOuts); } } // connect form-outs of called procedures with act-outs for (final PDG pdg : sdg.getAllPDGs()) { for (final PDGNode call : pdg.getCalls()) { final PDGNode[] actOuts = entry2out.get(call); assert actOuts != null; for (final PDGEdge out : pdg.outgoingEdgesOf(call)) { if (out.kind == PDGEdge.Kind.CALL_STATIC || out.kind == PDGEdge.Kind.CALL_VIRTUAL) { final PDGNode calleeEntry = out.to; final PDGNode[] formOuts = entry2out.get(calleeEntry); final PDG callee = sdg.getPDGforId(calleeEntry.getPdgId()); assert formOuts != null; assert actOuts.length == formOuts.length; for (int i = 0; i < actOuts.length; i++) { final PDGNode actOut = actOuts[i]; if (actOut != null) { // primitive type (and immutable type) params have no act out callee.addVertex(actOut); final PDGNode formOut = formOuts[i]; if (formOut != null) { callee.addEdge(formOut, actOut, PDGEdge.Kind.PARAMETER_OUT); } } } } } } } // collect reachable points-to elements for reachable fields for each parameter for (final PDG pdg : sdg.getAllPDGs()) { final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsMod = new HashMap<PDGNode, OrdinalSet<InstanceKey>>(); final Map<PDGNode, OrdinalSet<InstanceKey>> node2ptsRef = new HashMap<PDGNode, OrdinalSet<InstanceKey>>(); final IR ir = pdg.cgNode.getIR(); if (ir == null) { continue; } for (int i = 0; i < pdg.params.length; i++) { if (!pdg.getParamType(i).isPrimitiveType()) { final PDGNode formIn = pdg.params[i]; final int ssaVar = ir.getParameter(i); if (ssaVar >= 0) { final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar); node2ptsMod.put(formIn, ptsSet); } } } final PDGNode[] formOuts = entry2out.get(pdg.entry); for (int i = 0; i < formOuts.length; i++) { final PDGNode formOut = formOuts[i]; if (formOut != null) { final PDGNode formIn = pdg.params[i]; final OrdinalSet<InstanceKey> ptsSet = node2ptsMod.get(formIn); node2ptsRef.put(formOut, ptsSet); } } final TypeReference retType = pdg.getMethod().getReturnType(); if (retType != TypeReference.Void && !retType.isPrimitiveType()) { for (final PDGNode retNode : pdg.getReturns()) { final SSAReturnInstruction ret = (SSAReturnInstruction) pdg.getInstruction(retNode); final int ssaVar = ret.getResult(); final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar); node2ptsRef.put(retNode, ptsSet); } } for (final PDGNode call : pdg.getCalls()) { final PDGNode[] actIns = pdg.getParamIn(call); final SSAAbstractInvokeInstruction invk = (SSAAbstractInvokeInstruction) pdg.getInstruction(call); for (int i = 0; i < actIns.length; i++) { if (!pdg.getParamType(call, i).isPrimitiveType()) { final PDGNode actIn = actIns[i]; final int ssaVar = invk.getUse(i); if (ssaVar >= 0) { final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar); node2ptsRef.put(actIn, ptsSet); } } } final PDGNode actOuts[] = entry2out.get(call); for (int i = 0; i < actIns.length; i++) { final PDGNode actOut = actOuts[i]; if (actOut != null) { final PDGNode actIn = actIns[i]; final OrdinalSet<InstanceKey> ptsSet = node2ptsRef.get(actIn); node2ptsMod.put(actOut, ptsSet); } } final TypeReference callRetType = invk.getDeclaredTarget().getReturnType(); if (callRetType != TypeReference.Void && !callRetType.isPrimitiveType()) { final int ssaVar = invk.getReturnValue(0); final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar); final PDGNode retNode = pdg.getReturnOut(call); node2ptsMod.put(retNode, ptsSet); } } // create mod/ref sets for get & set instructions for (final PDGField read : pdg.getFieldReads()) { if (!read.field.isStatic()) { if (read.field.isArray()) { final SSAArrayLoadInstruction ali = (SSAArrayLoadInstruction) pdg.getInstruction(read.node); final int ssaVarBase = ali.getArrayRef(); if (ssaVarBase >= 0) { final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase); node2ptsRef.put(read.accfield, ptsSet); } } else { final SSAGetInstruction get = (SSAGetInstruction) pdg.getInstruction(read.node); final int ssaVarBase = get.getRef(); if (ssaVarBase >= 0) { final IField field = sdg.getClassHierarchy().resolveField(get.getDeclaredField()); final OrdinalSet<InstanceKey> ptsSet = pointsToObjectField(pdg.cgNode, ssaVarBase, field); node2ptsRef.put(read.accfield, ptsSet); } } // final SSAInstruction get = pdg.getInstruction(read.node); // final int ssaVar = get.getDef(); // if (ssaVar >= 0) { // final OrdinalSet<InstanceKey> ptsSet = findReachableInstances(pdg.cgNode, ssaVar); // node2ptsRef.put(read.accfield, ptsSet); // } } } for (final PDGField write : pdg.getFieldWrites()) { if (!write.field.isStatic()) { if (write.field.isArray()) { final SSAArrayStoreInstruction asi = (SSAArrayStoreInstruction) pdg.getInstruction(write.node); final int ssaVarBase = asi.getArrayRef(); if (ssaVarBase >= 0) { final OrdinalSet<InstanceKey> ptsSet = pointsToArrayField(pdg.cgNode, ssaVarBase); node2ptsMod.put(write.accfield, ptsSet); } } else { final SSAPutInstruction put = (SSAPutInstruction) pdg.getInstruction(write.node); final int ssaVarBase = put.getRef(); if (ssaVarBase >= 0) { final IField field = sdg.getClassHierarchy().resolveField(put.getDeclaredField()); final OrdinalSet<InstanceKey> ptsSet = pointsToObjectField(pdg.cgNode, ssaVarBase, field); node2ptsMod.put(write.accfield, ptsSet); } } } } // add data flow for each pdg FlatHeapParamsDataFlow.compute( pdg, node2ptsMod, node2ptsRef, (sdg.cfg.accessPath ? PDGEdge.Kind.DATA_ALIAS : PDGEdge.Kind.DATA_HEAP), progress); } }
private IMethod makeFunctionConstructor( IR callerIR, SSAAbstractInvokeInstruction callStmt, IClass cls, int nargs) { SymbolTable ST = callerIR.getSymbolTable(); if (nargs == 0) { return makeFunctionConstructor(cls, cls); } else if (nargs == 1) { if (ST.isStringConstant(callStmt.getUse(1))) { TypeReference ref = TypeReference.findOrCreate( JavaScriptTypes.jsLoader, TypeName.string2TypeName((String) ST.getStringValue(callStmt.getUse(1)))); if (DEBUG) { System.err.println( ("ctor type name is " + (String) ST.getStringValue(callStmt.getUse(1)))); } IClass cls2 = cha.lookupClass(ref); if (cls2 != null) { return makeFunctionConstructor(cls, cls2); } } return makeFunctionConstructor(cls, cls); } else { assert nargs > 1; JavaScriptLoader cl = (JavaScriptLoader) cha.getLoader(JavaScriptTypes.jsLoader); for (int i = 1; i < callStmt.getNumberOfUses(); i++) if (!ST.isStringConstant(callStmt.getUse(i))) return makeFunctionConstructor(cls, cls); StringBuffer fun = new StringBuffer("function _fromctor ("); for (int j = 1; j < callStmt.getNumberOfUses() - 1; j++) { if (j != 1) fun.append(","); fun.append(ST.getStringValue(callStmt.getUse(j))); } fun.append(") {"); fun.append(ST.getStringValue(callStmt.getUse(callStmt.getNumberOfUses() - 1))); fun.append("}"); try { String fileName = "ctor$" + ++ctorCount; File f = new File(System.getProperty("java.io.tmpdir") + File.separator + fileName); FileWriter FO = new FileWriter(f); FO.write(fun.toString()); FO.close(); Set<String> fnNames = JSCallGraphUtil.loadAdditionalFile(cha, cl, fileName, f.toURI().toURL()); IClass fcls = null; for (String nm : fnNames) { if (nm.endsWith("_fromctor")) { fcls = cl.lookupClass(nm, cha); } } assert fcls != null : "cannot find class for " + fileName + " in " + f; f.delete(); if (DEBUG) System.err.println(("looking for ctor " + ctorCount + " and got " + fcls)); if (fcls != null) return makeFunctionConstructor(cls, fcls); } catch (IOException e) { } return makeFunctionConstructor(cls, cls); } }