/// <summary> /// Bind an output or ref result with the argument /// </summary> /// <param name="calleePTG"></param> /// <param name="vr"></param> /// <param name="outParameter"></param> /// <param name="ipm"></param> /// <returns></returns> private void bindRefOrOutParameter(PTGraph callerPTG, PTGraph calleePTG, Variable argVar, Variable outParameter) { if (argVar != null) { // This is like a StoreInditect of LoadIndirect but using the mapping // *arg = related(*outP) // PTAnalysisNode addrArg = callerPTG.GetAddress(argVar); // Nodes callerValues = callerPTG.Values(addrArg); Nodes callerValues = callerPTG.Values(callerPTG.GetLocations(argVar)); // PTAnalysisNode addrOutP = calleePTG.GetAddress(outParameter); // Nodes calleeValues = calleePTG.Values(addrOutP); Nodes calleeValues = calleePTG.Values(calleePTG.GetLocations(outParameter)); Nodes relatedValues2 = Nodes.Empty; foreach (IPTAnalysisNode n2 in calleePTG.Values(calleeValues)) { relatedValues2.AddRange(RelatedExtended(n2)); } // I am assuming Strong Update. Adding an aditional argument false // it become weak update callerPTG.Assign(callerValues, relatedValues2, calleePTG.MethodLabel); } }
/// <summary> /// Bind the caller with the callee and simplify the resulting pointsToGraph /// by removing the load nodes that has been resolved (captured objects) /// </summary> /// <param name="callerPTG"></param> /// <param name="calleePTG"></param> /// <param name="vr"></param> /// <returns></returns> private void bindCallerWithCalleePTG(PTGraph callerPTG, PTGraph calleePTG, Variable vr) { // Compute Edges Edges Inew = new Edges(); foreach (Edge ie in calleePTG.I) { foreach (IPTAnalysisNode nu1 in RelatedExtended(ie.Src)) { foreach (IPTAnalysisNode nu2 in RelatedExtended(ie.Dst)) { Inew.AddIEdge(nu1, ie.Field, nu2); } } } // Compute Edges Edges Onew = new Edges(); foreach (Edge oe in calleePTG.O) { foreach (IPTAnalysisNode nu1 in RelatedExtended(oe.Src)) { if (!nu1.IsNull) Onew.AddOEdge(nu1, oe.Field, oe.Dst); } } // Compute Escape Nodes eNew = new Nodes(); foreach (IPTAnalysisNode n in calleePTG.E) { eNew.AddRange(RelatedExtended(n)); } callerPTG.I.AddEdges(Inew); callerPTG.O.AddEdges(Onew); callerPTG.E.AddRange(eNew); /// Assign vr = related(retValue) Nodes argNodes = Nodes.Empty; if (callerThisRef != null) { // argNodes.Add(callerPTG.GetAddress(callerThisRef)); argNodes.AddRange(callerPTG.GetLocations(callerThisRef)); } if (calleePTG.Method.Parameters != null) { for (int i = 0; i < calleePTG.Method.Parameters.Count; i++) { Parameter p = calleePTG.Method.Parameters[i]; PNode pn = calleePTG.ParameterMap[p]; if (!pn.IsByValue) { if (arguments[i] is Variable) { Variable vArg = (Variable)arguments[i]; bindRefOrOutParameter(callerPTG, calleePTG, arguments[i] as Variable, p); } } if (arguments[i] is Variable) { Variable vArg = (Variable)arguments[i]; // PTAnalysisNode addrArg = callerPTG.GetAddress(vArg); // argNodes.Add(addrArg); argNodes.AddRange(callerPTG.GetLocations(vArg)); } } } if (vr != null) { if (!vr.Type.IsPrimitive && calleePTG.RetValue != null) { callerPTG.AddVariable(vr, callerPTG.MethodLabel); Nodes relatedValues2 = Nodes.Empty; // PTAnalysisNode addrRetValue = calleePTG.GetAddress(calleePTG.RetValue); // foreach (PTAnalysisNode n2 in calleePTG.Values(addrRetValue)) foreach (IPTAnalysisNode n2 in calleePTG.Values(calleePTG.GetLocations(calleePTG.RetValue))) { relatedValues2.AddRange(RelatedExtended(n2)); } callerPTG.Assign(vr, relatedValues2, calleePTG.MethodLabel); } else { callerPTG.ForgetVariable(vr); } } // Now we can remove the load nodes that don't escape Set<LNode> lNodes = callerPTG.LoadNodes; // B = Nodes forward reachable from from Escaping, Parameters, callee Arguments and Global nodes Nodes B = callerPTG.ReachableFromParametersReturnAndGlobalsAnd(argNodes); foreach (LNode ln in lNodes) { Set<Edge> IToRemove = new Set<Edge>(); Set<Edge> OToRemove = new Set<Edge>(); // If the LoadNode is not reachable or it is captured if (!B.Contains(ln) || (Related(ln).Count > 0)) // if (!B.Contains(ln) || (ln.IsParameterValueLNode && (Related(ln).Count > 0 || !Related(ln).Contains(ln)))) //if (!B.Contains(ln) /*&& (ln is LAddrFieldNode */ // /*&& ln.Label.Method.Equals(callerPTG.Method)*/) { foreach (Edge ie in callerPTG.I.EdgesFromSrc(ln)) IToRemove.Add(ie); foreach (Edge ie in callerPTG.I.EdgesFromDst(ln)) IToRemove.Add(ie); foreach (Edge oe in callerPTG.O.EdgesFromDst(ln)) OToRemove.Add(oe); foreach (Edge oe in callerPTG.O.EdgesFromSrc(ln)) OToRemove.Add(oe); removedLoadNodes.Add(ln); } callerPTG.I.RemoveEdges(IToRemove); callerPTG.O.RemoveEdges(OToRemove); } }