/** * Is this a 'static' call? (invokestatic in Java) */ public boolean isStatic() { return getCallSite().isStatic(); }
} else if (instr instanceof SSAAbstractInvokeInstruction) { SSAAbstractInvokeInstruction callInst = (SSAAbstractInvokeInstruction) instr; String sign = callInst.getDeclaredTarget().getSignature(); if (((SSAAbstractInvokeInstruction) instr).isStatic()) { derefValueNumber = callInst.getUse(NULL_TEST_APIS.get(sign)); !NULL_TEST_APIS.containsKey(sign), "Add support for non-static NULL_TEST_APIS : " + sign); derefValueNumber = ((SSAAbstractInvokeInstruction) instr).getReceiver();
@Override public String toString(SymbolTable symbolTable) { String code = site.getInvocationString(); StringBuilder s = new StringBuilder(); if (hasDef()) { s.append(getValueString(symbolTable, getDef())).append(" = "); } s.append("invoke").append(code); s.append(' '); s.append(site.getDeclaredTarget().toString()); if (getNumberOfPositionalParameters() > 0) { s.append(' ').append(getValueString(symbolTable, getUse(0))); for (int i = 1; i < getNumberOfPositionalParameters(); i++) { s.append(',').append(getValueString(symbolTable, getUse(i))); } } s.append(" @"); s.append(site.getProgramCounter()); if (exception == -1) { s.append(" exception: NOT MODELED"); } else { s.append(" exception:").append(getValueString(symbolTable, exception)); } return s.toString(); }
/** * Returns an array of {@code int} with the parameter's var nums of the * invoked method in {@code invokeInstruction}. * * @param invokeInstruction * The instruction that invokes the method. * @return an array of {@code int} with all parameter's var nums * including the this pointer. */ public static int[] getParameterNumbers(SSAAbstractInvokeInstruction invokeInstruction) { final int number = invokeInstruction.getNumberOfPositionalParameters(); final int[] parameterNumbers = new int[number]; assert (parameterNumbers.length == invokeInstruction.getNumberOfUses()); for (int i = 0; i < parameterNumbers.length; i++) { parameterNumbers[i] = invokeInstruction.getUse(i); } return parameterNumbers; }
/** * For each invocation in the method, add nodes for actual parameters and return values */ protected void addNodesForInvocations(CGNode node, IR ir) { for (CallSiteReference site : Iterator2Iterable.make(ir.iterateCallSites())) { SSAAbstractInvokeInstruction[] calls = ir.getCalls(site); for (SSAAbstractInvokeInstruction invokeInstr : calls) { for (int i = 0; i < invokeInstr.getNumberOfUses(); i++) { // just make nodes for parameters; we'll get to them when // traversing // from the callee PointerKey use = heapModel.getPointerKeyForLocal(node, invokeInstr.getUse(i)); addNode(use); Set<SSAAbstractInvokeInstruction> s = MapUtil.findOrCreateSet(callParams, use); s.add(invokeInstr); } // for any def'd values, keep track of the fact that they are def'd // by a call if (invokeInstr.hasDef()) { PointerKey def = heapModel.getPointerKeyForLocal(node, invokeInstr.getDef()); addNode(def); callDefs.put(def, invokeInstr); } PointerKey exc = heapModel.getPointerKeyForLocal(node, invokeInstr.getException()); addNode(exc); callDefs.put(exc, invokeInstr); } } }
int nUses = instruction.getNumberOfPositionalParameters(); int nExpected = target.getMethod().getNumberOfParameters(); for (int i = 0; i < instruction.getNumberOfPositionalParameters(); i++) { if (target.getMethod().getParameterType(i).isReferenceType()) { PointerKey formal = getTargetPointerKey(target, i); if (instruction.getUse(i) < 0) { Assertions.UNREACHABLE("unexpected " + instruction + " in " + caller); PointerKey actual = getPointerKeyForLocal(caller, instruction.getUse(i)); if (formal instanceof FilteredPointerKey) { system.newConstraint(formal, filterOperator, actual); if (instruction.hasDef() && instruction.getDeclaredResultType().isReferenceType()) { PointerKey result = getPointerKeyForLocal(caller, instruction.getDef()); PointerKey ret = getPointerKeyForReturnValue(target); system.newConstraint(result, assignOperator, ret); PointerKey e = getPointerKeyForLocal(caller, instruction.getException()); PointerKey er = getPointerKeyForExceptionalReturnValue(target); if (SHORT_CIRCUIT_SINGLE_USES && uniqueCatchKey != null) {
public Iterator<PointerKeyAndCallSite> getParamPreds(LocalPointerKey pk) { // TODO Set<SSAAbstractInvokeInstruction> instrs = callParams.get(pk); if (instrs == null) { return EmptyIterator.instance(); } ArrayList<PointerKeyAndCallSite> paramPreds = new ArrayList<>(); for (SSAAbstractInvokeInstruction callInstr : instrs) { for (int i = 0; i < callInstr.getNumberOfUses(); i++) { if (pk.getValueNumber() != callInstr.getUse(i)) continue; CallSiteReference callSiteRef = callInstr.getCallSite(); // get call targets Collection<CGNode> possibleCallees = cg.getPossibleTargets(pk.getNode(), callSiteRef); // construct graph for each target for (CGNode callee : possibleCallees) { addSubgraphForNode(callee); // TODO test this!!! // TODO test passing null as an argument PointerKey paramVal = heapModel.getPointerKeyForLocal(callee, i + 1); assert containsNode(paramVal); paramPreds.add(new PointerKeyAndCallSite(paramVal, callSiteRef)); } } } return paramPreds.iterator(); }
Collection<Statement> params = MapUtil.findOrCreateSet(callerParamStatements, call.getCallSite()); Collection<Statement> rets = MapUtil.findOrCreateSet(callerReturnStatements, call.getCallSite()); for (int j = 0; j < call.getNumberOfUses(); j++) { Statement st = new ParamCaller(node, callIndex, call.getUse(j)); delegate.addNode(st); params.add(st); if (!call.getDeclaredResultType().equals(TypeReference.Void)) { Statement st = new NormalReturnCaller(node, callIndex); delegate.addNode(st);
int argCount = instruction.getNumberOfPositionalParameters(); PointerKey A = builder.getPointerKeyForLocal(caller, instruction.getUse(i)); builder.getSystem().newConstraint(F, (F instanceof FilteredPointerKey) ? builder.filterOperator : assignOperator, A); targetVisitor.newFieldWrite(target, av, fn, constParams[i]); } else if(i >= num_pseudoargs) { PointerKey A = builder.getPointerKeyForLocal(caller, instruction.getUse(i)); targetVisitor.newFieldWrite(target, av, fn, A); if (instruction.getDef(0) != -1) { PointerKey RF = builder.getPointerKeyForReturnValue(target); PointerKey RA = builder.getPointerKeyForLocal(caller, instruction.getDef(0)); builder.getSystem().newConstraint(RA, assignOperator, RF); PointerKey EA = builder.getPointerKeyForLocal(caller, instruction.getDef(1)); builder.getSystem().newConstraint(EA, assignOperator, EF);
private void propagateToCaller() { // if (caller.getIR() == null) { // return; // } g.addSubgraphForNode(caller); SSAAbstractInvokeInstruction[] callInstrs = getCallInstrs(caller, call); for (SSAAbstractInvokeInstruction callInstr : callInstrs) { PointerKey returnAtCallerKey = heapModel.getPointerKeyForLocal(caller, isExceptional ? callInstr.getException() : callInstr.getDef()); assert g.containsNode(returnAtCallerKey); assert g.containsNode(returnKey); handler.handle(curPkAndState, returnAtCallerKey, returnBarLabel); } }
/** * TODO: enhance this logic using type inference * * @return true if we need to filter the receiver type to account for virtual dispatch */ @SuppressWarnings("unused") private boolean needsFilterForReceiver(SSAAbstractInvokeInstruction instruction, CGNode target) { FilteredPointerKey.TypeFilter f = (FilteredPointerKey.TypeFilter) target.getContext().get(ContextKey.PARAMETERS[0]); if (f != null) { // the context selects a particular concrete type for the receiver. // we need to filter, unless the declared receiver type implies the // concrete type (TODO: need to implement this optimization) return true; } // don't need to filter for invokestatic if (instruction.getCallSite().isStatic() || instruction.getCallSite().isSpecial()) { return false; } MethodReference declaredTarget = instruction.getDeclaredTarget(); IMethod resolvedTarget = getClassHierarchy().resolveMethod(declaredTarget); if (resolvedTarget == null) { // there's some problem that will be flagged as a warning return true; } return true; }
String def = call.hasDef() ? Integer.valueOf(call.getDef()) + "=" : ""; final StringBuilder result = new StringBuilder(def).append("call ") .append(call.getDeclaredTarget().getDeclaringClass().getName().getClassName()).append('.') .append(call.getDeclaredTarget().getName()); result.append(" exc:").append(call.getException()); for (int i = 0; i < s.getNumberOfUses(); i++) { result.append(' ').append(s.getUse(i));
@Override public void act(int x) { vns[i++] = instruction.getUse(x); } });
/** * Side effect: records invariant parameters as implicit points-to-sets. * * @return if non-null, then result[i] holds the set of instance keys which may be passed as the ith parameter. (which must be * invariant) */ @Override public InstanceKey[][] computeInvariantParameters(SSAAbstractInvokeInstruction call) { InstanceKey[][] constParams = null; for (int i = 0; i < call.getNumberOfUses(); i++) { // not sure how getUse(i) <= 0 .. dead code? // TODO: investigate if (call.getUse(i) > 0) { if (contentsAreInvariant(symbolTable, du, call.getUse(i))) { system.recordImplicitPointsToSet(getPointerKeyForLocal(call.getUse(i))); if (constParams == null) { constParams = new InstanceKey[call.getNumberOfUses()][]; } constParams[i] = getInvariantContents(call.getUse(i)); for (int j = 0; j < constParams[i].length; j++) { system.findOrCreateIndexForInstanceKey(constParams[i][j]); } } } } return constParams; } }
@SuppressWarnings("unused") private static OrdinalSet<FuncVertex> getConstructorTargets(FlowGraph flowGraph, CallVertex callVertex, IProgressMonitor monitor) throws CancelException { SSAAbstractInvokeInstruction invoke = callVertex.getInstruction(); assert invoke.getDeclaredTarget().getName().equals(JavaScriptMethods.ctorAtom); VarVertex objectParam = flowGraph.getVertexFactory().makeVarVertex(callVertex.getCaller(), invoke.getUse(0)); return flowGraph.getReachingSet(objectParam, monitor); }
if (s instanceof SSAAbstractInvokeInstruction) { SSAAbstractInvokeInstruction call = (SSAAbstractInvokeInstruction) s; TypeVariable v = getVariable(call.getException()); Collection<TypeReference> defaultExceptions = call.getExceptionTypes(); if (defaultExceptions.size() == 0) { continue; IMethod m = cha.resolveMethod(call.getDeclaredTarget()); if (m != null) { TypeReference[] x = null;
public Iterator<PointerKeyAndCallSite> getReturnSuccs(LocalPointerKey pk) { SSAAbstractInvokeInstruction callInstr = callDefs.get(pk); if (callInstr == null) return EmptyIterator.instance(); ArrayList<PointerKeyAndCallSite> returnSuccs = new ArrayList<>(); boolean isExceptional = pk.getValueNumber() == callInstr.getException(); CallSiteReference callSiteRef = callInstr.getCallSite(); // get call targets Collection<CGNode> possibleCallees = cg.getPossibleTargets(pk.getNode(), callSiteRef); // construct graph for each target for (CGNode callee : possibleCallees) { addSubgraphForNode(callee); PointerKey retVal = isExceptional ? heapModel.getPointerKeyForExceptionalReturnValue(callee) : heapModel .getPointerKeyForReturnValue(callee); assert containsNode(retVal); returnSuccs.add(new PointerKeyAndCallSite(retVal, callSiteRef)); } return returnSuccs.iterator(); }
private IntSet identifyDependentParameters(CGNode caller, CallSiteReference site) { MutableIntSet dependentParameters = IntSetUtil.make(); SSAAbstractInvokeInstruction inst = caller.getIR().getCalls(site)[0]; DefUse du = caller.getDU(); for(int i = 0; i < inst.getNumberOfPositionalParameters(); i++) { MutableIntSet values = IntSetUtil.make(); values.add(inst.getUse(i)); collectValues(du, du.getDef(inst.getUse(i)), values); if (values.contains(index+1)) dependentParameters.add(i); } return dependentParameters; }
@Override public IntSet getRelevantParameters(CGNode caller, CallSiteReference site) { // 0 for function (synthetic apply), 1 for this (function being invoked), 2 // for this arg of function being invoked, // 3 for arguments array MutableIntSet params = IntSetUtil.make(); for(int i = 0; i < 4 && i < caller.getIR().getCalls(site)[0].getNumberOfUses(); i++) { params.add(i); } return params.union(base.getRelevantParameters(caller, site)); }